# Does mathematica cache the interpolating function from ParametricNDSolve?

I want to evaluate the solution of a system of non-linear ODEs using ParametricNDSolve. The output of ParametricNDSolve is a ParametricFunction object. Let's call it $$f_\theta(t)$$, where $$\theta$$ is a list of all parameters used in ParametricNDSolve.

For a given choice of the parameters $$\hat\theta$$, the ParametricFunction becomes a InterpolatingFunction object. I want to evaluate this function at multiple points $$\{t_1,t_2,...,t_n\}$$, which is, obtaining the value $$f_{\hat\theta}(t_i)$$.

Does Mathematica fully solve the system of equations each time I call $$f_{\hat\theta}(t_i)$$ for a different $$i$$? Or does it cache the InterpolatingFunction after the first call (let's say, $$f_{\hat\theta}(t_1)$$) and uses it to obtain the value of $$f_{\hat\theta}$$ at $$t_2,...,t_n$$?

• It's in the docs: Search for "ParametricCaching" (short answer: by default, it caches and reuses the last solution for a given set of parameters) Jul 29 at 20:17
• Thanks @MichaelE2! If you post as a solution I'll be happy to accept it. If so, you should mention that the reference is in ParametricNDSolve/Options/Method/ParametricCaching. Jul 29 at 20:27
• I added a bit.... :) Jul 29 at 20:55
• Related: What are the valid options for the “ParametricCaching” option in ParametricNDSolve? You seem to have gotten a better answer than I did, though. :-) Jul 29 at 21:02
• @MichaelSeifert Missed that question -- sorry. Summer's been busy. Jul 29 at 21:53

To extend this Q&A beyond one that is "easily found in the documentation," where some basic facts about "ParametricCaching" are given, I'll add some undocumented suboptions to Method -> {"ParametricCaching" -> {Automatic, ...opts...}}:

sol = ParametricNDSolveValue[{x''[t] + a x[t] == 0, x == b,
x' == 0}, x, {t, 0, 1000}, {a, b}, MaxSteps -> ∞];
sol[[-1, -1, -3]]
(*
{"Cache" -> True, "CacheTableLength" -> 19, "CacheTableWidth" -> 7,
"CacheKeyMaxBytes" -> 1000000, "CacheResultMaxBytes" -> 1000000,
"KeyComparison" -> None, "ResultComparison" -> LessEqual}
*)


For instance, we can use the timings to verify when a cached solution is reused. This confirms that the "TableCache*" suboptions seem to set the dimensions of the cache table:

sol1 = ParametricNDSolveValue[{x''[t] + a x[t] == 0, x == b,
x' == 0}, x, {t, 0, 1000}, {a, b}, MaxSteps -> ∞,
Method -> {"ParametricCaching" -> {Automatic,
"CacheTableLength" -> 1, "CacheTableWidth" -> 1}}];
sol1[1, 1] // AbsoluteTiming
sol1[1, 1] // AbsoluteTiming
sol1[1, 2] // AbsoluteTiming
sol1[1, 1] // AbsoluteTiming
(*
{0.017357, 0.540302}
{0.000014, -0.416147}
{0.020204, -0.832294}
{0.01881, -0.416147}   <-- N.B. Recomputed
*)

sol2 = ParametricNDSolveValue[{x''[t] + a x[t] == 0, x == b,
x' == 0}, x, {t, 0, 1000}, {a, b}, MaxSteps -> ∞,
Method -> {"ParametricCaching" -> {Automatic,
"CacheTableLength" -> 1, "CacheTableWidth" -> 2}}];
sol2[1, 1] // AbsoluteTiming
sol2[1, 1] // AbsoluteTiming
sol2[1, 2] // AbsoluteTiming
sol2[1, 1] // AbsoluteTiming
(*
{0.019945, 0.540302}
{0.000017, -0.416147}
{0.01882, -0.832294}
{0.000022, -0.416147}  <-- N.B. Reused
*)


The memory-related options should be self-explanatory and useful. We can test "CacheResultMaxBytes" but I'm not sure how to test "CacheKeyMaxBytes".

(* bytes of a result *)
sol1[1, 1] // ByteCount
(*  305704  *)

sol3 = ParametricNDSolveValue[{x''[t] + a x[t] == 0, x == b,
x' == 0}, x, {t, 0, 1000}, {a, b}, MaxSteps -> ∞,
Method -> {"ParametricCaching" -> {Automatic,
"CacheResultMaxBytes" -> 400000}}];
sol3[1, 1] // AbsoluteTiming
sol3[1, 1] // AbsoluteTiming
(*
{0.015709, 0.540302}
{0.000013, -0.416147}  <-- N.B. Reused
*)

sol4 = ParametricNDSolveValue[{x''[t] + a x[t] == 0, x == b,
x' == 0}, x, {t, 0, 1000}, {a, b}, MaxSteps -> ∞,
Method -> {"ParametricCaching" -> {Automatic,
"CacheResultMaxBytes" -> 1000}}];
sol4[1, 1] // AbsoluteTiming
sol4[1, 1] // AbsoluteTiming
(*
{0.018927, 0.540302}
{0.022862, -0.416147}  <-- N.B. Recomputed
*)


I don't about keys and their function in ParametricNDSolve caching, nor how "ResultComparison" is used.

(Note it's important to rerun ParametricNDSolveValue each time you want to test to reset the cache table.)

• Thanks for the detailed answer! Jul 29 at 21:50