# Manipulate and ParametricNDSolve

EDIT: typo spotted in comments, code reposted with fix as well as new behavior

I'm having trouble getting mathematica to give me a working plot. I've defined specific values for my parameters:

b = 0.1372;
g = 1/7;
soln = NDSolve[{X'[t] + b*X[t]*Y[t]/2700000 == 0,
Y'[t] - b*X[t]*Y[t]/2700000 + g*Y[t] == 0, Z'[t] - g*Y[t] == 0,
X[0] == 2700000 - Y[0], Y[0] == b*2700000, Z[0] == 0}, {X, Y,
Z}, {t, 0, 180}, MaxSteps -> Infinity];
Plot[{Evaluate[X[t] /. soln], Evaluate[Y[t] /. soln],
Evaluate[Z[t] /. soln]}, {t, 0, 180}, PlotRange -> {0, 3000000},
PlotLabels -> {"S", "I", "R"}]


and got a good plot. I tried to scale this up for manipulate:

ClearAll;
soln = ParametricNDSolve[
{
X'[t] + b*X[t]*Y[t]/2700000 == 0,
Y'[t] - b*X[t]*Y[t]/2700000 + g*Y[t] == 0,
Z'[t] - g*Y[t] == 0,
X[0] == 2700000 - Y[0],
Y[0] == b*2700000,
Z[0] == 0
},
{{X[t], Y[t], Z[t]}},
{t, 0, 500},
{b, g}];
Manipulate[
ParametricPlot[
soln[b, g],
{t, 0, 500},
PlotRange -> {0, 3000000}
],
{b, 0.01, .999},
{g, 0.01, .999}
]


and nothing fruitful came out. The sliders show up, but the plot window is highlighted red, and I get error output:

ParametricNDSolve::dspar: 1 cannot be used as a parameter.

ParametricNDSolve::dspar: 1. cannot be used as a parameter.

ParametricNDSolve::dspar: 1 cannot be used as a parameter.

General::stop: Further output of ParametricNDSolve::dspar will be suppressed during this calculation.

• try ParametricNDSolve and not ParamatricNDSolve and see if that works. When the color is blue it means Mathematica does not know about it. – Nasser Nov 25 '19 at 23:39
• Will update original post, thanks for catching that. – Johnathan Marquardt Nov 25 '19 at 23:43

Not sure why you want to use ParametricPlot in the Manipulate, while you had used Plot in your first visualization. Consider that you have three components in your solution, so that would not make sense for a 2D parametric plot; you would have to use ParametricPlot3D instead. I suspect that neither are what you want, and instead you simply want plots of the three components as a function of the $$b,g$$ parameters, in which case Plot will do.

Here are a few modifications that at least allow you to see the shape of the results. In particular, I changed to ParametricNDSolveValue and I removed one level of braces in your desired result (i.e. {X[t], Y[t], Z[t]} and not {{X[t], Y[t], Z[t]}}. I then used Plot instead of ParametricPlot inside Manipulate.

ClearAll[b, g, t, soln]
soln = ParametricNDSolveValue[{X'[t] + b*X[t]*Y[t]/2700000 == 0,
Y'[t] - b*X[t]*Y[t]/2700000 + g*Y[t] == 0, Z'[t] - g*Y[t] == 0,
X[0] == 2700000 - Y[0], Y[0] == b*2700000, Z[0] == 0},
{X[t], Y[t], Z[t]}, {t, 0, 500}, {b, g}];

Manipulate[
Plot[Evaluate@soln[b, g], {t, 0, 500}, PlotRange -> {0, 3000000}],
{{b, 0.05}, 0.01, .999}, {g, 0.01, .999}
]


I chose a starting value for b that would give a more interesting / pleasing plot, but that adds nothing to the functionality.

• This is wonderful and exactly what I was looking for. Thank you! – Johnathan Marquardt Nov 26 '19 at 0:06
• This is a great answer! Sorry I accidentally downvoted it, it’s now locked in and I can’t adjust the vote. This is a strange pattern for me (mobile browsing when too tired, hah!). This would look really cool in 3D! – CA Trevillian Dec 6 '19 at 18:33

For simulation purposes, one can use the following code with a button to generate different sets of parameters at the same time rather than changing individual parameters. The example uses "Initialization" to change parameters (k1,k2,k3,k11,k22) at the same time. Press Button to generate new parameter values for (k1,k2,k3,k11,k22) based on Initialization.

Clear[Evaluate[Context[] <> "*"]];
Clear[eqns, init, vars, param, solNL];

eqns = {
y1'[t] == -k1*y1[t]*y2[t] + k11*y3[t],
y2'[t] == -k1*y1[t]*y2[t] + k3*y5[t] + k11*y3[t],
y3'[t] == k1*y1[t]*y2[t] - k2*y3[t]*y4[t] + k22*y5[t] - k11*y3[t],
y4'[t] == -k2*y4[t]*y3[t] + k22*y5[t],
y5'[t] == k2*y3[t]*y4[t] - k22*y5[t] - k3*y5[t],
y6'[t] == k3*y5[t]
};
init = {
y1[0] == 30,
y2[0] == 1,
y3[0] == 0,
y4[0] == 20,
y5[0] == 0,
y6[0] == 0
};
vars = {y1, y2, y3, y4, y5, y6};
param = {k1, k2, k3, k11, k22};

solNL = ParametricNDSolveValue[
{eqns, init},
vars,
{t, 0, 20},
param
];

Manipulate[
Plot[
Evaluate[#[t] & /@ solNL[k1, k2, k3, k11, k22]], {t, 0, 20},
PlotLegends -> vars
],
Button["generate new parameters", {k1, k2, k3, k11, k22} = random[]],
Initialization :> (random[] := {RandomReal[{1, 2}],
RandomReal[{1, 2}], RandomReal[{2, 5}], RandomReal[{2, 8}],
RandomReal[{2, 4}]}; {k1, k2, k3, k11, k22} = random[];)
]
`