11
$\begingroup$

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]
$\endgroup$
  • $\begingroup$ test[] can also be defined as test[oldJ_List, newJ_List] := ManhattanDistance[oldJ, newJ] > 1. $\endgroup$ – J. M. will be back soon Sep 30 '12 at 9:52
10
$\begingroup$

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
$\endgroup$
  • 2
    $\begingroup$ Very nice! thanks! $\endgroup$ – Dr. belisarius Sep 29 '12 at 21:45
  • $\begingroup$ BTW. This is the first iterative structure I used in this answer. I'm still thinking about the second one $\endgroup$ – Dr. belisarius Sep 30 '12 at 3:21
2
$\begingroup$

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
$\endgroup$
  • $\begingroup$ nice! Why the N@? $\endgroup$ – Dr. belisarius Sep 30 '12 at 22:17
  • 1
    $\begingroup$ forgot to remove N (i was using it to simplify the printed output) ... removed now. $\endgroup$ – kglr Sep 30 '12 at 22:23
  • $\begingroup$ @belisarius, on second thought (and few limited timing tests with j=Range[1000]) it seems that N is actually cruical for speed. $\endgroup$ – kglr Sep 30 '12 at 23:04

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.