2
$\begingroup$

I am fitting data using a system of coupled differential equations and have defined a model function like so:

Clear[a, b, c, d, e, f, fit];

fit[a_?NumberQ,b_?NumberQ,c_?NumberQ,d_?NumberQ,e_?NumberQ,f_?NumberQ] :=
(fit[a, b, c, d, e, f] = NDSolve[{
   x'[t] == a - b*x[t] + c*(y[t] - x[t]),
   y'[t] == d - e*y[t] + f*(x[t] - y[t]),
   x[0] == 0,y[0] == 0},{x, y},{t, 0, 100}] // First // Values)

It works just fine when I plug in parameter values just to check out some plots:

Plot[{fit[1, 0.5, 0.5, 0.8, 0.5, 0.5][[1]][t],fit[1, 0.5, 0.5, 0.8, 0.5, 0.5][[2]][t]},
{t, 0, 15}, PlotStyle -> {{Dashed, Black}, Red}]

enter image description here

However, I want to reference the x and y fits separately, without specifying parameter values, like so:

fit[a,b,c,d,e,f][[1]][t]
(* Interpolating Function[...][t] *)

instead what that gets me is:

fit[a,b,c,d,e,f][[1]][t]
(* a[t] *)

I want to do this because I want to use a KroneckerDelta to make a combined fit that I can pass into NonlinearModel fit like in this solution: https://mathematica.stackexchange.com/a/15913/52355 because as is my work around is I have two functions:

fitX[a_?NumberQ,b_?NumberQ,c_?NumberQ,d_?NumberQ,e_?NumberQ,f_?NumberQ] :=
(fitX[a, b, c, d, e, f] = {x}/.NDSolve[{
   x'[t] == a - b*x[t] + c*(y[t] - x[t]),
   y'[t] == d - e*y[t] + f*(x[t] - y[t]),
   x[0] == 0,y[0] == 0},{x, y},{t, 0, 100}] // First)

fitY[a_?NumberQ,b_?NumberQ,c_?NumberQ,d_?NumberQ,e_?NumberQ,f_?NumberQ] :=
(fitY[a, b, c, d, e, f] = {y}/.NDSolve[{
   x'[t] == a - b*x[t] + c*(y[t] - x[t]),
   y'[t] == d - e*y[t] + f*(x[t] - y[t]),
   x[0] == 0,y[0] == 0},{x, y},{t, 0, 100}] // First)

that I pass in separately and essentially fit the curves to the data one at a time, but I would prefer to fit the both curves to the data at once. Is there a way that I could rewrite the original fit function so that I can recover the interpolating function without first passing in parameter values, or is that just not possible?

When I tried searching up this problem, I found this post: ParametricNDSolve not returning an interpolating function after specifying parameter vlaue which doesn't seem to be quite the problem I am having.

$\endgroup$
2
  • 3
    $\begingroup$ For fit[a,b,c,d,e,f][[1]][t], WRI introduced Indexed[fit[a,b,c,d,e,f],1][t], which delays taking Part 1 until fit[..] evaluates to a List. Does that help? -- You might be better off using ParametricNDSolve[] though. $\endgroup$
    – Michael E2
    Commented Jun 9, 2022 at 18:30
  • $\begingroup$ @MichaelE2 Wow, thank you so much, I had no idea I could use Indexed[] in this way. It worked perfectly! I actually originally wrote this code using ParametricNDSolve, the actual system is x, y, and z, and for some reason the z curve was not behaving as expected - the results from NDSolve and ParametricNDSolve were different, though the x and y curves were exactly the same. I couldn't figure it out for the life of me, and stuck with NDSolve because of it. But Indexed[] works like a charm, so I will be using that! Thank you! $\endgroup$
    – Illari
    Commented Jun 10, 2022 at 2:47

0

Your Answer

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