Re: For Loop and Array related

• To: mathgroup at smc.vnet.net
• Subject: [mg58031] Re: For Loop and Array related
• From: Maxim <ab_def at prontomail.com>
• Date: Thu, 16 Jun 2005 05:37:59 -0400 (EDT)
• References: <d8oucl\$t6q\$1@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```On Wed, 15 Jun 2005 10:03:01 +0000 (UTC), mchangun at gmail.com
<mchangun at gmail.com> wrote:

> Hi All,
>
> I have an array with 100 elements, all set to zero initially.  Then I
> want to randomly choose one element and increase its value by one, and
> repeat this 16000 times. Here is my code:
>
> Lattice = Table[0, {n, 100}];
> For[i = 1, i = 16000, i++, Lattice[[Random[Integer, {1, 100}]]]++]
>
> So now if I add all the elements in the list Lattice together, I should
> get 16000 (I use Total[Lattice] to get the sum of the list).  But this
> doesn't happen, and strangely, each time I run this, the sum of the
> list is different!  What am I doing wrong?
>
> Also I'm aware that a lot of Mathematica newbies try and write code
> like it were C++ and I think i've fallen into this trap as well.  So is
> there a different (more Mathematica) way which I can implement the
> above?
>
>

Increment[x] internally evaluates x = x + 1 (and returns the old value of
x then). Therefore, L[[Random[...]]]++ becomes L[[Random[...]]] =
L[[Random[...]]] + 1, where Random is evaluated twice and gives two
different indices.

Perhaps it would be better if Increment, AddTo and other assignment
functions evaluated the arguments of the left-hand side once; that is, in
pos=1;L[[pos++]]++ the argument pos++ should be evaluated once and then
the expression should be transformed into L[[1]] = L[[1]] + 1. This way we
get the desired behaviour: pos now has the value 2 and the first element
of L is incremented. Otherwise Increment just confuses the programmer into
thinking that it will work like in C. This still wouldn't get rid of side
effects, though, as x = x + 1 still evaluates x on the right-hand side of
Set.

Your example can be rewritten as

Lattice[[#]]++& /@ Table[Random[Integer, {1, 100}], {16000}]

For further speed-up, this can be compiled:

Lattice = Compile[{},
Module[{Lattice},
Lattice = Table[0, {100}];
Lattice[[#]]++& /@ Table[Random[Integer, {1, 100}], {16000}];
Lattice
]][];

Sow and Reap give comparable performance:

Lattice = Last@ Reap[
Sow[0, Range@ 100];
Sow[0, Table[Random[Integer, {1, 100}], {16000}]],
_, Length@ #2 - 1&];

If the number of tries is much larger than 16000, then the compiled
version takes several times less memory than uncompiled, most likely due
to the use of packed arrays.

Maxim Rytin
m.r at inbox.ru

```

• Prev by Date: Re: For Loop and Array related
• Next by Date: Re: problem with InverseLaplaceTransform
• Previous by thread: Re: For Loop and Array related
• Next by thread: Re: For Loop and Array related