5
$\begingroup$

I am using Mathematica's FindFit function to fit a parametric solution to my data and I am getting the error

FindFit::nrnum: The function value [complicated expression] is not a real number at {ka,kd,beta} = {0.7,0.1,0.1}

he initial guesses of the parameters {ka=0.7,kd=0.1,beta=0.1} are very close to the values I used to mock up the data, and I can't figure out where I am going wrong. I posted a similar version of this question on stack exchange but didn't get any response.

First I use the ParametricNDSolveValue function to parametrically solve two coupled first order differential equations for the functions 'a[t]' and 'b[t]' with parameters ka, kd, and beta:

sol = ParametricNDSolveValue[{D[a[t], t] == -kd*a[t] + ka*(1 - a[t] - b[t]), a[0] == ka/(ka + kd), 
  D[b[t], t] == -kd*b[t] + ka*(1 - Exp[-beta*t]) (1 - a[t] - b[t]), b[0] == 0 }, {a, b}, 
  {t, 0, 20}, {ka, kd, beta}]

I can extract the solution for a[t] for ka=0.7, kd=0.1, beta=0.1 by using:

y1 = sol[0.7, 0.1, 0.1][[1]]

Plotting y1 as a function of t gives the expected curve:

Plot[y1[t], {t, 0, 20}, PlotRange -> All]

Then I create a data table eyeballing the values from the above plot:

dataA = {{0, 0.87}, {5, 0.84}, {10, 0.75}, {15, 0.68}, {20, 0.62}}

Finally to test FindFit, I use FindFit with sol[ka, kd, beta][[1]][t] to fit the data giving the same initial values for ka, kd, and beta that I used to generate the above data:

fit = FindFit[dataA, sol[ka, kd, beta][[1]][t], {{ka, 0.7}, {kd, 0.1}, {beta, 0.1}}, t]

At which point I get the error:

FindFit::nrnum: "The function value 1/2\ ((-0.87+Abs[0.7[0.]])^2+(-0.84+Abs[0.7[5.]])^2+(-0.75+Abs[0.7[10.]])^2+(-0.68+Abs[0.7[15.]])^2+(-0.62+Abs[0.7[20.]])^2) is not a real number at {ka,kd,beta} = {0.7,0.1,0.1}."

I tried using Abs[sol[ka, kd, beta][[1]][t]] in FindFit, that didn't work. Then I tried adding constraints:

fit = FindFit[dataA, {Abs[sol[ka, kd, beta][[1]][t]], {ka > 0, kd > 0, 
  beta > 0}}, {{ka, 0.7}, {kd, 0.1}, {beta, 0.1}}, t]

And that failed too.

Any clues what is wrong with my code? Thanks a lot!

$\endgroup$
2
  • $\begingroup$ Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. $\endgroup$ Commented Feb 3, 2015 at 17:42
  • $\begingroup$ Take a close look at your error output message. Your variable substitution is problematic and you end up with terms like Abs[0.7[5.]] repeatedly. 0.7 is not a function and cannot be addressed as such. $\endgroup$ Commented Feb 3, 2015 at 20:00

2 Answers 2

2
$\begingroup$
sol = ParametricNDSolve[{D[a[t], t] == -kd*a[t] + ka*(1 - a[t] - b[t]), a[0] == ka/(ka + kd), 
                        D[b[t], t] == -kd*b[t] + ka*(1 - Exp[-beta*t]) (1 - a[t] - b[t]), 
                        b[0] == 0}, {a, b}, {t, 0, 20}, {ka, kd, beta}];

dataA = {{0, 0.87}, {5, 0.84}, {10, 0.75}, {15, 0.68}, {20, 0.62}};

fit = FindFit[dataA, a[ka, kd, beta][t] /. sol, {{ka, 0.7}, {kd, 0.1}, {beta, 0.1}}, t]

 (* {ka -> 0.932926, kd -> 0.136649, beta -> 0.0603393} *)

Plot[{a[.7, .1, .1][t] /. sol, a[ka, kd, beta][t] /. fit /. sol}, {t, 0, 20}, PlotRange -> All]

Mathematica graphics

$\endgroup$
4
  • $\begingroup$ +1 But could you explain why the result of 'ParametricNDSolveValue' isn't working here? $\endgroup$ Commented Feb 3, 2015 at 20:34
  • $\begingroup$ @Matariki I haven't tried it :) $\endgroup$ Commented Feb 3, 2015 at 20:44
  • $\begingroup$ @belisarius Thanks a lot, this worked! I think my syntax of finding "the solution for a[t]" from ParametricNDSolveValue is incorrect, i.e. it is incorrect to use sol[ka, kd, beta][[1]][t] in FindFit, but I don't know why. Also, an excellent post by @Oleksandr R. on the question of simultaneously fitting multiple datasets with a parametric solution of coupled differential equations can be found here: link $\endgroup$ Commented Feb 3, 2015 at 21:13
  • $\begingroup$ @Sam Glad to hear it helped $\endgroup$ Commented Feb 3, 2015 at 21:15
2
$\begingroup$

The problem is that sol[ka, kd, beta][[1]][t] evaluates to ka[t] before numeric values are substituted for the parameters. You need to prevent evaluation of [[1]] until after sol has evaluated to a list of solutions.

Thanks to Mr.Wizard for pointing out Indexed, which will do what we're after.

fit = FindFit[dataA, Indexed[sol[ka, kd, beta], 1][t], {{ka, 0.7}, {kd, 0.1}, {beta, 0.1}}, t]
(*  {ka -> 0.932928, kd -> 0.136649, beta -> 0.0603392}  *)

In pre-V10, something like this will work (original answer):

firstIfList[l_List] := First[l]

fit = FindFit[dataA, firstIfList[sol[ka, kd, beta]][t], {{ka, 0.7}, {kd, 0.1}, {beta, 0.1}}, t]
(*  {ka -> 0.932928, kd -> 0.136649, beta -> 0.0603392}  *)

See Prevent Part[] from trying to extract parts of symbolic expressions for a similar issue with Part.

$\endgroup$
5
  • $\begingroup$ Indexed[sol[ka, kd, beta], 1][t] also works. $\endgroup$ Commented Feb 4, 2015 at 11:43
  • $\begingroup$ @Mr.Wizard Thanks! I knew there was something new that solved this problem, but I forgot the name. $\endgroup$ Commented Feb 4, 2015 at 11:44
  • $\begingroup$ It's in this answer in the Q&A you linked, if you'd like to vote for it. ;^) $\endgroup$ Commented Feb 4, 2015 at 11:45
  • 1
    $\begingroup$ @Mr.Wizard Oops! I didn't read far enough. +1. :) $\endgroup$ Commented Feb 4, 2015 at 11:46
  • $\begingroup$ Thanks everybody for answering my questions! Good to know about Indexed! $\endgroup$ Commented Feb 4, 2015 at 18:30

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.