# Better curve fitting of sinusoids

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


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


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

• 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] . – JimB Oct 10 at 23:44
• Maybe try Fourier or FourierDST? – Silvia yesterday

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


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


And the final fit looks quite nice

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


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

• +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.) – JimB Oct 11 at 1:41
• 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. – JimB Oct 11 at 1:57
• 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. – Indeterminate Oct 11 at 2:25