1
$\begingroup$

I am doing a very small job of making points rotate or diffuse randomly on a circle.

I generate the particles using positions = RandomPoint[Circle[],100] and create an identity for individual particles using

indexed = MapIndexed[First@#2 -> #1 &, positions];

Code for rotating particles

(* strategy : get all the points. rotate them using a random number
(angle) generated from a Gaussain function. export updated points out
of the module *)

BrownianWalkCircle[particlepos_, particleind_] := 
Module[{newposition, index, angle, center},
center = {0, 0};
angle = Pi/1800.; (* 0.1 degree rotation about center {0,0} *)

newposition = 
RotationTransform[RandomVariate[NormalDistribution[0, angle]],center][#] & /@particlepos; 
(* in the line above we generate the new position *)

index = Thread[Range[Length@particleind] -> newposition]; (* new
position associated with particle name or identity *)

{newposition, index}] /; Length@particlepos > 0

Now I am using the following code to draw the circle and points that are in motion on the circle

Monitor[For[i = 1, i < 3500, i++,
{positions, indexed} = BrownianWalkCircle[positions, indexed];
g = Graphics[{Circle[], Red, Point@positions}]
], g]

Problem

I get the following message almost always when i use 100 particles:

Flatten::flpi: Levels to be flattened together in {{1,3},{2,4}} should be lists of positive integers. >>

The simulation runs fine (see the picture below)

enter image description here

I never get this message with fewer particles say if i use 40 particles instead of 100.

Can anyone suggest what is the reason and how this message can be avoided?

$\endgroup$
1
$\begingroup$

Update

(I have given more thought to the problem and have come up with what I think is a better answer.)

I have good news and bad news.

First the good news.

  1. I was able to compress your code into something very simple. That eliminated a lot code that might have been harboring a bug that was causing the messages.
  2. I can tell you how to avoid the error messages.

Now the bad news.

  1. I could not determine where the error messages are coming from.
  2. I can't give a fix, only a work around.

Code using Do to perform the iteration

With[{angle = 1/2 Degree}, 
  brownianWalkCircle[pts : {{_, _} ..}] := 
    RotationTransform[RandomVariate[NormalDistribution[0, angle]]][#] & /@ pts]

Do is simpler and quicker than For.

With[{nPts = 123, nSteps = 100},
  Module[{p, g},
    p = RandomPoint[Circle[], nPts];
    Monitor[
      Do[
        p = Quiet[brownianWalkCircle[p]];
        g = Graphics[{Circle[], Red, AbsolutePointSize[5], Point[p]}], 
       nSteps],
    g]]]

The above is all the code that is needed to show both the problem and the work-around, which is adding the Quiet wrapper. When messages are coming from somewhere deep in Wolfram's code, this is the bandage to apply.

Code using Nest

I include this as a variant approach to iterating over many steps.

With[{nPts = 123, nSteps = 100},
  Module[{p, g},
    Monitor[
      Nest[
        (p = Quiet[brownianWalkCircle[#]]; 
         g = Graphics[{Circle[], Red, AbsolutePointSize[5], Point[p]}];
         p) &,
        RandomPoint[Circle[], nPts],
        nSteps];,
   g]]]

Note

I recant on my previous assertion that the error message is coming from Graphics. See my revised code above, where wrapping brownianWalkCircle with Quiet is sufficient to suppress the error messages. Frankly, I can't really say anything about how the messages get produced.

$\endgroup$
  • 1
    $\begingroup$ You don't really need to use Map[] with RotationTransform[]; thus, With[{angle = Degree/2}, brownianWalkCircle[pts : {{_, _} ..}] := RotationTransform[RandomVariate[NormalDistribution[0, angle]]][pts]] $\endgroup$ – J. M.'s technical difficulties Dec 11 '16 at 5:25
  • $\begingroup$ Thanks so much @m_goldberg. I am accepting your answer. And also thanks a lot for the cleaner code. Btw if you look at mathematica.stackexchange.com/questions/132525/… do you think i should avoid global variables and the For loop used in this question $\endgroup$ – Ali Hashmi Dec 11 '16 at 11:31
  • $\begingroup$ @m_goldberg actually in the above question what i did was create a bunch of global variable and then update the values of those variables in each iteration in the For loop like in the question posted above. The methods that update the values use functional strategy. Do you think that should be avoided as well $\endgroup$ – Ali Hashmi Dec 11 '16 at 11:33
  • $\begingroup$ @m_goldberg perhaps something like Nest[(all functions in succession), initial configuration of the system, steps for iteration]. what do you think? $\endgroup$ – Ali Hashmi Dec 11 '16 at 11:54
  • 1
    $\begingroup$ @AliHashmi. I am not saying you should always avoid global variables. They certainly have their legitimate uses. But none were necessary in the test code, and I don't like to use them when there is no need. You might find Do a good iterator, suited to your work, and easier to use than Nest. See the updates I have made above. $\endgroup$ – m_goldberg Dec 11 '16 at 16:40

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.