Often, curve fitting is very sensitive to starting values of parameters. It would be great, if I could to find such starting values of parameters "by hand" using Manipulate.
So, I plot in Manipulate my experimental data points and theoretical curve. I can change the shape of this curve by changing all parameters in manipulate in such way that they approximate my experimental data relatively well. Now I would like to run fitting using current parameters in Manipulate as starting values. Finally I would like to insert the parameters found by fitting back into Manipulate.
Here is example code for simple function. My data is more complex.
data = Table[{x, 8 x^3 - 7 x^2 - 10 x + 1 + RandomReal[{-5, 5}]}, {x, -2, 2, 0.1}];
Manipulate[
Show[
Plot[a x^3 + b x^2 + c x + d, {x, -2, 2}],
ListPlot[data]
],
{a, -10, 10},
{b, -10, 10},
{c, -10, 10},
{d, -10, 10}
]
Answer
As I understand the question a curve fitting procedure that has the following properties is sought:
- Manually adjust the parameters to get an approximate fit.
- Use these parameters as the starting values for
FindFit
. - Propagate the solution from
FindFit
back to theManipulate
parameters. - Subsequently enable further editing of the
Manipulate
parameters and repeat the cycle.
The following code satisfies this criteria by wrapping Manipulate
inside a DynamicModule
and the use of a Button
to indicate when FindFit
should be run.
data = Table[{x, 8 x^3 - 7 x^2 - 10 x + 1 + RandomReal[{-5, 5}]}, {x, -2, 2, 0.1}];
DynamicModule[
{
sol
},
Manipulate[
If[computeFlag == True,
sol = FindFit[data,
aa x^3 + bb x^2 + cc x +
dd, {{aa, a}, {bb, b}, {cc, c}, {dd, d}}, x];
{a, b, c, d} = {aa, bb, cc, dd} /. sol;
computeFlag = False;
];
Column[{
Dynamic[
Button["Compute",
computeFlag = True
]
],
Show[
Plot[a x^3 + b x^2 + c x + d, {x, -2, 2},
PlotStyle -> Black],
ListPlot[data, PlotStyle -> Red],
ImageSize -> 300,
PlotRange -> {{-2.05, 2.05}, All}
]
}],
(*Manipulate variables*)
{{computeFlag, False}, ControlType -> None},
{{a, 1}, -10, 10, Appearance -> "Open"},
{{b, 1}, -10, 10, Appearance -> "Open"},
{{c, 1}, -10, 10, Appearance -> "Open"},
{{d, 1}, -10, 10, Appearance -> "Open"}
] (* end of Manipulate *)
] (* end of DynamicModule *)
Below is a figure where the parameters have been manually adjusted.
After clicking the Compute button FindFit
propagates the solution back to the Manipulate
parameters.
The user is free to re-edit the Manipulate
parameters and repeat the cycle.
Comments
Post a Comment