Gplatzeck
Gplatzeck

Reputation: 11

Recursive function with for in Mathematica does not work

Why does this recursive function not work?

Code:

Clear[i];
Clear[v];
final= 4;

Recursion = Function[{v},
   For[i = 1, i <= 2, i++,
      Print["Current level ", v ];
      Print["Try: ", i];
      If[v == final,
         Print["End"];, 
         Recursion[v + 1]; (*else-case*)
      ];
      Print["Back! i:", i];
   ];
]

Recursion[1];

Out:

0: Current level 1
1: Try: 1
2: Current level 2
3: Try: 1
4: Current level 3
5: Try: 1
6: Current level 4
7: Try: 1
8: End
9: Back! i:1
10: Current level 4
11: Try: 2
12: End
13: Back! i:2
14: Back! i:3
15: Back! i:4
16: Back! i:5

Heeelp

In the 14th line, "i" should be =2, current level: 3 and try: 2.. then i=1, then i=2.. like a binary tree.

Why is this happening?!

Upvotes: 1

Views: 993

Answers (2)

Mr.Wizard
Mr.Wizard

Reputation: 24336

As Chris observes you need to localize i within the function, but I recommend you use Module to localize i. v is already localized by Function itself so you do not need Clear. Also, avoid starting user function names with a capital letter, as by convention those are reserved for system functions.

final = 4;

recursion =
  Function[{v},
   Module[{i},
    For[i = 1, i <= 2, i++,
     Print["Current level ", v];
     Print["Try: ", i];
     If[v == final, Print["End"], recursion[v + 1]];
     Print["Back! i:", i];
  ]]];

recursion[1];

Beyond this, the problem doesn't appear to require For and would be better written with Do. Also, you may want to choose a different structure: either a function defined with DownValues (meaning f[x_] := ... rather than f = Function[...]), or a Function using Slot (#) where #0 can be used for recursion. I will illustrate both methods for you.

DownValues

recursion2[v_Integer] :=
  Do[
   Print["Current level ", v];
   Print["Try: ", i];
   If[v == final, Print["End"], recursion2[v + 1]];
   Print["Back! i:", i],
   {i, 2}
  ]

Pure Function with Slot

Here # (also written #1) represents the single parameter of the function, and #0 is used to represent the function itself. See Slot for more.

recursion3 =
 Do[
   Print["Current level ", #];
   Print["Try: ", i];
   If[# == final, Print["End"], #0[# + 1]];
   Print["Back! i:", i],
   {i, 2}
 ] &;

Upvotes: 0

Chris Degnen
Chris Degnen

Reputation: 8655

Your iterator i is getting incremented inside the recursion, which is why it is counting to 5, higher than its set limit of 2.

You can make i a function of v to make it behave separately in each recursion, i.e.

final = 4;
Recursion = Function[v,
   For[i[v] = 1, i[v] <= 2, i[v]++,
    Print["Current level ", v];
    Print["Try: ", i[v]];
    If[v == final, Print["End"], Recursion[v + 1]];
    Print["Back! i[", v, "]:", i[v]]]];
Recursion[1]

This should make it easier for you to see what is happening, although I think you will need to restructure your code when you do see what it's doing.

Upvotes: 1

Related Questions