Fit Data To Fourier Series

Hi,

I want to fit some experimental data to a fourier series and have big problems to do the fit. Also a simple sin function did not work.
Attached is an example igor file.

I tried to fit with the following function:

Function fitFourierModel(w, x): FitFunc
    Wave w
    Variable x
   
    return w[0] + w[1]*cos(x + w[11]) + w[2]*sin(x + w[11]) + w[3]*cos(2*(x + w[11])) + w[4]*sin(2*(x + w[11])) + w[5]*cos(3*(x + w[11])) + w[6]*sin(3*(x + w[11])) + w[7]*cos(4*(x + w[11])) + w[8]*sin(4*(x + w[11])) + w[9]*cos(5*(x + w[11])) + w[10]*sin(5*(x + w[11]))
End


Do you have any suggestions?

Thanks

FourierAnalysis.pxp
First of all a more detailed description of your issue might be beneficial.

I had a quick look at your experiment and it seem you confuse degrees (in your plots) and rad (in your fit function).
Readjustment or substitution of x by x/w[12] might help (w[12] should be very close to 180/pi in this case).

HJ
Hans-Joerg was correct. I obtained reasonable looking fits by substituting x*pi/180 for your argument x. Igor takes radian arguments for trig functions, and you have to convert your input data which is in degrees. I left w[11] alone, so it will return a value in radians. I made no other changes to your pxp. My fitting results are attached.
And, of course, you get better performance (which may or may not be important) if you factor out the conversion of degrees to rads:
Function fitFourierModel(w, x): FitFunc
    Wave w
    Variable x
 
    Variable rads = x*pi/180
    return w[0] + w[1]*cos(rads + w[11]) + w[2]*sin(rads + w[11]) + w[3]*cos(2*(rads + w[11])) + w[4]*sin(2*(rads + w[11])) + w[5]*cos(3*(rads + w[11])) + w[6]*sin(3*(rads + w[11])) + w[7]*cos(4*(rads + w[11])) + w[8]*sin(4*(rads + w[11])) + w[9]*cos(5*(rads + w[11])) + w[10]*sin(5*(rads + w[11]))
End

Steve- correct me if I'm wrong, but it seems like fitting both sin and cos phase angle (w[11]) and fitting separate sin and cos amplitudes creates a linear dependency. Isn't the phase angle set by the amplitude ratio?

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
OK, I'm not a mathematician, I'm an experimentalist, so I tried the fit and computed the correlation matrix, and it's pretty terrible (The numbers are rounded to three digits, so those 1's are really something like 0.9999...):
1   -0.0146 0.0146  0.0146  -0.0146 -0.0146 0.0146  0.0146  0.0146  -0.0146 0.0146  -0.0146 2.47e+03
-0.0146 1   -1  -1  1   1   -1  -1  -1  1   -1  1   -0.311
0.0146  -1  1   1   -1  -1  1   1   1   -1  1   -1  -0.344
0.0146  -1  1   1   -1  -1  1   1   1   -1  1   -1  0.195
-0.0146 1   -1  -1  1   1   -1  -1  -1  1   -1  1   2.76
-0.0146 1   -1  -1  1   1   -1  -1  -1  1   -1  1   -0.699
0.0146  -1  1   1   -1  -1  1   1   1   -1  1   -1  -1.95
0.0146  -1  1   1   -1  -1  1   1   1   -1  1   -1  -1.57
0.0146  -1  1   1   -1  -1  1   1   1   -1  1   -1  2.7
-0.0146 1   -1  -1  1   1   -1  -1  -1  1   -1  1   -0.304
0.0146  -1  1   1   -1  -1  1   1   1   -1  1   -1  -0.642
-0.0146 1   -1  -1  1   1   -1  -1  -1  1   -1  1   1.98

But eliminating all the sin terms makes a bad fit. What am I missing?

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
John,

