1

EDIT: CHanged the code. Please try again t see if it works well on our PCs.

I am creating a simple Manipulate[] notebook. However when I place Table[] in the code, like:

Manipulate[ 
 OK = True;


 ai = ConstantArray[0, MaxIter + 1]; 
 bi = ConstantArray[0, MaxIter + 1]; 
 ci = ConstantArray[0, MaxIter + 1];
 ai[[1]] = a0; bi[[1]] = b0; ci[[1]] = (ai[[1]] + bi[[1]])/2;
 Table[ (*This instruction causes problems*)
  a = ai[[j - 1]]; b = bi[[j - 1]]; c = ci[[j - 1]];
  If[(f /. x -> a) (f /. x -> c) <= 0, ai[[j]] = ai[[j - 1]]; 
   bi[[j]] = ci[[j - 1]];, 
   If[(f /. x -> b) (f /. x -> c) <= 0, ai[[j]] = ci[[j - 1]]; 
     bi[[j]] = bi[[j - 1]];, OK = False; break;];];
  ci[[j]] = (ai[[j]] + bi[[j]])/2;
  , {j, 2, i}];

 If[OK, Show[Plot[f, {x, a0, b0}, PlotStyle -> Thick], 
   PlotLabel -> "Metoda bisekcji", ImageSize -> Large]]
 , 
 (*controls*)

 Dynamic@Column@{
    Control[{{f, x^2 - 1, "f(x)="}, {x^2 - 1, Cos[x] - x}}],
    Control[{{method, "Bisekcji", "Metoda:"}, {"Bisekcji", "Newtona", 
       "Iteracji prostej", "Siecznych"}}],
    Sequence @@ 
     If[method == "Bisekcji" || 
       method == 
        "Siecznych" , {Control[{{a0, 1/2, 
          "\!\(\*SubscriptBox[\(a\), \(0\)]\)="}}], 
       Control[{{b0, 2, 
          "\!\(\*SubscriptBox[\(b\), \(0\)]\)="}}]}, {Control[{{x0, 2,
           "\!\(\*SubscriptBox[\(x\), \(0\)]\)="}}]}],
    Control[{{i, 1, "Iteracja"}, 1, 5, 1}]
    },
 (*Initialization*)
 Initialization :> (
   MaxIter = 5;
   ) 
 ]

The cell containing the GUI keeps evaluating all the time and the displayed content keeps being refreshed and looks like shaking. Is it normal?

Misery
  • 2,640
  • 1
  • 30
  • 39

1 Answers1

4

The problem is that some variables are set in the main body of the Manipulate every time the Manipulate is updated. This triggers another update...ad infinitum.

Use TrackedSymbols to control when an update is triggered.

Manipulate[OK = True;
 ai = ConstantArray[0, MaxIter + 1];
 bi = ConstantArray[0, MaxIter + 1];
 ci = ConstantArray[0, MaxIter + 1];
 ai[[1]] = a0; bi[[1]] = b0; ci[[1]] = (ai[[1]] + bi[[1]])/2;
 Table[(*This instruction causes problems*)a = ai[[j - 1]]; 
  b = bi[[j - 1]]; c = ci[[j - 1]];
  If[(f /. x -> a) (f /. x -> c) <= 0, ai[[j]] = ai[[j - 1]];
   bi[[j]] = ci[[j - 1]];, 
   If[(f /. x -> b) (f /. x -> c) <= 0, ai[[j]] = ci[[j - 1]];
     bi[[j]] = bi[[j - 1]];, OK = False; break;];];
  ci[[j]] = (ai[[j]] + bi[[j]])/2;, {j, 2, i}];
 If[OK, Show[Plot[f, {x, a0, b0}, PlotStyle -> Thick], 
   PlotLabel -> "Metoda bisekcji", ImageSize -> Large]],

 (*controls*)
 Dynamic@Column@{Control[{{f, x^2 - 1, "f(x)="}, {x^2 - 1, 
       Cos[x] - x}}], 
    Control[{{method, "Bisekcji", "Metoda:"}, {"Bisekcji", "Newtona", 
       "Iteracji prostej", "Siecznych"}}], 
    Sequence @@ 
     If[method == "Bisekcji" || 
       method == 
        "Siecznych", {Control[{{a0, 1/2, 
          "\!\(\*SubscriptBox[\(a\), \(0\)]\)="}}], 
       Control[{{b0, 2, 
          "\!\(\*SubscriptBox[\(b\), \(0\)]\)="}}]}, {Control[{{x0, 2,
           "\!\(\*SubscriptBox[\(x\), \(0\)]\)="}}]}], 
    Control[{{i, 1, "Iteracja"}, 1, 5, 1}]},

 TrackedSymbols :> {i, a0, b0, method, f},

 (*Initialization*)Initialization :> (MaxIter = 5;)]

The rest of it needs work, apparently, but TrackedSymbols solves the continual-updating problem. One can also simply set TrackedSymbols -> True to track only the control variables.

Michael E2
  • 235,386
  • 17
  • 334
  • 747