4
$\begingroup$

Let's say I have a function which returns the resulting function of a differential equation solved by NDSolve:

solveDiffEq[a_] := {
  sol = NDSolve[
    {f''[t] == a*f[t], f[0] == 1, f'[0] == 1},
    f,
    {t, 0, 1}];
  {AbsoluteTime[], f[t] /. sol[[1]]}
  }

The time is included to check when the function is called. For example,

solveDiffEq[1][[1]] /. t -> 0.2

{3.644828015580337*10^9, 1.2214}

Now I display this output inside a manipulate as follows:

Manipulate[
 solveDiffEq[a0][[1]] /. t -> t0
 ,
 {t0, 0, 1},
 {a0, 1, 2}
 ]

The problem is that this re-evaluates the solveDiffEq function both when a0 is changed or when t0 is changed (you can observe when the solveDiffEq function is called by observing the changing time).

Obviously, when the slider a0 is changed, the function should re-solve the diff eq. However, when t0 is changed, there is no need to resolve the diff eq. - only to evaluate the returned interpolating function at a different point. I would like for this to be the behavior.

There is probably a simple trick; I suspect this has something to do with

/. t-> t0

Thanks in advance!

$\endgroup$
5
  • $\begingroup$ You may consider something like Manipulate[ s = solveDiffEq[a0]; Manipulate[s /. t -> t0, {t0, 0, 1}] , {a0, 1, 2}] $\endgroup$ Commented Jul 2, 2015 at 20:24
  • $\begingroup$ Thanks! This has the correct behavior, however, can it be done in a single manipulate statement? $\endgroup$
    – smörkex
    Commented Jul 2, 2015 at 20:26
  • $\begingroup$ Not with Manipulate AFAIK, but I may be wrong $\endgroup$ Commented Jul 2, 2015 at 20:27
  • $\begingroup$ This seems to work : Manipulate[ s = solveDiffEq[a0]; Dynamic[s /. t -> t0], {t0, 0, 1}, {a0, 1, 2}] $\endgroup$
    – andre314
    Commented Jul 2, 2015 at 20:56
  • $\begingroup$ @belisarius There is a problem with your code : when you move the cursor a0, t0 return to 0. I don't think that's expected from the OP. $\endgroup$
    – andre314
    Commented Jul 2, 2015 at 21:04

1 Answer 1

5
$\begingroup$

You must use a Dynamic[] in your Manipulate[]. It is documented in the "Advanced Manipulate Tutorial" (chapter "Using Dynamic inside Manipulate") :

solveDiffEq[a_] := {
  sol = NDSolve[
    {f''[t] == a*f[t], f[0] == 1, f'[0] == 1},
    f,
    {t, 0, 1}];
  {AbsoluteTime[], f[t] /. sol[[1]]}
  };

Manipulate[
     s = solveDiffEq[a0];
     Dynamic[s /. t -> t0],
     {t0, 0, 1},
     {a0, 1, 2}
     ]

The idea to use the separate variable s comes from Belisarius's comments.

$\endgroup$
1
  • $\begingroup$ Thanks, this works! I knew it had to be something simple, couldn't figure it out $\endgroup$
    – smörkex
    Commented Jul 2, 2015 at 22:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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