Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a list of points that may be used for linear interpolation using Interpolation and need to ensure that no two points have the same $x$ value, since, if they do, Interpolation reports errors:

enter image description here

Ideally I'd like to simply tweak such points just enough, that their control points don't shift visibly, but that they satisfy Interpolation (e.g. by adding a very small number to one of the offending points).

Alternatively, perhaps a different Mathematica interpolation function or different options for Interpolation avoid this error.

I've tried randomizing the points a bit, using various methods, but I get strange behavior, including briefly jagged plots (e.g. when changing settings for iorder) and eventual unresponsiveness of the control points (they just won't move).

 (*pts = MapAt[# + RandomReal[NormalDistribution[0, 10^-4]] &, 
   pts, -1];*)
 Plot[Interpolation[Prepend[pts, {0, 0}], InterpolationOrder -> iorder][x], {x, 0, 1}],
 {{pts, {{.2, .1}, {.4, .2}, {.6, .3}, {.8, .25}, {1, 0}}}, Locator},
 {{iorder, 3, "InterpolationOrder"}, Range[3], SetterBar}]

In context, I switch among even more curve fitting methods (e.g. Bezier, etc.), so dropping points is not an option, nor is moving them perceptibly, or skipping them.

Why not just add a tiny amount of random floating point error to all coordinates? –  whuber Nov 8 '12 at 21:19
@whuber: I'm not sure how to do that, if I precede the plot with something like pts = {RandomReal[{#[[1]] - .0001, #[[1]] + .0001}], #[[2]]} & /@ pts;, I get a wobbly plot. –  raxacoricofallapatorius Nov 8 '12 at 21:36
what about DeleteDuplicates? –  chris Nov 8 '12 at 21:40
@chris: No dropping, skipping or (perceptibly) moving of points. All the control points need to pretty much seem to stay where there are. They can "stick" of shift a tiny amount if that's the only way, but removing them is definitely out. –  raxacoricofallapatorius Nov 8 '12 at 21:48
I don't know what the structure of points is intended to be, so I'll give you an inefficient generic solution to jitter all the coordinates: MapAt[# + RandomReal[NormalDistribution[0, 10^-4]] &, points, -1]. Use a uniform distribution to limit the amount of jittering if you like and change the 10^-4 to suit your tastes. Generalizations of this approach will jitter only the x-coordinates. The idea here is to avoid looking for duplicates altogether. And if you're willing to change some coordinates, arguably it's best to change them all in the same fashion. –  whuber Nov 8 '12 at 21:51

2 Answers 2

up vote 5 down vote accepted

Assuming your points are in order, then you could just use a rule:

rule = {before___, {x_, y1_}, {x_, y2_}, after___} -> 
       {before, {x, y1}, {x + tweak, y2}, after}

Then apply with repeated replacement:

pts //. rule
That seems to do the trick! –  raxacoricofallapatorius Nov 8 '12 at 22:13

It seems that interpolation in two dimensions is desired. To do so, interpolate the x- and y-coordinates separately and plot the curve parametrically:

 Module[{f = Interpolation[#, InterpolationOrder -> iorder] & /@ 
             Transpose[Prepend[pts, {0, 0}]]},
  ParametricPlot[Through[f[x]], {x, 1, Length[pts]+1}, PlotRange -> {Full, Full}]],
 {{pts, {{.2, .1}, {.4, .2}, {.6, .3}, {.8, .25}, {1, 0}}}, Locator},
 {{iorder, 3, "InterpolationOrder"}, Range[3]}]


Now it does not matter that some of the x-coordinates may have been duplicated.

"...interpolate the $x$- and $y$-coordinates separately and plot the curve parametrically." - in that regard, one might consider using something like centripetal parametrization for the purpose... –  J. M. Nov 9 '12 at 16:21
@J.M. Thanks for that reference. –  whuber Nov 9 '12 at 16:24

This site is currently not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .