6
$\begingroup$

Newbie question here. Consider the following two functions:

f1[n_] := (
  q = {0, 0};
  Do[q[[RandomInteger[{1, 2}]]] += 1, n];
  Return[q]
  )

f2[n_] := (
  q = {0, 0};
  Do[k = RandomInteger[{1, 2}]; q[[k]] += 1, n];
  Return[q]
  )

Both seem to be doing the same thing: create a list of zeros, increment a random element $n$ times and return the list. The difference is that the first version "inlines" RandomInteger call into the indexing, while the second defines an intermediate variable k.

The function f2 works as expected, while f1 does not. For example, f1 sometimes returns lists for which sum of elements is not equal to the input n, which seems very strange.

In[357]:= f1[10]

Out[357]= {6, 7}

Can someone point out why f1 and f2 are treated differently?

$\endgroup$
15
$\begingroup$

Mathematica is an expression rewriting language. When it evaluates:

q[[RandomInteger[{1, 2}]]] += 1

It first rewrites it as:

q[[RandomInteger[{1, 2}]]] = q[[RandomInteger[{1, 2}]]] + 1

The result is that RandomInteger[{1, 2}] gets rewritten twice, possibly as different random integers.

$\endgroup$
7
$\begingroup$

The main problem is that q[[k]] += 1 is equivalent to q[[k]] = q[[k]] + 1, and so RandomInteger gets called twice. When the random number is the same (which happens half the time), then the behavior is what you expect. When the random numbers are different, then the behavior is completely different. Here is a version of your code where I add some debugging (I also removed the completely superfluous Return statement):

f1[n_] := (
    q = {0,0};
    Do[q[[Echo@RandomInteger[{1,2}]]] += 1; Print[q], n];
    q
)

Here is a short example:

SeedRandom[3]
f1[3]

1

2

{0,1}

2

2

{0,2}

2

1

{3,2}

{3, 2}

Let's see what happens. In the first iteration, we have:

q[[2]] = q[[1]] + 1

and so the result is {0, 1}. The second iteration does:

q[[2]] = q[[2]] + 1

and so the result is {0, 2}. The final iteration does:

q[[1]] = q[[2]] + 1

and so we get {3, 2}.

$\endgroup$

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.