# Troubles with FindFit for ODE

I need to use FindFit for ODE with arbitary number of parameters. This code (from documentation) works:

sol = First[
x /. NDSolve[{x''[t] + .33 x'[t] + .72 x[t]^3 == 0, x[0] == 2, x'[0] == 0}, x, {t, 20}]];
times = N[Range[0, 100]/5];
data = Transpose[{times, sol[times] + RandomReal[.1, 101]}];
lp= ListPlot[data, PlotRange -> All];
model[γ_?NumberQ, a_?NumberQ,
b_?NumberQ] := (model[γ, a, b] =
First[x /.  NDSolve[{x''[t] + γ x'[t] + a x[t] + b x[t]^3 == 0,
x[0] == 2, x'[0] == 0}, x, {t, 20}]]);
fit = FindFit[data, model[γ, a, b][x], {{γ, .1}, {a, .1}, {b, 1}}, x,
PrecisionGoal -> 4, AccuracyGoal -> 4];
{Show[Plot[model[γ, a, b][x] /. fit, {x, 0, 20},  PlotStyle -> Orange], lp],
ListPlot[Transpose[{times, data[[All, 2]] - (model[γ, a, b][times] /. fit)}]]}


But I need to place all my parameters into a list:

params = {γ, a, b};
model[params] := (model[params] =
First[x /.  NDSolve[{x''[t] + γ x'[t] + a x[t] + b x[t]^3 == 0,
x[0] == 2, x'[0] == 0}, x, {t, 20}]]);
fit = FindFit[data, model[params][x], params, x, PrecisionGoal -> 4, AccuracyGoal -> 4]


And this piece of code throws an FindFit::nrlnum error.

What should I do to use the list of parameters as the FindFit argument?

Thank a lot for your help!

• Do you know that there will always be three parameters? It looks like it, since they go into specific places in the NDSolve. Why do you need them in a list? If there are more parameters, how will that change the equation you solve with NDSolve? Nov 16 '14 at 18:45
• This code (from documentation) works The code does not work. screen shot: !Mathematica graphics you might be missing some additional code. Please post complete working code. Nov 16 '14 at 18:46
• Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Read the faq! 3) 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! Nov 16 '14 at 20:04
• @Nasser Right, i have fixed Nov 17 '14 at 9:06

Easier by using ParametricNDSolve[]:

params = {γ, a, b};
model = x /. ParametricNDSolve[{x''[t] + γ x'[t] + a x[t] + b x[t]^3 == 0, x[0] == 2, x'[0] == 0},
x, {t, 0, 20}, params];
fit = FindFit[data, model[Sequence @@ params][x], params, x, PrecisionGoal -> 4, AccuracyGoal -> 4]

(* {γ -> 0.339787, a -> 0.0385222, b -> 0.707646} *)

Plot[model[Sequence @@ params][t] /. fit, {t, 0, 20},  Epilog -> {Point@data}]


• But wouldn't the definition of model need to change if the params are not {γ, a, b} anymore? You explicitly refer to those symbols in the equation to be solved by ParametricNDSolve... Nov 16 '14 at 19:14
• @MariusLadegårdMeyer You need to write an ODE to be able to solve it. If that ODE has some parameters, the parameters must be written down in the equation. The "generality" stops there, when you are bound to write a particular equation. Nov 16 '14 at 19:20
• I agree. So the main points here are a) that ParametricNDSolve is nice, and b) passing the params to the model with Sequence @@ params, right? =) Nov 16 '14 at 19:25
• @MariusLadegårdMeyer Yep, that's it. No magic. Nov 16 '14 at 19:27
• Nevertheless is it possible to define the same model with NDSolve[]? Within my problem ParametricNDSolve[] model fitting takes much more time then NDSolve model with hardcoded sequence of parameters. Nov 30 '14 at 21:03