8
$\begingroup$

For a list of any given length, I want to generate another list from it adding elements which are mean of the consecutive elements, in between the elements, of the original list. For example:

list = {a, b, c};
newlist = {a, (a+b)/2, b, (b+c)/2, c}

I have written this function which does the job but I need much more elegant solution:

intFunc[list_] := Module[{list1},
list1 = ConstantArray[0, 2*Length[list] - 1];
Table[list1[[2*i - 1]] = list[[i]], {i, 1, Length[list]}];
Table[list1[[2*i]] = (list[[i]] + list[[i + 1]])/2, {i, 1, Length[list] - 1}];
list1
];
$\endgroup$
  • 2
    $\begingroup$ This is not exactly what you want, but do you know ArrayResample? Try: ArrayResample[{a,b,c},5] $\endgroup$ – Markus Roellig Sep 21 '15 at 12:17
  • $\begingroup$ I added parentheses where I think you forgot to do so. Please correct me if I were wrong. $\endgroup$ – yohbs Sep 21 '15 at 12:19
  • $\begingroup$ @MarkusRoellig I'll look into it. $\endgroup$ – mrkbtr Sep 21 '15 at 12:33
  • $\begingroup$ @yohbs thanks for the correction $\endgroup$ – mrkbtr Sep 21 '15 at 12:34
7
$\begingroup$
intFunc[list_]:=Interpolation[list, InterpolationOrder->1]@Range[1, Length@list, 1/2]
$\endgroup$
  • $\begingroup$ Looks good. Thanks! $\endgroup$ – mrkbtr Sep 21 '15 at 12:35
9
$\begingroup$

My take:

list = {a, b, c};
Riffle[list, MovingAverage[list, 2]]
(* {a, (a + b)/2, b, (b + c)/2, c} *)

Equivalently:

MovingAverage[Riffle[list, list], 2]

Finally, can be generalized to multiple points in between original data points. Equivalent to previous solutions (if using n=2):

intList[list_, n_] := MovingAverage[Flatten[Transpose[ConstantArray[list, n]], 1], n]

Demo (offsets in data include for clarity):

list = {1, 4, 9};
ListPlot[Evaluate @ (#/2 + intList[list, #] & /@ Range[5]), DataRange -> {1, 3}]

demo

Re the comment by Markus Roellig: using ArrayResample like so gives the same results.

intList2[list_, n_] := ArrayResample[list, (Length[list] - 1)*n + 1]
$\endgroup$
  • $\begingroup$ Works well. Thanks. $\endgroup$ – mrkbtr Sep 21 '15 at 13:20
  • $\begingroup$ @mrkbtr added an extension for multiple datapoints in between the original points, in case you might need that. $\endgroup$ – LLlAMnYP Sep 21 '15 at 13:23
5
$\begingroup$

For integer lists, this s/b nicely faster than others (interpolation and the two moving-average based solutions:

Riffle[#, Divide[Most@# + Rest@#, 2]] &

enter image description here

On real/symbolic, it is comparable to the moving-average based solutions. The interpolation based solution performs uniformly poorly on large lists regardless of type.

$\endgroup$
  • $\begingroup$ Perhaps you meant Riffle[#, Divide...] & rather than Riffle[list, Divide...]& ? $\endgroup$ – LLlAMnYP Sep 22 '15 at 9:55
  • $\begingroup$ @LLlAMnYP oops, yes, fixing. Thanks for catching. $\endgroup$ – ciao Sep 22 '15 at 10:09
  • $\begingroup$ On my machine with a list of 4*^6 reals your solution still performs a factor of 2 better than the second best. $\endgroup$ – LLlAMnYP Sep 22 '15 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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