I need to solve a system of first order differential equations that look like

$$ f_1'(t)=F_1(f_1(t),...,f_n(t),g(f_1(t),...,f_n(t))),\\ .\\ .\\ .\\ f_n'(t)=F_n(f_1(t),...,f_n(t),g(f_1(t),...,f_n(t))). $$

I can of course code this easily within NDSolve with equations of the type

fi[t] == Fi[ f1[t] ,... , fn[t] , g[ f1[t] ,... , fn[t] ] ]

The problem is that, I assume, Mathematica evaluates the function $g$ in each of the $n$ equations, which is not ideal as $g$ and the $f_i$ functions can be quite expensive.

Of course, the naive solution is to simply add an additional algebraic equation to NDSolve,

G[t] == g[ f1[t] ,... , fn[t] ] 

and then change the other equations to

fi[t] == Fi[ f1[t] ,... , fn[t] , G[t] ]

But this is then much much slower to solve as NDSolve uses a DAE solver.

Is there any "elegant way" to evaluate auxiliary variables (like $g$ in my example) within each step of NDSolve to then use them in the equations? This is very easy to implement on "traditional" languages but I haven't been able to do so with Mathematica. Thanks!

EDIT: To give one example, the simplest case would be:

-l[t]r'[t] == vtr[t, r[t], l[t], eta[ t,r[t],l[t] ] ],
l'[t] == vtl[t, r[t], l[t], eta[ t,r[t],l[t] ] ],
r[t0] == r0, l[t0] = l0 },

where vtr, vtl, and eta are previously defined functions, and r0, l0, r0, and tf are some chosen parameters of course.

I guess a workaround would be to define an additional differential equation

Z'[t] == eta[t, r[t], l[t] ]

and then replace the eta functions by Z'[t] and give Z[t] the correct initial conditions. But if feels a bit stupid to solve an additional unnecessary differential equation.

  • $\begingroup$ It depends on how you define "elegant". Techniques in e.g. this or this can be used, but they (esp. the latter one) are somewhat advanced. Also, it's worth pointing out that, using these techniques doesn't necessarily speed up your code, because the ODE solver will be influenced. (See discussions in e.g. this and this. ) Can you add a specific example so we can play with it? $\endgroup$
    – xzczd
    Jul 21, 2023 at 2:21
  • 2
    $\begingroup$ Have you tried memoizing g? $\endgroup$
    – Michael E2
    Jul 21, 2023 at 3:19
  • $\begingroup$ Thanks, I will try those techniques. Vectorize sounds like the obvious solution. $\endgroup$ Jul 21, 2023 at 14:19


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.