# ParametricNDSolve: Parameter inside UnitStep leads to longer integration times

I have found one of the most annoying issues in ParametricNDSolve. When a parameters occurs inside UnitStep (and Piecewise and If) the integration takes much longer time. I illustrate this by an easy example

First, create two identical systems with an infusion running for 100 time units. In the first system we set the value of the infusion time and in the second system this parameter value will be set later on to the same value.

sys1 = {x'[t] == RATE*UnitStep[100 - t], x[0] == 0};
sys2 = {x'[t] == RATE*UnitStep[tInf - t], x[0] == 0};
vars = {x};


Create two ParametricNDSolve objects:

p1 = First@
ParametricNDSolve[sys1, vars, {t, 0, 200}, {RATE},
Method -> {"ParametricSensitivity" -> None,
"ParametricCaching" -> None}];
p2 = First@
ParametricNDSolve[sys2, vars, {t, 0, 200}, {RATE, tInf},
Method -> {"ParametricSensitivity" -> None,
"ParametricCaching" -> None}];


Now we crete a large set of of random parameter values for the parameter RATE.

runs = 10000;
rvs = RandomReal[{0, 1}, runs];


Solve the first system (with only one parameter) a large number of times and take the time.

AbsoluteTiming[Do[x[rvs[[i]]] /. p1, {i, runs}]]

{1.546088, Null}


Solve the second system, with parameters RATE and tInf where tInf=100, a large number of times and take the time.

AbsoluteTiming[Do[x[rvs[[i]], 100] /. p2, {i, runs}]]

{9.052518, Null}


The second systems take approximately 6x longer to solve. What is going on here? There might be a large issue here with the ParametricNDSolve environment.

-
I'm not so sure whether this is not the contrary of a problem but a good example of why ParametericNDSolve is useful: the time to run just NDSolve for every value of RATE is about the same as that for the two-parameter case. The one-parameter case is much faster and that might well be because ParametericNDSolve can do an optimization for that case that it can't do for the (highly nonlinear) case where the parameter is in the UnitStep. Of course, I'm just guessing... –  Albert Retey Jan 21 at 22:06
When you call NDSolve on the problem it will do processing of the equations every time, which is not done in ParametricNDSolve. To get a better comparison between NDSolve and ParametricNDSolve one should use use NDSolveProcessEquations together with NDSolveReinitiliaze and NDSolveIterate. I think that if you try that you will see that NDSolve is not as slow as you said. But I will try that later today. –  jaclea Jan 22 at 6:27
Of course my comparison is somewhat oversimplified -- but there is certainly also some overhead in what ParametricNDSolve does/tries to do. While it might be well justified to claim that there is still potential for further optimization of ParametricNDSolve, I find the claim "there is a large issue" with it a little overdrawn -- after all you give no indication that it does something wrong and it isn't (much) slower than a naive approach. And I find it makes perfect sense that the case with a parameter in UnitStep is much more difficult/expensive than the almost trival one... –  Albert Retey Jan 22 at 9:30
One more comment: in my opinion there actually is a problem with ParametricNDSolve: there is only very vague documentation about what it does internally ("Derivatives of ParametricFunction are computed using a combination of symbolic and numerical sensitivity methods when possible."). One can make some guesses from the method options and examples but it's really difficult to make a reasonable guess about what kind of optimizations we can expect to be done and what the premises are for them. Maybe one day there will be another section in the advanced ndsolve docs... –  Albert Retey Jan 22 at 9:46
I totally agree with you. I have found other issues with ParametricNDSolve, see my other posts. I don't use the ParametricSensitivties at all. My overall problem is to solve a huge system of differential equations for a large set of parameter values. Since the Processing of equations (NDSolveProcessequations) takes a signifant portion of the time, I would like to only Process the equations once. I have tried is to use the parameters as states in the model and then use NDSolve`Processequation + Reinitialize to set new parameter values. However, the added states changes the RHS. –  jaclea Jan 22 at 12:11