# Mathematica periodic moving map

I am pleased to have MovingMap in Mathematica 10. But, today, I encountered the problem that needs MovingMap with a periodic boundary condition.

To be specific, Consider the following example.

MovingMap[ f, Range, {2} ]


will gives the result {f[{1, 2}], f[{2, 3}], f[{3, 4}]}. However, what I want to get is {f[{1, 2}], f[{2, 3}], f[{3, 4}], f[{4,1}]}.

One of the easiest and straightforward way would be calculating the last one and then join the lists together. But I want to know if there is more elegant way to do it. (I checked the optional arguments of MovingMap but I couldn't find a solution.)

• Use Map with Partition: f /@ Partition[Range, 2, 1, {1, 1}] gives {f[{1, 2}], f[{2, 3}], f[{3, 4}], f[{4, 1}]} – Bob Hanlon Nov 5 '14 at 15:15

"Reflected" padding works as desired but "Periodic" padding is missed. There is corresponding definition for "Reflected"

RandomProcessesTemporalDataUtilitiesDumptoCannonicalPadding[
RandomProcessesTemporalDataUtilitiesDumptd_, "Reflected",
RandomProcessesTemporalDataUtilitiesDumpw_,
RandomProcessesTemporalDataUtilitiesDumpCaller_] :=
Reverse[Rest[
TemporalDataUtilitiesTDResample[
RandomProcessesTemporalDataUtilitiesDumptd,
RandomProcessesTemporalDataUtilitiesDumpw, {},
RandomProcessesTemporalDataUtilitiesDumpCaller]["Values"]]]


So we can add a similar definition for "Periodic"

RandomProcessesTemporalDataUtilitiesDumptoCannonicalPadding[
RandomProcessesTemporalDataUtilitiesDumptd_, "Periodic",
RandomProcessesTemporalDataUtilitiesDumpw_,
RandomProcessesTemporalDataUtilitiesDumpCaller_] :=
TemporalDataUtilitiesTDResample[
RandomProcessesTemporalDataUtilitiesDumptd,
RandomProcessesTemporalDataUtilitiesDumpw, {},
RandomProcessesTemporalDataUtilitiesDumpCaller]["Values"]


Verification:

MovingMap[f, Range, {2}, "Periodic"]
(* {f[{3, 1}], f[{1, 2}], f[{2, 3}]} *)

• You can get this result with MovingMap[f, Range, {2}, Range]. With either approach a RotateLeft is required to put in order that OP requested. – Bob Hanlon Nov 5 '14 at 15:21

Here is one way:

movingMapCircular[f_, l_List] := MapThread[f@* List, {l, RotateLeft[l]}];


For example:

movingMapCircular[f, {1, 2, 3, 4}]

(* {f[{1, 2}], f[{2, 3}], f[{3, 4}], f[{4, 1}]} *)


A generalization of this approach for arbitrary window size may look like:

ClearAll[movingMapCircular];
movingMapCircular[f_, l_List, {n_Integer}] :=
f@* List,
MapThread[RotateLeft, {ConstantArray[l, n], Range[0, n - 1]}]
];


for example:

movingMapCircular[f, Range, {3}]

(* {f[{1, 2, 3}], f[{2, 3, 4}], f[{3, 4, 5}], f[{4, 5, 1}], f[{5, 1, 2}]} *)


With versions 10.4.1 and 11.0.1 "Periodic" works:

MovingMap[f, Range, 1, "Periodic"]
MovingMap[f, Range, {1, Left}, "Periodic"]
MovingMap[f, Range, 2, "Periodic"]
MovingMap[f, Range, {2, Center}, "Periodic"]

{f[{5, 1}], f[{1, 2}], f[{2, 3}], f[{3, 4}], f[{4, 5}]}

{f[{1, 2}], f[{2, 3}], f[{3, 4}], f[{4, 5}], f[{5, 1}]}

{f[{4, 5, 1}], f[{5, 1, 2}], f[{1, 2, 3}], f[{2, 3, 4}], f[{3, 4, 5}]}

{f[{5, 1, 2}], f[{1, 2, 3}], f[{2, 3, 4}], f[{3, 4, 5}], f[{4, 5, 1}]}


But MovingMap is still one order of magnitude slower than Map + Partition:

ClearSystemCache[]
m1 = MovingMap[f, Range[10^6], {2, Center}, "Periodic"]; // RepeatedTiming
ClearSystemCache[]
m2 = f /@ Partition[ArrayPad[Range[10^6], {1, 1}, "Periodic"], 3, 1]; // RepeatedTiming
ClearSystemCache[]
m3 = f /@ Partition[Range[10^6], 3, 1, {2, 2}]; // RepeatedTiming
ClearSystemCache[]
m4 = DeveloperPartitionMap[f, Range[10^6], 3, 1, {2, 2}]; // RepeatedTiming
m1 === m2 === m3 === m4

{6.60, Null}

{0.950, Null}

{0.987, Null}

{1.07, Null}

True
`