Message Boards Message Boards

GROUPS:

[✓] Avoid Manipulate causing CPU loop?

Posted 1 month ago
352 Views
|
6 Replies
|
0 Total Likes
|

Hello

I am looking for a better understanding of the behavior of Manipulate when using a Module. I know this is a larger topic but I have a specific question.

I will post my code at the end for reference.

I have a function defined inside Manipulate and all is working as expected however Mathematica pegs one of my CPUs to 100% even after the results are calculated and returned.

I read an article saying a function inside Manipulate will be continuously reevaluated even when sliders are not being changed. The article suggested placing the function inside a Module to prevent reevaluation by Manipulate unless something changes like a Slider value.

My question is – Why is this necessary? Why does Mathematica loop the function causing constant CPU usage? I almost understand why using Module resolves the problem but am I confused why this is the default behavior of Manipulate.

If I remove the Module below the CPU loop returns.

Code is below. This is a SpiroGraph emulator I am fooling around with.

Manipulate[Module[{Cx,Cy,Fx,Fy},

l=p/r; (* Drawing hole radius as a percent of drawing disk radius *)
k=r/R0;(* Drawing disk radius as a percent of stationary outer ring radius *)

Cx[t_]:=R0*Sin[t]; (* X coordinate of stationary outer ring *)
Cy[t_]:=R0*Cos[t];(* Y coordinate of stationary outer ring *)

Fx[t_]:=R0*((1-k)*Cos[t]+(l*k*Cos[((1-k)/k)*t]));
Fy[t_]:=R0*((1-k)*Sin[t]-(l*k*Sin[((1-k)/k)*t]));


ParametricPlot[{{Fx[t1],Fy[t1]},{Cx[t1],Cy[t1]}},{t1,0,R Pi}]],
{{R0,32,"Stationary ring inner radius"},10,200,10,Appearance->"Labeled"},
{{r,IntegerPart[R0/2]-1,"Drawing disk radius"},1,R0,1,Appearance->"Labeled"},
{{p,IntegerPart[r/2]-1,"Drawing hole radius"},1,r,1,Appearance->"Labeled"},
{{R,30,"Number of rotations"},1,100,10,Appearance->"Labeled"}
]
6 Replies
Posted 1 month ago

I do not know why the code I pasted did not display correctly. Trying again.

Code is below. This is a SpiroGraph emulator I am fooling around with.

Manipulate[Module[{Cx,Cy,Fx,Fy},

l=p/r; (* Drawing hole radius as a percent of drawing disk radius *)
k=r/R0;(* Drawing disk radius as a percent of stationary outer ring radius *)

Cx[t_]:=R0*Sin[t]; (* X coordinate of stationary outer ring *)
Cy[t_]:=R0*Cos[t];(* Y coordinate of stationary outer ring *)

Fx[t_]:=R0*((1-k)*Cos[t]+(l*k*Cos[((1-k)/k)*t]));
Fy[t_]:=R0*((1-k)*Sin[t]-(l*k*Sin[((1-k)/k)*t]));


ParametricPlot[{{Fx[t1],Fy[t1]},{Cx[t1],Cy[t1]}},{t1,0,R Pi}]],
{{R0,32,"Stationary ring inner radius"},10,200,10,Appearance->"Labeled"},
{{r,IntegerPart[R0/2]-1,"Drawing disk radius"},1,R0,1,Appearance->"Labeled"},
{{p,IntegerPart[r/2]-1,"Drawing hole radius"},1,r,1,Appearance->"Labeled"},
{{R,30,"Number of rotations"},1,100,10,Appearance->"Labeled"}
]

Your code is unreadable. Please use the code sample button.

Posted 1 month ago

I never knew about the code sample button. Thanks!. see below code.

ClearAll;
(*Clear[n]*)
ClearAll["Global`*"]

