# Linear interpolation between defined anchorpoints in an array (where anchorpoints are set each time we see a new element)

This question is an update and a correction my earlier question: Linear interpolation of a list between periodic anchorpoints (which was nicely answered).

Imagine I have a list of the form:

list = {1,1,1,2,2,2,3,3,3,4,4,4,7};


Where we can see that there are an ordered set of integer or real numbered values that repeat themselves some fixed number of times N. Is there a nice one-liner to transform this list into something like:

modifiedList = {1,1+1/3,1+2/3,2+1/3,2+2/3,3,3+1/3,3+2/3,4,5,6,7}


Where each time we see a new value we place an anchorpoint, and then "fix" the points in the array between these anchorpoints so that they lie on a line between successive anchorpoints?

• Niniar, you should wait longer before Accepting an answer. I recommend 24 hours to let everyone around the world to have time to answer. It's hard to tell what answers you may receive if you give people a chance. Aug 8, 2013 at 3:13
• @Mr.Wizard Ok, I'll do just that. Aug 8, 2013 at 3:16

We can use Interpolation.

1. Find the start points of each run of values. (idx)

2. Extract these values and pair them with the indexes, and generate an InterpolatingFunction with an InterpolationOrder of 1. (intf)

3. Apply this function to a list of natural numbers the length of your input list.

Code:

idx  = Most @ Accumulate @ Prepend[Length /@ Split[list], 1]

intf = Interpolation[{idx, list[[idx]]}\[Transpose], InterpolationOrder -> 1]

intf @ Range @ Length @ list

{1, 4, 7, 10, 13}

InterpolatingFunction[{{1,13}},<>]

{1, 4/3, 5/3, 2, 7/3, 8/3, 3, 10/3, 11/3, 4, 5, 6, 7}


A manual approach that is likely quite a bit slower but which I enjoyed writing:

f[{a : {x_, ___}, {y_, ___}}] := Most @ Range[x, y, (y - x)/Length@a]

Flatten[f /@ Partition[Split[list], 2, 1]] ~Append~ Last[list]

{1, 4/3, 5/3, 2, 7/3, 8/3, 3, 10/3, 11/3, 4, 5, 6, 7}

• I really like the manual approach - but good to know that Interpolation can be used like this. Thanks! Aug 8, 2013 at 2:41