Message Boards Message Boards

0
|
3735 Views
|
6 Replies
|
0 Total Likes
View groups...
Share
Share this post:

[?] Avoid Manipulate causing CPU loop?

Posted 5 years ago

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"}
]
POSTED BY: Albert Cattani
6 Replies
Posted 5 years 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"}
]
POSTED BY: Albert Cattani

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

POSTED BY: Gianluca Gorni
Posted 5 years 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"}
 ]
POSTED BY: Albert Cattani
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 BY: Martijn Froeling
Posted 5 years 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

POSTED BY: Albert Cattani

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..

POSTED BY: Martijn Froeling
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