Manipulate[Module[{Cx, Cy, Fx, Fy},

  l = p/r ;(* 
  Drawing hole radius as a percent of drawing disk radius *)

  k = r/R0;(* 
  Drawing disk radius as a percent of stationary outer ring radius *)
\

  Cx[t_] := R0*Sin[t]; (* X coordinate of stationary outer ring *)

  Cy[t_] := R0*Cos[t];(* Y coordinate of stationary outer ring *)

  Fx[t_] := R0*((1 - k)*Cos[t] + (l*k*Cos[((1 - k)/k)*t]));
  Fy[t_] := R0*((1 - k)*Sin[t] - (l*k*Sin[((1 - k)/k)*t]));

  ParametricPlot[{{Fx[t1], Fy[t1]}, {Cx[t1], Cy[t1]}}, {t1, 0, R Pi}]],
 {{R0, 32, "Stationary ring inner radius"}, 10, 200, 10, 
  Appearance -> "Labeled"},
 {{r, IntegerPart[R0/2] - 1, "Drawing disk radius"}, 1, R0, 1, 
  Appearance -> "Labeled"},
 {{p, IntegerPart[r/2] - 1, "Drawing hole radius"}, 1, r, 1, 
  Appearance -> "Labeled"},
 {{R, 30, "Number of rotations"}, 1, 100, 10, 
  Appearance -> "Labeled"}
 ]
Manipulate[
 l = p/r;(*Drawing hole radius as a percent of drawing disk radius*)
 k = r/R0;(*Drawing disk radius as a percent of stationary outer ring \
radius*)

 r = Clip[Round[r], {1, R0 - 1}];
 p = Clip[Round[p], {1, r - 1}];

 ParametricPlot[{
   R0 ((1 - k) Cos[t1] + (l k Cos[((1 - k)/k)*t1])),
   R0 ((1 - k) Sin[t1] - (l k Sin[((1 - k)/k)*t1]))
   }, {t1, 0, R Pi},
  Epilog -> Circle[{0, 0}, R0], 
  PlotRange -> R0 {{-1.1, 1.1}, {-1.1, 1.1}}]

 ,

 {{R0, 32, "Stationary ring inner radius"}, 10, 200, 10, 
  Appearance -> "Labeled"},

 {{r, Round[R0/2], "Drawing disk radius"}, 1, Dynamic[R0 - 1], 1, 
  Appearance -> "Labeled"},
 {{p, Round[r/2], "Drawing hole radius"}, 1, Dynamic[r - 1], 1, 
  Appearance -> "Labeled"},

 {{R, 30, "Number of rotations"}, 1, 150, 10, Appearance -> "Labeled"},

 {l, ControlType -> None},
 {k, ControlType -> None}
 ]
Posted 1 month ago

Thank you Martijn for your reply. I see I could have avoided the CPU loop taking a different approach avoiding the Function definitions. But what I am trying to understand is how do I know what triggers the CPU looping? Is this something I can anticipate, and thus avoid, or is this a guessing game of what to avoid via trial and error?

I want to develop a list of best practices for Mathematica and right now understanding what causes the CPU looping is my goal.

I have other programs that work just fine (no CPU loop) and others that loop. I hope to understand the reasons why.

thanks

Al

no clue why, it didn't happen on my system.

i would always prevent using function definition within a dynamic environement since function evaluation can be done using Initialization or out side the manipulate command. If the input of the function is a dynamic parameter the function will reevaulate anyways.

Manipulate[
 l = p/r;(*Drawing hole radius as a percent of drawing disk radius*)
 k = r/R0;

 (*Drawing disk radius as a percent of stationary outer ring radius*)
 r = Clip[Round[r], {1, R0 - 1}];
 p = Clip[Round[p], {1, r - 1}];

 ParametricPlot[{
   Fx[t1], Fy[t1]}, {t1, 0, R Pi},
  Epilog -> Circle[{0, 0}, R0],
  PlotRange -> R0 {{-1.1, 1.1}, {-1.1, 1.1}}]
 ,
 {{R0, 32, "Stationary ring inner radius"}, 10, 200, 10, 
  Appearance -> "Labeled"},
 {{r, Round[R0/2], "Drawing disk radius"}, 1, Dynamic[R0 - 1], 1, 
  Appearance -> "Labeled"},
 {{p, Round[r/2], "Drawing hole radius"}, 1, Dynamic[r - 1], 1, 
  Appearance -> "Labeled"},
 {{R, 30, "Number of rotations"}, 1, 150, 10, Appearance -> "Labeled"},
 {l, ControlType -> None}, {k, ControlType -> None}
 , Initialization :> {
   Fx[t1_] := R0 ((1 - k) Cos[t1] + (l k Cos[((1 - k)/k)*t1])),
   Fy[t1_] := R0 ((1 - k) Sin[t1] - (l k Sin[((1 - k)/k)*t1]))
   }
 ]

Also using module within manipulate can be prevented by using the local parameters as manipulate variables without a control. this also localizes the variables, not sure but DynamicModule could be used instead if the parameter definitions should be dynamic..

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract