2
$\begingroup$

I am trying to fit sinusoids to my experimental data of the form: $y= a+b sin(\theta)+csin(2\theta)+dsin(4\theta)$ and I am using the non-linear fit model. However I feel the data fitting is not good, how can I iteratively improve my fit? Here is my code

Position50K ={2.29398, 16.4984, 31.471, 45.8031, 57.4666, 69.7218, 81.0981, \
92.5701, 106.796, 121.909, 136.564, 149.898, 160.087, 172.138, \
185.383, 196.216, 209.591, 221.267, 231.311, 244.509, 258.118, \
273.437, 287.129, 298.899, 310.201, 323.688, 335.386, 348.173, \
361.205, 365.005};
Torque50K ={6.19*10^-8, 5.46*10^-8, 5.24*10^-8, 4.69*10^-8, 4.49*10^-8, 
 4.37*10^-8, 4.41*10^-8, 4.52*10^-8, 4.76*10^-8, 5.08*10^-8, 
 5.37*10^-8, 5.78*10^-8, 6.24*10^-8, 6.55*10^-8, 7.04*10^-8, 
 7.32*10^-8, 7.59*10^-8, 7.76*10^-8, 7.94*10^-8, 8.13*10^-8, 
 8.32*10^-8, 8.13*10^-8, 8.16*10^-8, 8.06*10^-8, 7.89*10^-8, 
 7.63*10^-8, 7.4*10^-8, 7.04*10^-8, 6.66*10^-8, 6.76*10^-8};
Torquedata50K = Transpose@{Position50K, Torque50K};
nlm = NonlinearModelFit[Torquedata50K, 
  a + b*Sin[x*\[Pi]/180] + c*Sin[x*\[Pi]/90] + 
   d*Sin[4 x*\[Pi]/180], {a, b, c, d}, x] (*x is in degrees*)
nlm["BestFitParameters"];
Show[ListPlot[Torquedata50K, PlotStyle -> Black], 
 Plot[nlm[x], {x, 0, 365}, PlotStyle -> Red]]

enter image description here Now basically, I want to subtract the constant term and $sin(\theta)$ term from my raw data so that I can get the $sin(2\theta)$ and $sin(4\theta)$ variation. So I did this in code

BaseTorque[x_] := 
  6.495726466567145`*^-8 - 1.9304374060084893`*^-8 Sin[(\[Pi] x)/180]; (*what I obtained from fitting*)
Torque50Knew = Torque50K - BaseTorque /@ Position50K;
Torque50KnewData = Transpose@{Position50K, Torque50Knew};
Show[ListPlot[Torque50KnewData, PlotStyle -> Black], 
 Plot[test[x], {x, 0, 365}, PlotStyle -> Red]]

enter image description here

You can clearly see neither my subtracted data, nor the fits look good. What can I do to improve my fitting?

$\endgroup$
  • 3
    $\begingroup$ You need to add a set of phase parameters: p1, p2, and p3 as in nlm = NonlinearModelFit[Torquedata50K, a + b*Sin[x*\[Pi]/180 + p1] + c*Sin[x*\[Pi]/90 + p2] + d*Sin[4 x*\[Pi]/180 + p3], {a, b, c, d, {p1, 0}, {p2, 0}, {p3, 0}}, x] . $\endgroup$ – JimB Oct 10 at 23:44
  • $\begingroup$ Maybe try Fourier or FourierDST? $\endgroup$ – Silvia yesterday
5
$\begingroup$

Others might have a much better way, but wanted to look into the residuals and found that fitting two sines one after the other does actually a pretty good job. Also, I scaled your values up by 10^8 just to be sure there are no numerical issues. I'll just leave the code here and see for yourself how many of the parameters you need.

pts = {2.29398, 16.4984, 31.471, 45.8031, 57.4666, 69.7218, 81.0981, 
   92.5701, 106.796, 121.909, 136.564, 149.898, 160.087, 172.138, 
   185.383, 196.216, 209.591, 221.267, 231.311, 244.509, 258.118, 
   273.437, 287.129, 298.899, 310.201, 323.688, 335.386, 348.173, 
   361.205, 365.005};
vals = 10^8*{6.19*10^-8, 5.46*10^-8, 5.24*10^-8, 4.69*10^-8, 
    4.49*10^-8, 4.37*10^-8, 4.41*10^-8, 4.52*10^-8, 4.76*10^-8, 
    5.08*10^-8, 5.37*10^-8, 5.78*10^-8, 6.24*10^-8, 6.55*10^-8, 
    7.04*10^-8, 7.32*10^-8, 7.59*10^-8, 7.76*10^-8, 7.94*10^-8, 
    8.13*10^-8, 8.32*10^-8, 8.13*10^-8, 8.16*10^-8, 8.06*10^-8, 
    7.89*10^-8, 7.63*10^-8, 7.4*10^-8, 7.04*10^-8, 6.66*10^-8, 
    6.76*10^-8};

model = NonlinearModelFit[
  Transpose[{pts, vals}],
  a1*Sin[b1*t + c1] + d1,
  {a1, b1, c1, d1},
  t,
  Method -> "NMinimize"]

Mathematica graphics

This gives a similar result than your first plot. Looking at the residuals shows that there is a second sine hidden. So let's fit another model

residual1 = vals - model /@ pts;

model2 = NonlinearModelFit[
  Transpose[{pts, residual1}],
  a2*Sin[b2*t + c2] + d2,
  {a2, b2, c2, d2},
  t,
  Method -> "NMinimize"
  ]

img

And the final fit looks quite nice

Show[{
  ListPlot[Transpose[{pts, vals}]],
  Plot[model[t] + model2[t], {t, 0, 365}]
  }]

img

The residual that is left doesn't really look like it's up for another sine fit

Mathematica graphics

$\endgroup$
  • 2
    $\begingroup$ +1 Very nice. If one lives by the use of "AICc", then model["AICc"], model2["AICc"], and model3["AICc"] (where model3 is the model with all 3 terms) results in -19.923, -16.5801, and -11.1587. That suggests that the model with just a single term is far better than the other two models with the model with all 3 terms being the worst of the bunch. (Smaller values of AICc are better.) $\endgroup$ – JimB Oct 11 at 1:41
  • $\begingroup$ And to be specific model3 is the OP's model where the frequencies for all 3 terms are known. If one allows those to vary, then the $AIC_c$ value is even lower (1.63709) for that model with 3 terms. $\endgroup$ – JimB Oct 11 at 1:57
  • $\begingroup$ Thanks a lot, maybe my physical experimental data is garbage then, because after baseline sinusoid subtraction, I should still be able to retrieve a sin(2x) and a small sin(4x) variation. $\endgroup$ – Indeterminate Oct 11 at 2:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.