# Fit data with linear combinations of Cos and Sin

Recall that if $f$ is a piecewise continuous function on the interval $[-\pi, \pi]$, then the Fourier series of $f$ is

$$f(x) = \sum_{n=0}^{\infty} (a_n \cos(nx) + b_n \sin(nx)).$$

Suppose that I have the following discrete data stored in the List called list:

list = {{-6.28319,27.},
{-6.18319,29.9378},
{-6.08319,31.4545},
{-5.98319,31.4815},
{-5.88319,30.054},
{-5.78319,27.3079},
{-5.68319,23.4676},
{-5.58319,18.8269},
{-5.48319,13.7254},
{-5.38319,8.52035},
{-5.28319,3.5588},
{-5.18319,-0.849714},
{-5.08319,-4.45626},
{-4.98319,-7.09014},
{-4.88319,-8.66947},
{-4.78319,-9.20395},
{-4.68319,-8.78975},
{-4.58319,-7.59713},
{-4.48319,-5.85203},
{-4.38319,-3.81336},
{-4.28319,-1.7481},
{-4.18319,0.0934504},
{-4.08319,1.5002},
{-3.98319,2.31839},
{-3.88319,2.46391},
{-3.78319,1.92767},
{-3.68319,0.77379},
{-3.58319,-0.86928},
{-3.48319,-2.82358},
{-3.38319,-4.88107},
{-3.28319,-6.82563},
{-3.18319,-8.45569},
{-3.08319,-9.60509},
{-2.98319,-10.1604},
{-2.88319,-10.0728},
{-2.78319,-9.36378},
{-2.68319,-8.12337},
{-2.58319,-6.50193},
{-2.48319,-4.69555},
{-2.38319,-2.92666},
{-2.28319,-1.42171},
{-2.18319,-0.387886},
{-2.08319,0.00884309},
{-1.98319,-0.337699},
{-1.88319,-1.46055},
{-1.78319,-3.31281},
{-1.68319,-5.76826},
{-1.58319,-8.62934},
{-1.48319,-11.6421},
{-1.38319,-14.5166},
{-1.28319,-16.9518},
{-1.18319,-18.6617},
{-1.08319,-19.401},
{-0.983185,-18.9886},
{-0.883185,-17.3258},
{-0.783185,-14.4076},
{-0.683185,-10.327},
{-0.583185,-5.27092},
{-0.483185,0.492234},
{-0.383185,6.63133},
{-0.283185,12.7772},
{-0.183185,18.5507},
{-0.0831853,23.5918},
{0.0168147,27.5873},
{0.116815,30.2954},
{0.216815,31.5636},
{0.316815,31.3407},
{0.416815,29.6794},
{0.516815,26.7315},
{0.616815,22.7344},
{0.716815,17.9917},
{0.816815,12.8477},
{0.916815,7.66002},
{1.01681,2.7712},
{1.11681,-1.51793},
{1.21681,-4.97054},
{1.31681,-7.43032},
{1.41681,-8.83083},
{1.51681,-9.19685},
{1.61681,-8.63808},
{1.71681,-7.33557},
{1.81681,-5.52246},
{1.91681,-3.4608},
{2.01681,-1.41646},
{2.11681,0.365385},
{2.21681,1.68215},
{2.31681,2.3911},
{2.41681,2.42056},
{2.51681,1.77408},
{2.61681,0.527401},
{2.71681,-1.18153},
{2.81681,-3.16824},
{2.91681,-5.22173},
{3.01681,-7.12679},
{3.11681,-8.6864},
{3.21681,-9.74219},
{3.31681,-10.1909},
{3.41681,-9.99543},
{3.51681,-9.18896},
{3.61681,-7.87251},
{3.71681,-6.20529},
{3.81681,-4.38926},
{3.91681,-2.64914},
{4.01681,-1.20978},
{4.11681,-0.272896},
{4.21681,0.00442148},
{4.31681,-0.472474},
{4.41681,-1.72346},
{4.51681,-3.68806},
{4.61681,-6.22729},
{4.71681,-9.13288},
{4.81681,-12.1433},
{4.91681,-14.9649},
{5.01681,-17.2974},
{5.11681,-18.8597},
{5.21681,-19.416},
{5.31681,-18.7978},
{5.41681,-16.9216},
{5.51681,-13.7988},
{5.61681,-9.53872},
{5.71681,-4.34296},
{5.81681,1.50794},
{5.91681,7.67462},
{6.01681,13.7843},
{6.11681,19.4588},
{6.21681,24.3444}};

