# Solving an ODE System with Multiple Initial Conditions

I am trying to use ParametricNDSolveValue to run ODE simulations with multiple initial conditions then plot the results with ParametricPlot3D. I want this method to scale, so that I could start with 10 to 20 different initial conditions. Below I have made an attempt with two different initial conditions stored in the list set. I do not know how to correct the code so the simulation works (there is no error messages). I think the problem is with Evaluate[sol[#1, #2, #3][t]] & set as different tests with other variations this code segment had the most errors associated with it.

My Attempt

Defining ODE System

Clear[x0, x1, x2]
Clear[A]
(*Parameter values *)
A = {{1/20, 1/4, 1/50}, {1/4, 1/26, 1/40}};
(*ODE System*)
ODEsys = {x0'[t] == x1[t]^2 + x2[t] - x0[t],
x1'[t] ==
x1[t] (1 - A[[1, 1]] x1[t] - A[[1, 2]] x2[t] - A[[1, 3]] x0[t]),
x2'[t] ==
x2[t] (1 - A[[2, 1]] x1[t] - A[[2, 2]] x2[t] - A[[2, 3]] x0[t])};
tmax = 100;


Simulation and Plotting

set = {{5.5468753., 6.36718753., 13.2031253.}, {3.8281253.,
36.253., 5.93753.}}
With[{tmax = 100},
sol = ParametricNDSolveValue[{ODEsys, {x1[0] == init1,
x2[0] == init2, x0[0] == init0}}, {x1, x2, x0}, {t, 0,
tmax}, {init1, init2, init0}]];
ParametricPlot3D[Evaluate[sol[#1, #2, #3][t]] & set, {t, 0, tmax},
PlotRange -> All, ImageSize -> Large]


Output

Notes

Try:

ParametricPlot3D[Evaluate[Through /@ (sol[#[[1]], #[[2]], #[[3]]][t] & /@ set)],
{t, 0, tmax}, PlotRange -> All, ImageSize -> Large]


There is probably a neater way though. Your version was missing the Map (/@), as well as trying to feed slots that weren't in the list, as they are subelements of the list instead. Then the Through is used to get the t values into the right place.

To try and help you understand what is going on out, your code had this construct (removing the Evaluate, which is needed to get the plot to realise it had multiple separate lines to plot in different colours):

sol[#1, #2, #3][t] &


which is a pure function that needs to take three arguments, like this example:

({#1, #2, #3} &) [5, 3, 2]
{5, 3, 2}


When you try and apply this kind of function to a list, it is only being passed one argument, not three, so you get the slotn error:

({#1, #2, #3} &) @{5, 3, 2}

Function::slotn: Slot number 2 in {#1,#2,#3}& cannot be filled from ({#1,#2,#3}&)[{5,3,2}]
{{5, 3, 2}, #2, #3}


Hence why I used #[1] etc (so take the first part of the argument).

({#[[1]], #[[2]], #[[3]]} &) @{5, 3, 2}
{5, 3, 2}


And if we want to Map this across a list, we use /@ instead of @:

({#[[1]], #[[2]], #[[3]]} &) /@ set
{{5.55, 6.37, 13.2}, {3.83, 36.3, 5.94}}


So now moving back to your function, we try:

(sol[#[[1]], #[[2]], #[[3]]][t] & /@ set)
{{InterpolatingFunction[], InterpolatingFunction[], InterpolatingFunction[]}[t],
{InterpolatingFunction[], InterpolatingFunction[], InterpolatingFunction[]}[t]}


Which evaluates, but if you look closely the [t] is being applied at the end of each list of InterpolationFunctions, not to each individual one, i.e. they are {a,b,c}[t] rather than {a[t],b[t],c[t]}. The function to move the [t] to the right place is Through:

Through[{a,b,c}[t]]
{a[t], b[t], c[t]}


But this needs applying on each individual sublist, so we use Map again to get the Through to the right place. And then wrap it in an Evaluate in order to get the colours on the plot.

Basically take the bit of code outside of the ParametricPlot3D and apply a fixed value of t (either manually or using e.g. With) - if it doesn't evaluate to a list of numbers then you need to fix that.

• Thanks this is what I was looking for. Could you explain what you mean by as "well as trying to feed slots that weren't in the list, as they are subelements of the list instead" – AzJ Aug 1 '18 at 20:16
• @AzJ, I have added an explanation – SPPearce Aug 2 '18 at 8:36