# Simple while loop alternative in Mathematica

I have noticed that there are a few examples that go into some detail regarding While loop alternatives. (See here for example: Alternatives to While Loops?) However, I wanted to provide a simpler example for clarity, and to help affirm something which I am currently unclear about.

Can someone give a simple, faster alternative to the following code containing a While loop? (It counts the number of iterations taken before a pseudorandom uniform number on [0,1] to be generated.)

 Module[{cSwitch, cCount, cRand}, cSwitch = 0; cCount = 0; cRand = 0.9999;
While[cSwitch == 0, aRand = RandomReal[]; cCount += 1;
If[aRand > cRand, cSwitch = 1]]; cCount] // Timing


A corollary question is, when should one use a While loop for simplicity, and when is it really beneficial to use an alternative? I am highlighting really just to emphasise that there is a tradeoff between readability of code and speed.

Best,

Ben

• Just for fun: Block[{$IterationLimit = Infinity}, If[RandomReal[] > 0.9999, #, #0[# + 1]] &]. Another: NestWhile[# + 1 &, 0, RandomReal[] < 0.9999 &]. Nov 14, 2014 at 0:40 ## 1 Answer You are looking for a pattern suitable for loops which must terminate on a condition (rather than run a fixed number of times). While is a good solution for this, but the key is really Break[], which can be used in While, Do, For, etc. I would write this code as count = 1; While[RandomReal[] <= 0.9999, count++]; count  as here you can move the condition to the beginning of While. If you can't, then something like While[True, ... If[condition, Break[]]; ... ]  is an alternative. (You can also use For, as in For[count = 1, RandomReal[] <= 0.9999, count++]; count, but I'm not a fan of for loops in Mathematica. I usually prefer While.) Many problems that need to break on condition can be solved with NestWhile. Your example would be NestWhile[# + 1 &, 1, RandomReal[] <= 0.9999 &]  Check the documentation to see all the possible syntaxes for NestWhile. It's also possible to use recursive iteration, though it's more likely to be slower here, and we need to release the restriction on the iteration limit using $IterationLimit = Infinity:

f[n_] := If[RandomReal[] > 0.9999, n, f[n + 1]]
f


A very concise, but arguably not too readable version of the same is If[RandomReal[] > 0.9999, #, #0[# + 1]] & . Here #0 refers to the anonymous function itself.

If performance is key, then the While version has the advantage that it can Compiled. Not every function is compilable. A procedural style, such as the version using While, is the most suitable to be compiled.

• a very instructional answer. +1 Nov 14, 2014 at 1:54
• Your nasty unreadable last piece of code can be greatly improved as the If isn't really needed: Block[{\$IterationLimit = Infinity}, (# + 1 // (#0^Boole[RandomReal[] < 0.9999])) &@1 // #[] &] Nov 14, 2014 at 2:04
• Hi, thanks for your reply - that is useful to see. I have done some timing on the various different approaches to the While loop, and all seem to be very similar in terms of their timing. Can I ask if anyone could provide examples of when there is a significant difference in timing between a While loop vs a functional construct? Best, Ben Nov 14, 2014 at 12:03