# 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. – J. M. Sep 30 '12 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! – Dr. belisarius Sep 29 '12 at 21:45
BTW. This is the first iterative structure I used in this answer. I'm still thinking about the second one – Dr. belisarius Sep 30 '12 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@? – Dr. belisarius Sep 30 '12 at 22:17
forgot to remove N (i was using it to simplify the printed output) ... removed now. – kglr Sep 30 '12 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 '12 at 23:04