You are correct. I was paying attention only to the degree-to-radian conversion. If you think of each sine and cosine as the decomposition of a single complex term, they must have a common phase, with relative amplitude related to cos(phi) and sin(phi). Of course, that phase angle may change with the Fourier harmonic, so using a common phase coefficient for all harmonics is incorrect too.
John and LausX,

After thinking more about John's comments (and my own previous response), I realized that if you want to express the fitting function as a sum of sine AND cosine terms, then no phase argument, i.e. w[11], should be included. The sum of a sine and cosine with different amplitudes is equivalent to a single sinusoid with a phase coefficient (you can look up the trig identities). The choice of form should depend on which is most useful to you. I repeated the pxp without phase angle coefficients (and with John's factorization speed-up), and have attached the result. Although the fit for data set 3 looks good, I don't understand its large V_chisq.
I was also thinking of a linear dependency of the sines and cosines first.
However, the phase shift is constant for all summands. This is identical to a situation in which you set it to zero and adjust the x-scaling of the corresponding wave.
Nevertheless you run into trouble if you consider the periodicity of the trigonometric functions. Further trouble arises from the addition rules etc.
Ultimately, w[11] should be constrained to [0,pi/2[ (open interval) to avoid these traps.

Happy fitting,
HJ

Edit:
I'm not entirely sure if a low frequency ,e.g., sine is really covered by high frequency cosines in case you use a small amount of components.
Thanks a lot for all your tips!

My idea was to fit the data according to the attached paper to equation 7 on page 6.
Also thanks for the tip with the linear dependency, I even didn't taught about that.

Let's see how the extracted values will agree with other literature values.

1.3446840.pdf
Another complementary approach you might consider is using Igor's FFT. By definition, this would give the best value for all of the harmonics (within the Nyquist limit); curve fitting gives the best value for a few selected harmonics (but including all the signal in the fitting). If the signal energy is indeed concentrated in a few harmonics, the results should be similar. I checked this out for your data set 3 (and added an additional non-negligible fitting harmonic), and it works.

It is also worth thinking about whether your data is affected by systemic, repeatable artifacts or by temporally variable random noise. The latter would contribute to a broad-power spectrum, and could be reduced by signal averaging. The former might be calibrated and subtracted from the data,
Keep in mind that the FFT operation results in a complex wave:
DisplayHelpTopic "Fourier Transforms"

FU?
Exactly. Both the magnitude and phase of each harmonic can be used to make a continuous function of the original x-variable similar to the curve fit function output, if desired. See Igor's FFT help file for an example of how to do the complex-to-real conversion of the FFT output.
I tried to write the fitting function in a more compacht form like:

Function fitFourierModel(w, x): FitFunc
    Wave w
    Variable x
   
    Variable rad = x*Pi/180
    Variable i, nmax, temp
    nmax = dimSize(w,0)
   
    temp = w[0]
    for (i = 1; i < 10; i+= 2)
        temp += w[i]*cos(rad) + w[i+1]*sin(rad)
        endfor

    return temp
//  return w[0] + w[1]*cos(rad) + w[2]*sin(rad) + w[3]*cos(2*rad) + w[4]*sin(2*rad) + w[5]*cos(3*rad) + w[6]*sin(3*rad) + w[7]*cos(4*rad) + w[8]*sin(4*rad) + w[9]*cos(5*rad) + w[10]*sin(5*rad)
End


But with this for-loop it is not possible to fit. Is this normal? Or do you have any ideas?

Thanks
I guess you missed the i* in the arguments to get the harmonics... --> cos(i*rad)
HJ

PS: Maybe you want to have a look at the "other" kind of fitfunctions using coefficient-, y-, and x-waves .
displayhelptopic "All-At-Once Fitting Functions"
You have an nmax parameter in your code, but don't use it. Also, I observed in data set 3, that the 6th harmonic is bigger than the 5th. I suggest increasing your for-loop limit to at least i<12.