Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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]
share|improve this question
    
test[] can also be defined as test[oldJ_List, newJ_List] := ManhattanDistance[oldJ, newJ] > 1. –  J. M. Sep 30 '12 at 9:52

2 Answers 2

up vote 10 down vote accepted

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
share|improve this answer
2  
Very nice! thanks! –  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 –  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
share|improve this answer
    
nice! Why the N@? –  belisarius Sep 30 '12 at 22:17
1  
forgot to remove N (i was using it to simplify the printed output) ... removed now. –  kguler 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. –  kguler Sep 30 '12 at 23:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.