# FindFit not giving a good fit despite good initial parameters

I'm having a problem with FindFit not giving a good fit to my data, even though the initial parameters I give look really good when plotted. The fitting function is

P1[Ω_, Δ_, t_] :=
((Ω/Sqrt[Ω^2 + Δ^2])*Sin[(1/2)*Sqrt[Ω^2 + Δ^2]*t])^2;

fitfunction[Ω_, Δ_, t_, a_, b_, c_] :=
a + b*P1[Ω, Δ + c, t];


and I give the approximate starting parameters:

centrepeak = -91;
Ωapprox = 2 π 29 10^3;
amplitude = 0.8;
offset = 0.13;
pulsetime = 16 10^-6;


Then I fit using FindFit:

rabifit =
FindFit[scandata,
{fitfunction[Ω, Δ, pulsetime, voffset, amp, hoffset],
amp < 1, amp > 0, voffset > 0, voffset < 0.5 },
{{Ω, Ωapprox}, {amp, amplitude}, {voffset, offset}, {hoffset, centrepeak}}, Δ]


which gives

{Ω -> 187398., amp -> 0.216895, voffset -> 0.136962, hoffset -> 93.5922}


If I plot the fitting function with my starting parameters (red line) and the fitted parameters (orange line) against the data I get the following graph:

As it can be seen the initial parameters seem to give a much better fit than the fitted ones. I've tried various things, e.g., changing the fitting method, but nothing seems to work. Any suggestions for anything else I could try?

The code for generating the plot is

Show[Plot[{
fitfunction[Ωapprox, 2 π Δ 10^3, pulsetime, offset, amplitude, 2 π centrepeak 10^3],
fitfunction[Ω, 2 π Δ 10^3, pulsetime, voffset, amp, 2 π hoffset 10^3] /. rabifit},
{Δ, 0, 200},
PlotRange -> {All, {0, 1}},
PlotStyle -> {Directive[Thick, Red], Directive[Thick, Orange]},
Frame -> True, FrameStyle -> 30,
FrameLabel -> {"Frequency (kHz)", "Probability in |1>"},
ImageSize -> 30*30],
ListPlot[scandata, PlotStyle -> PointSize[0.007]]]

• Please give the full code for generating the plot. You should use NonlinearModelFit instead of FindFit, since its output is much more convenient... – grbl Dec 10 '13 at 10:16
• It would be helpful if you submitted at least the data that you're fitting. Also, what version of Mathematica are you using? – au700 Dec 10 '13 at 11:20
• Thanks, I've updated the post with the code for generating the plot. The data can be found via the link in the first sentence, I can provide more if necessary. I'm using Mathematica 7.0. – Joe Dec 10 '13 at 13:51

The problem is that when you plot your function, you are applying scaling factors that you are not passing to FindFit. For example, you pass a starting guess of centrepeak of -91 when it should be -2 π 91 10^3. Try this

scandata = Import["peakdata.csv"];
scandata = Map[{#[[1]], N[ToExpression[#[[2]]]]} &, scandata];

fitfunction[Ω_, Δ_, t_, a_, b_, c_] :=
a + b*P1[Ω, Δ + c, t];

P1[Ω_, Δ_, t_] := ((Ω/Sqrt[Ω^2 + Δ^2])*Sin[(1/2)*Sqrt[Ω^2 + Δ^2]*t])^2.;

Ωapprox = 2 π 29 10^3;
centrepeak = -2 π 91 10^3;
amplitude = 0.8;
offset = 0.13;
pulsetime = 16 10^-6;

rabifit =
FindFit[scandata,
{fitfunction[Ω, 2 π Δ 10^3, pulsetime, voffset, amp, hoffset],
amp < 1, amp > 0, voffset > 0, voffset < 0.5},
{{Ω, Ωapprox}, {amp, amplitude}, {voffset, offset}, {hoffset, centrepeak}},
Δ, MaxIterations -> 1000]

Show[Plot[{
fitfunction[Ωapprox, 2 π Δ 10^3, pulsetime, offset, amplitude, centrepeak ],
fitfunction[Ω, 2 π Δ 10^3, pulsetime, voffset, amp, hoffset ] /. rabifit},
{Δ, 0, 200}, PlotRange -> {All, {0, 1}},
PlotStyle -> {Directive[Thick, Red], Directive[Thick, Orange]},
Frame -> True, FrameStyle -> 30,
FrameLabel -> {"Frequency (kHz)", "Probability in |1>"},
ImageSize -> 30*30],
ListPlot[scandata, PlotStyle -> PointSize[0.007]]]


• @ssch - You edited my post so that, for example, [CapitalOmega] was replaced by an actual capital omega. This is very nice so thank you. How did you do it please? – WalkingRandomly Dec 10 '13 at 14:49
• Using this userscript: Additional useful buttons for our M.SE editor – ssch Dec 10 '13 at 14:50
• @WalkingRandomly - thanks a lot! Should have spotted that myself... – Joe Dec 10 '13 at 16:36