Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Normally, when using Manipulate[expr, controls, options], the graphics updating should be carried out at the very end of expr.

But now I encounter a situation where the graphics result is evaluated at each step inside a double-Fold-iteration. Yes I can still adopt the method mentioned above and write following code,

DynamicModule[{g},
 Manipulate[
  Module[{a},
   Fold[(
      k = #2;
      Fold[(a = #2; g = v[a, k]; Pause[.05]) &, {}, Range[5]]
     ) &, {}, Range[15]];
   Dynamic@g
  ],
 {{k, 1}, ControlType -> None},
 TrackedSymbols :> {},
 SynchronousUpdating -> Automatic,
 Initialization :> (v[a_, k_] := Plot[Sin[x (a + k x)], {x, 0, 6}])]
]

But the problem is that I will have to first wait for the double-Fold-evaluation to complete and only after this can I see the updates in a queued sequence. The code I used here is but an over-simplified example and the actual code will take much longer time for computation. I wonder if it is possible to do the graphics updating at every iteration step when v[a, k] is evaluated?

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

Here's a possible way. The question is how one wants to trigger the double-Fold calculation to begin. In this example, I used a Button with Method -> "Queued".

Manipulate[
 Dynamic@g,

 {{k, 1}, ControlType -> None},
 {{g, Graphics[{}, AspectRatio -> 1/GoldenRatio]}, ControlType -> None},
 {{v, v}, ControlType -> None},
 Button["go",
   Module[{a},
    Fold[(k = #2; Fold[(a = #2; g = v[a, k]; Pause[.05]) &, {}, Range[5]]) &, {}, Range[15]]],
   Method -> "Queued"],
 TrackedSymbols :> {}, SynchronousUpdating -> Automatic, 
 Initialization :> (v[a_, k_] := Plot[Sin[x (a + k x)], {x, 0, 6}])]

Edit

Here a simulation of the Fold. Unfortunately, nesting the Dynamics interferes with a clean modeling of Fold. One is better off using UpdateInterval than Pause. Pause happens in the kernel and can cause synchronization issues.

Manipulate[
 Dynamic[
  k = First@k0;
  a0 = Range[5];
  Dynamic[Refresh[
    a = First @ a0;
    If[Length@a0 > 1,
     a0 = Rest @ a0,
     k = First @ k0; If[Length@k0 > 1, k0 = Rest @ k0]];
    v[a, k],
    TrackedSymbols :> {}, UpdateInterval -> 0.05]]
  ],

 {{k, 1}, ControlType -> None}, {{a, 1}, ControlType -> None},
 {{k0, Range[15]}, ControlType -> None}, {{a0, Range[5]}, ControlType -> None},
 {{v, v}, ControlType -> None},
 TrackedSymbols :> {}, 
 Initialization :> (v[a_, k_] := Plot[Sin[x (a + k x)], {x, 0, 6}, PlotLabel -> {k, a}];)]

N.B. The Fold example in the OP just models a nested Do loop. To model a full fledged fold, a fuller is needed to work with.

share|improve this answer
    
Your solution exactly solves my problem, thank you Micheal E2! –  saturasl Jun 18 '13 at 23:53
    
@saturasl Thanks. I just added another solution, but the Button one is cleaner and less likely to cause problems as features are added to the demonstration. –  Michael E2 Jun 19 '13 at 0:00
    
@Micheal E2 I just got a trival question: In your Button solution, the current value of k can not be shown even with {Dynamic[k], Dynamic[g]}, because the evaluation is done outside the main body. I wonder if we could show both k and g simultaneously? –  saturasl Jun 19 '13 at 0:18
1  
@saturasl Try Dynamic[k, TrackedSymbols :> {k}] instead of just Dynamic[k]. Or Dynamic@Refresh[k, TrackedSymbols :> {k}]. –  Michael E2 Jun 19 '13 at 2:04
1  
It works, thanks! I also figured out the meaning of {{v, v}, ControlType -> None}: Because controls format are executed in advance to the Initialization options. So when firstly executing control, a undefined symbol v is asigned to the variable v; then while executing initialization, the symbol v is defined to be a function name, therefore the variable v now will be automatically recognized by the local master kernel as a function name. –  saturasl Jun 19 '13 at 5:37
show 1 more comment

You need to render g in FrontEnd before your Fold (or anything that changes g) is evaluated, thus you can monitor all changes happened to g in real-time. Also, you do not need Manipulate here. Something like this would be sufficient:

Dynamic[g]
Module[{a, k, v},
  v[a_, k_] := Plot[Sin[x (a + k x)], {x, 0, 6}];
  Fold[(k = #2;
     Fold[(a = #2; g = v[a, k]; Pause[.05]) &, {}, Range[5]]
     ) &, {}, Range[15]]
  ];

Or if you want to keep g local:

DynamicModule[{g},
  Cell[BoxData[MakeBoxes[Dynamic[g]]], "Output"] // CellPrint;
  Module[{a, k, v},
   v[a_, k_] := Plot[Sin[x (a + k x)], {x, 0, 6}];
   Fold[(k = #2;
      Fold[(a = #2; g = v[a, k]; Pause[.05]) &, {}, Range[5]]
      ) &, {}, Range[15]]
   ]
  ];
share|improve this answer
    
Yes you are right. Actually me current code is just in the first form you provided. However I want to submit my FEM code to WolframDemonstrationProject, so I will have to convert it using Manipulate. Still, thanks for your second code, there is something new to me. –  saturasl Jun 18 '13 at 20:25
add comment

I figured out a solution, using nested Refresh to simulate the two Folds in my previous code. In this way the graphics updating can still be put at the end of the innermost Refresh,

DynamicModule[{a = 1, k = 1, kprev = 1},
 Manipulate[
  Refresh[
   Refresh[
    Pause[.05];
    If[k != kprev, kprev = k; a = 1];
    g = v[a, k];
    Row[{Dynamic[a], Dynamic[k], Dynamic[g]}, ", "],

    If[run && a <= 5, a++];
    UpdateInterval -> If[run, If[a <= 5, 0, Infinity], Infinity]
   ],
   If[run && a > 5 && k <= 10, k++];
   UpdateInterval -> If[run, If[k <= 10, 0, Infinity], Infinity]
  ],

 {{run, False}, {True, False}, ControlType -> Checkbox},
 TrackedSymbols :> {run, a, k},
 SynchronousUpdating -> Automatic,
 Initialization :> (v[a_, k_] := 
 Plot[Sin[x (a + k x)], {x, 0, 6}, ImageSize -> 200])
]]

The remaining problem is, in this way the nested folds are destroyed and so is the efficiency advantage of using Fold...

share|improve this answer
    
I managed to come up with a possible solution, but this one may have efficiency issue. Hope someone can help to improve it. –  saturasl Jun 18 '13 at 22:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.