Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

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

1 Answer 1

up vote 6 down vote accepted

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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