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).

Manipulate[
 (*pts = MapAt[# + RandomReal[NormalDistribution[0, 10^-4]] &, 
   pts, -1];*)
 (*pts={RandomReal[{#[[1]]-.0001,#[[1]]+.0001}],#[[2]]}&/@pts;*)    
 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.

share|improve this question
    
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
show 2 more comments

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
share|improve this answer
    
That seems to do the trick! –  raxacoricofallapatorius Nov 8 '12 at 22:13
add comment

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

Manipulate[
 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]}]

Plot

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

share|improve this answer
1  
"...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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.