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.

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?

share|improve this question
    
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. –  Mr.Wizard Aug 8 '13 at 3:13
    
@Mr.Wizard Ok, I'll do just that. –  Niniar Aug 8 '13 at 3:16
add comment

1 Answer 1

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}
share|improve this answer
    
I really like the manual approach - but good to know that Interpolation can be used like this. Thanks! –  Niniar Aug 8 '13 at 2:41
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.