# Declaring functions in NDSolve? [duplicate]

I have a simple enough series of coupled ODES, which is relatively easy to solve. It looks something like this.

err = 0.05; jc = 2500; b = 0.7; k = 1; pt = 2; pf = 1; n = 3;

sdp :=  pt + err*pf;
scp :=  pt + erri*pf;
sup :=  pt + err*pf + delt;

sdn :=    bd*n;
scn :=  bc*n;
sun :=   bu*n;

vp[t_] :=  (jc*b)/(x[t]*sdp + y[t]*scp + z[t]*sup );
vn[t_] :=  (jc*(1 - b))/(x[t]*sdn + y[t]*scn + z[t]*sun );

pd[t_] := vp[t]*sdp + vn[t]*sdn;
pc[t_] := vp[t]*scp + vn[t]*scn;
pu[t_] := vp[t]*sup + vn[t]*sun;

ad[t_] :=  (pd[t]*(x[t] + y[t] + z[t]))/(x[t]*pd[t] + y[t]*pc[t] + z[t]*pu[t]);
ac[t_] :=  (pc[t]*(x[t] + y[t] + z[t]))/(x[t]*pd[t] + y[t]*pc[t] + z[t]*pu[t]);
au[t_] :=  (pu[t]*(x[t] + y[t] + z[t]))/(x[t]*pd[t] + y[t]*pc[t] + z[t]*pu[t]);


Now, if I declare some other constants, it's easy to solve my equations:

   delt = 0.25; erri =  3*err; bd = 0.3; bc = 0.3; bu = 0.3;

eqns = {x'[t] == k*x[t]*(ad[t] - 1), y'[t] == k*y[t]*(ac[t] - 1),
z'[t] == k*z[t]*(au[t] - 1), x[0] == 1800, y[0] == 100, z[0] == 10};

fun1 = NDSolve[eqns, {x,y,z}, {t,0,10}];
Plot[Evaluate[x[t]/.fun1],{t,0,10}]


But what I really want to do is put $delt$, $erri$, $bd$, $bc$ and $bu$ inside the MANIPULATE environment. This works fine if I write all $x'$, $y'$ and $z'$ explicitly in terms of these variables but is messy and extremely long. So what I tried was something like this;

Manipulate[{Plot[Evaluate[x[t] /. NDSolve[eqns, {x, y, z}, {t, 0, 10}]], {t, 0, 10}],
Plot[Evaluate[y[t] /. NDSolve[eqns, {x, y, z}, {t, 0, 10}]], {t, 0,10}],
Plot[Evaluate[z[t] /. NDSolve[eqns, {x, y, z}, {t, 0, 10}]], {t, 0, 10}]},
{{bd, 0, "bd variable"}, 0, 1}, {{erri, err, "erri variable"}, err, 1},
{{bc, 0, "bc variable"}, 0, 1}, {{bu, 0, "bu variable"}, 0,
1}, {{delt, 0, "delt variable"}, 0, 5}]


Yet when I run this, I get a non-numerical value error. I think this is because the variables are not being explicitly considered from their parent equations, but I'm not sure how to enter this in so it works; I thought the SetDelay notation would work but apparently not. Anyone have any ideas on the syntax to make this work?

• Please remove any unnecessary material and reduce your problem down to a minimal working example (e.g. remove definitions that you don't use in the problematic codes etc). Commented Feb 12, 2016 at 15:20
• As @MarcoB says, you should try to come up with a minimal example. Try to see if you can reproduce the problem in a simple case where there is only one differential equation with only one parameter that you would like to Manipulate. Commented Feb 12, 2016 at 16:44
• I don't think this will work. I suggest you read up on ParametricNDSolve, it may be better suited to this job. Commented Feb 13, 2016 at 12:31

This is mentioned in the possible issues of document of Manipulate: Manipulate only "notices" explicit visible parameters. The easiest way I can think of to fix your code is to use With to make those parameters explicit:

Clear[bd, erri, bc, bu, delt]
eqns = {x'[t] == k*x[t]*(ad[t] - 1), y'[t] == k*y[t]*(ac[t] - 1),
z'[t] == k*z[t]*(au[t] - 1), x[0] == 1800, y[0] == 100, z[0] == 10};

With[{eqns = eqns},
Manipulate[{Plot[Evaluate[x[t] /. NDSolve[eqns, {x, y, z}, {t, 0, 10}]], {t, 0, 10}],
Plot[Evaluate[y[t] /. NDSolve[eqns, {x, y, z}, {t, 0, 10}]], {t, 0, 10}],
Plot[Evaluate[z[t] /. NDSolve[eqns, {x, y, z}, {t, 0, 10}]], {t, 0, 10}]}, {{bd, 0.3,
"bd variable"}, 0, 1}, {{erri, 3 err, "erri variable"}, err,
1}, {{bc, 0.3, "bc variable"}, 0, 1}, {{bu, 0.3, "bu variable"}, 0,
1}, {{delt, 0.25, "delt variable"}, 0, 5}]]