Evaluating number of iteration with a certain map with While

Beeing used to programming in C-like languages I am struggling with iterations and loops with mathematica. I am trying not to use the For command, as already lots of people recommended.

I am trying to solve the following problem:

Given the map $$z_{i+1}= z_i^2 +c$$ with $$z_i, c \in \mathbb{C}$$ and $$z_0 = 0$$ evaluate the contours that represents given the parameter $$c$$ the number of iterations $$i$$ that I have to perform in order to have $$|z_i|> 2$$. Perform the computation with $$-0.6 \leq Re(z_i)\leq -0.4$$ and $$0.6 \leq Im(z_i)\leq 0.4$$ and 100 points per axis.

Given the condition I though I could use a While Loop to perform the task

i=0;            (*init counter*)
z[i]=0;         (*init z[i]*)
g[c_]:= While[
Abs[z[i]]<= 2, (*condition*)
z[i+1]= z[i]^2 +c; (*process*)
i++;            (*increment*)
]
Print[i]
g[0.2 + 0.2 I]

This computation with the input, say, $$(-0.2 +0.2 i)$$ (and with many others) takes all the memory of the machine I am using (Wolfram online). I don't understand whether I am just missing something or the amount of computation I can perform on the server just isn't enough (which seems really unlikely)

Furthermore I would like the function to return an integer (i - the number of iterations) but I really struggle with how to correctly use the synthax of Mathematica to do that.

Thanks in advance to everyone who is so keen to stop by and help :)

• Hello there. Just wanted to point out that for the input you give as example the computation will never finish because the condition is always satisfied. The absolute value never goes above 0.36. – Kiro Apr 10 at 8:20

The problem with your code is that for some values of c, Abs[z] will never become larger than 2. You need to cap the number of iterations.

For this type of iteration, the typical function to use is Nest and related functions.

countIter[c_] :=
Length@NestWhileList[
#^2 + c &,
0.0,
Abs[#] <= 2 &,
1,
100 (* limit number of iterations to 100 *)
]

result =
Table[
countIter[re + im I],
{re, -0.6, -0.4, 0.2/100},
{im, 0.4, 0.6, 0.2/100}
];

ArrayPlot[result, ColorFunction -> "Rainbow"] However, this type of problem is quite amenable to compilation with Compile. When using Compile, the usual advice does not apply: a procedural style is still the best. (This does not mean that For is good, I'd still argue against that. But there are many other procedural constructs such as Do and While).

countIterCompiled = Compile[{{c, _Complex}},
Block[{z = 0.0 + 0.0 I, i = 0},
While[i <= 100 && Abs[z] <= 2,
z = z^2 + c;
i++
];
i
]
]

Using countIterCompiled will be much faster than countIter.

• thank u very much for the suggestion... I previously had a similar idea using Module instead of Block, and the problem was that the exercise did not specify that for many values the map was converging so I had to cap the number of iterations. – JacquesLeen Apr 9 at 15:33
• @JacquesLeen Maybe that was part of the exercise: will you discover it on your own? Inside Compile, Module and Block are the same, I think. (Not outside of it.) – Szabolcs Apr 9 at 15:59

For iterated function systems like this, Nest and relatives are the preferred tools. Just exploring your (rather famous) map:

f[z_, c_] := z^2 + c
Abs[NestList[f[#, 0.2 + 0.2 I] &, 0, 30]]
(* {0, 0.282843, 0.344093, 0.351367, 0.327239, 0.304778, 0.303605,
0.311545, 0.316158, 0.315818, 0.313773, 0.312729, 0.31295, 0.313482,
0.313697, 0.313611, 0.313477, 0.313435, 0.313464, 0.313497, 0.313504,
0.313495, 0.313487, 0.313486, 0.313489, 0.313491, 0.313491, 0.31349,
0.31349, 0.31349, 0.31349} *)

As you can see, it converges to a value inside your radius. That's why your function doesn't terminate.

You could also use MandelbrotSetPlot to create Szabolcs' graphic:

MandelbrotSetPlot[{-0.6 + 0.4 I, -0.4 + 0.6 I}, PlotLegends -> Automatic] 