How to control when NDSolve is called inside Manipulate

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 == 1, f' == 1},
f,
{t, 0, 1}];
{AbsoluteTime[], f[t] /. sol[]}
}

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

solveDiffEq[] /. t -> 0.2

{3.644828015580337*10^9, 1.2214}

Now I display this output inside a manipulate as follows:

Manipulate[
solveDiffEq[a0][] /. 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

• You may consider something like Manipulate[ s = solveDiffEq[a0]; Manipulate[s /. t -> t0, {t0, 0, 1}] , {a0, 1, 2}] – Dr. belisarius Jul 2 '15 at 20:24
• Thanks! This has the correct behavior, however, can it be done in a single manipulate statement? – smörkex Jul 2 '15 at 20:26
• Not with Manipulate AFAIK, but I may be wrong – Dr. belisarius Jul 2 '15 at 20:27
• This seems to work : Manipulate[ s = solveDiffEq[a0]; Dynamic[s /. t -> t0], {t0, 0, 1}, {a0, 1, 2}] – andre314 Jul 2 '15 at 20:56
• @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. – andre314 Jul 2 '15 at 21:04

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 == 1, f' == 1},
f,
{t, 0, 1}];
{AbsoluteTime[], f[t] /. sol[]}
};

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.

• Thanks, this works! I knew it had to be something simple, couldn't figure it out – smörkex Jul 2 '15 at 22:20