5

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:

Plot of data and fitting function for the initial parameters (red) and the fitted parameters (orange)

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]]]
Svend Tveskæg
  • 425
  • 5
  • 14
Joe
  • 53
  • 5
  • 1
    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

1 Answers1

5

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]]]

enter image description here

ssch
  • 16,590
  • 2
  • 53
  • 88
WalkingRandomly
  • 4,107
  • 1
  • 20
  • 36