Plotting list using ListPlot, I see:

ListPlot[list, PlotRange -> {-25, 35}, Joined -> True,
PlotStyle -> Directive[Red, Thickness[0.015]]]

I know that I can use the Fit function to "find a least-squares fit to a list of data as a linear combination of the functions funs of variables vars." However, it seems that I can only have a single coefficient. For example, in the following code, I do three different types of fits:

1. In cosfit, I fit list to Cos[n*x] functions: cosfit = Fit[list, Table[Cos[n*x], {n, 0, end}], x];
2. In sinfit, I fit list to Sin[n*x] functions: sinfit = Fit[list, Table[Sin[n*x], {n, 0, end}], x];
3. In cossinfit, I fit list to Cos[n*x] + Sin[n*x] functions: Fit[list, Table[Cos[n*x] + Sin[n*x], {n, 0, end}], x];

However, in the resulting fits, each function has only a single coefficient. For example, the fit of list to Cos[n*x] + Sin[n*x] (i.e., in cossinfit) becomes:

$$c_0(\cos[0x] + \sin[0x]) + c_1(\cos[1x] + \sin[1x]) + c_2(\cos[2x] + \sin[2x]) + \ldots,$$

rather than

$$a_0\cos[0x] + b_0\sin[0x] + a_1\cos[1x] + b_1\sin[1x] + a_2\cos[2x] + b_2\sin[2x] + \ldots.$$

My question is, in the following code, how do I fit to both $\cos$ and $\sin$ (with separate coefficients in front of each $\cos$ or $\sin$ term)?

Grid[
Table[

cosfit = Fit[list, Table[Cos[n*x], {n, 0, end}], x];
sinfit = Fit[list, Table[Sin[n*x], {n, 0, end}], x];
cossinfit = Fit[list, Table[Cos[n*x] + Sin[n*x], {n, 0, end}], x];
{
Show[{
ListPlot[list, PlotRange -> All, Joined -> True,
PlotStyle -> Directive[Red, Thickness[0.015]]],
Plot[cosfit, {x, list[[1, 1]], list[[-1, 1]]}, PlotRange -> All,
PlotStyle -> Black]
}, PlotRange -> {-25, 35}, ImageSize -> 350,
PlotLabel -> "Cos Fit: n = " <> "0.." <> ToString[end]],

Show[{
ListPlot[list, PlotRange -> All, Joined -> True,
PlotStyle -> Directive[Red, Thickness[0.015]]],
Plot[sinfit, {x, list[[1, 1]], list[[-1, 1]]}, PlotRange -> All,
PlotStyle -> Black]
}, PlotRange -> {-25, 35}, ImageSize -> 350,
PlotLabel -> "Sin Fit: n = " <> "0.." <> ToString[end]],

Show[{
ListPlot[list, PlotRange -> All, Joined -> True,
PlotStyle -> Directive[Red, Thickness[0.015]]],
Plot[cossinfit, {x, list[[1, 1]], list[[-1, 1]]},
PlotRange -> All, PlotStyle -> Black]
}, PlotRange -> {-25, 35}, ImageSize -> 350,
PlotLabel -> "Cos/Sin Fit: n = " <> "0.." <> ToString[end]]
}

, {end, {1, 2, 5, 20, 25, 30}}]
]

which gives this output:

Is using Fit the way to go, or should I use some other built-in Mathematica function?

(In actuality, list was generated by taking discrete points from the function:

9 Cos[x] + 9 Cos[2 x] + 9 Cos[3 x] + 6 Sin[x] + 6 Sin[2 x] + 6 Sin[3 x]

which I chose as a minimal working example. But in general, I will not know the functional form of the data in list, since in general I will obtain list from (noisy) empirical measurements.)

• It almost seems like I should be using FourierSeries or something like that. But in general I don't know the functional form of the data in list since list is in general obtained empirically. Mar 4, 2014 at 17:28
• Table[Cos[n x], {n, 0, 10}] ~Join~ Table[Sin[n x], {n, 1, 10)]. But why don't you use Fourier instead? Mar 4, 2014 at 17:59

