# From iterative to functional

How to write this small piece in a functional way (ie. without state variables)?:

test[oldJ_List, newJ_List] := Total[Abs[oldJ - newJ]] > 1;
relax[j_List, x_?NumericQ] := Mean[Nearest[j, x, 4]];

j = Range[100]; (* any numeric list *)
j1 = j/2; (*some initial value for the While[] test to return True*)

While[test[j1, j],
j1 = j;
(j[[#]] = relax[j, j[[#]]]) & /@ Range@Length@j]

• test[] can also be defined as test[oldJ_List, newJ_List] := ManhattanDistance[oldJ, newJ] > 1. Sep 30, 2012 at 9:52

Let me first redefine your relax to return a list as:

Clear@relax1
relax1[j_List, i_Integer] := MapAt[Mean[Nearest[j, #, 4]] &, j, i]


Then, the algorithm can be written in a functional way without state variables using Fold and NestWhile as follows (if I understood your intentions correctly):

With[{indx = Range@Length@#}, NestWhile[Fold[relax1[#1, #2] &, #, indx] &, #, test, 2]] &@j

• Very nice! thanks! Sep 29, 2012 at 21:45
• BTW. This is the first iterative structure I used in this answer. I'm still thinking about the second one Sep 30, 2012 at 3:21

This also works:

fold = Function[{lst},Fold[(ReplacePart[#1, #2 ->relax[#1, #1[[#2]]]]) &,
lst,  Range@Length@lst]];
fxpnt = FixedPoint[fold, #, SameTest -> (Not[test[#1, #2]] &)] &;
fxpnt@j

• nice! Why the N@? Sep 30, 2012 at 22:17
• forgot to remove N (i was using it to simplify the printed output) ... removed now.
– kglr
Sep 30, 2012 at 22:23
• @belisarius, on second thought (and few limited timing tests with j=Range[1000]) it seems that N is actually cruical for speed.
– kglr
Sep 30, 2012 at 23:04