6
$\begingroup$

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)).$$

See for example, this page.

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

ListPlot

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:

FitOutput

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.)

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – Andrew
    Mar 4, 2014 at 17:28
  • 2
    $\begingroup$ Table[Cos[n x], {n, 0, 10}] ~Join~ Table[Sin[n x], {n, 1, 10)]. But why don't you use Fourier instead? $\endgroup$
    – Szabolcs
    Mar 4, 2014 at 17:59

1 Answer 1

9
$\begingroup$

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

Flatten

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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