I want a way to rotate a list to the right by a fractional amount, i.e. I want a function fractionalRotateRight[data, 2.3]
that would rotate data two positions to the right, and then an extra 0.3 positions.
-
$\begingroup$ What does it mean by "0.3 positions"? $\endgroup$– Αλέξανδρος ΖεγγCommented Mar 26, 2020 at 3:27
-
$\begingroup$ I imagine that the list is the values of a periodic function sampled evenly. When I 'shift' by 0.3 positions I want to estimate from the current sample, what the sample would have been, had I shifted my sampling positions by 0.3 units. That's how I think about it anyway. $\endgroup$– TomCommented Mar 26, 2020 at 16:48
2 Answers
fractionalRotateRight[data_, shift_] := Module[{n, f, nShift},
n = IntegerPart[shift];
f = FractionalPart[shift];
nShift = RotateRight[data, n];
If[shift >= 0,
MovingAverage[Prepend[nShift, nShift[[-1]]], {f, 1 - f}],
MovingAverage[Append[nShift, nShift[[1]]], {1 - Abs[f], Abs[f]}]
]
]
Example (1): The input fractionalRotateRight[{0, 0, 1, 0, 0}, 1.7]
produces the output {0., 0., 0., 0.3, 0.7}
Example (2): The input fractionalRotateRight[{0, 0, 1, 0, 0}, -1.7]
produces the output {0.7, 0.3, 0., 0., 0.}
Another approach is to use interpolation.
list = RandomInteger[{0, 10}, 10]
int = Interpolation[list, InterpolationOrder -> 1];
shift = 0.2;
int[# + shift] & /@ Range[10] // Quiet
list is the list that you want to rotate, shift is the amount to rotate. int[x] is a function that you can index into at will, in particular at all the shifted locations. The Quiet is needed because at the ends you are extrapolating, and this generates a warning (but not an error).