It seems that one way to accomplish separate coefficients for $\cos$ and $\sin$ is to define something like:

bothfit = Fit[list, Flatten[Table[{Cos[n*x], Sin[n*x]}, {n, 0, end}]], x];

where I use Flatten to flatten out the Table before the Fit. I get this result:

Grid[
Table[

bothfit =
Fit[list, Flatten[Table[{Cos[n*x], Sin[n*x]}, {n, 0, end}]], x];

{
Show[{
ListPlot[list, PlotRange -> All, Joined -> True,
PlotStyle -> Directive[Red, Thickness[0.015]]],
Plot[bothfit, {x, list[[1, 1]], list[[-1, 1]]}, PlotRange -> All,
PlotStyle -> Black]
}, PlotRange -> {-25, 35}, ImageSize -> 350,
PlotLabel -> "Both Fit: n = " <> "0.." <> ToString[end]]
}

, {end, {1, 2, 3, 5, 20, 25, 30}}]
]

which seems like the correct result. For example, if I look at the fit with end having the value 30, the resulting function is essentially the function from which the data was derived for the minimal working example in the original post:

output = 1.41844*10^-16 + 9. Cos[x] + 9. Cos[2 x] + 9. Cos[3 x] +
3.79959*10^-15 Cos[4 x] + 4.69366*10^-15 Cos[5 x] +
1.78808*10^-15 Cos[6 x] - 3.12918*10^-15 Cos[7 x] -
1.3411*10^-15 Cos[8 x] - 4.47042*10^-16 Cos[9 x] +
4.47052*10^-16 Cos[10 x] + 7.82362*10^-16 Cos[11 x] -
5.02962*10^-15 Cos[12 x] + 2.90611*10^-15 Cos[13 x] -
3.12978*10^-15 Cos[14 x] + 4.69489*10^-15 Cos[15 x] +
1.56505*10^-15 Cos[16 x] + 2.23593*10^-15 Cos[17 x] +
6.70829*10^-16 Cos[18 x] - 8.94518*10^-16 Cos[19 x] +
3.91394*10^-15 Cos[20 x] + 5.36838*10^-15 Cos[21 x] -
1.5101*10^-15 Cos[22 x] + 6.26537*10^-15 Cos[23 x] -
3.58113*10^-15 Cos[24 x] + 2.23898*10^-15 Cos[25 x] -
2.24004*10^-15 Cos[26 x] + 2.68992*10^-15 Cos[27 x] -
1.79528*10^-15 Cos[28 x] + 4.49745*10^-16 Cos[29 x] -
1.80804*10^-15 Cos[30 x] + 6. Sin[x] + 6. Sin[2 x] + 6. Sin[3 x] +
1.34457*10^-15 Sin[4 x] - 2.24094*10^-15 Sin[5 x] -
3.13727*10^-15 Sin[6 x] + 1.56862*10^-15 Sin[7 x] +
2.24084*10^-16 Sin[8 x] + 7.17056*10^-15 Sin[9 x] -
2.24075*10^-15 Sin[10 x] + 8.96275*10^-16 Sin[11 x] +
2.68874*10^-15 Sin[12 x] + 1.79243*10^-15 Sin[13 x] -
1.79236*10^-15 Sin[14 x] - 8.06524*10^-15 Sin[15 x] -
3.13631*10^-15 Sin[16 x] + 4.48015*10^-16 Sin[17 x] -
8.95963*10^-16 Sin[18 x] + 2.23971*10^-15 Sin[19 x] +
8.95787*10^-16 Sin[20 x] - 2.01526*10^-15 Sin[21 x] -
1.56717*10^-15 Sin[22 x] + 6.7151*10^-16 Sin[23 x] -
2.23779*10^-16 Sin[24 x] - 3.57924*10^-15 Sin[25 x] +
3.35395*10^-15 Sin[26 x] + 2.23441*10^-15 Sin[27 x] +
4.46389*10^-16 Sin[28 x] + 1.78194*10^-15 Sin[29 x] +
2.21658*10^-15 Sin[30 x];

Chop[output]

9. Cos[x] + 9. Cos[2 x] + 9. Cos[3 x] + 6. Sin[x] + 6. Sin[2 x] + 6. Sin[3 x]

But this approach may not be the best way to accomplish the fit.