sineFit is a function to detect the parameters of a noisy sine curve, even less than one period long.
It requires only x and y values and no additional parameters as input.
It is tested with R2016a and R2020a.
The mean calculation time is on my PC 13 ms with a maximum of 2400 ms.
optional: plot graphics if ommited. Do not plot if 0
x and y values, y = offs + amp * sin(2pi * f * x + phi) + noise
SineParams(2): amplitude (amp)
SineParams(3): frequency (f)
SineParams(4): phaseshift (phi)
SineParams(5): MSE , if negative then SineParams are from FFT
This is a brief and not exact description of the program flow.
• Estimate the offset by the mean of all y values.
• Build the FFT with heavy zero padding.
• Take the frequency, amplitude and phase of the largest FFT peak.
If the frequency is at the Nyquist limit or the period is less than one, add extra frequencies for evaluation.
• Take those values as initial values for the regressions.
• Take the resulting MSE as rating.
• Exclude results above Nyquist frequency.
• Depending on the number of samples and the MSE, set a limit for an accepted amplitude in relation to the FFT amplitude.
• If the amplitude from regression is higher than the accepted amplitude, take the FFT parameters.
A demonstration GUI is included.
For more information read the "ReadMe.pdf".
Peter Seibold (2021). Sine fitting (https://www.mathworks.com/matlabcentral/fileexchange/66793-sine-fitting), MATLAB Central File Exchange. Retrieved .
Truly great! Thank you so much for you contribution!
@Alexandra, please send a problematic data example (x and y values) by email to me.
It's 3am and I don't quite know the etiquette of bug reporting here so please excuse if this is the wrong place for it. The function worked for a lot of data then stopped with an error when I passed it some data with a ramped offset. When Numf>1, paramsFFT has more than 4 columns. In line 95, when you preassign paramsOut=zeros(Numf,6); it looks like this assumes paramsFFT only has 4 columns. It looks like changing line 95 to paramsOut=zeros(Numf,length(paramsFFT)+2) should work, but does anything else need to be changed as well? e.g. do I need to change references to paramsOut(i,5) to paramsOut(i,end-1)? Sorry, I don't know enough about the method to know whether this is enough?
Really useful for challenging data. Well documented.
Needed a program for fitting real data with a sine wave and this does the job perfectly!
Great in-depth "readme" pdf for those interested in the details, and a "basictest.m" file for those who just want to start using the fit function.
As stated in the ReadMe.pdf, I made the evaluation for 0.3 to 10 periods in the observed range. The peak/zero evaluation is not for the final result. It serves as initial start values for the regression. This regression (done with nlinfit.m) uses all input samples, thefore no information is thrown away. In many faulty cases, even when you take the correct sine parameters as initial value, the regression delivers faulty results, i.e. the best fit for this noisy sine is another sine. Therefore I doudt that a FTT will deliver better results in this case. Nevertheless I think with many periods in the observed range the FFT may beat the evaluation in the time domain. I will consider FFT as suplement in a later version.
Looks interesting for use cases with few periods in sample range, especially <1. However, at least for large number of periods in sample range, it is more robust and efficient to FFT the samples and watch for the largest component and DC. With a large number of samples, an SNR of -20 dB is no problem then, something impossible with peak/zeros evaluation. Reason: Fitting to a sine model implies a specific phase relationship of all samples. Only evaluating peaks and zeros means throwing away a lot of information.
Find the treasures in MATLAB Central and discover how the community can help you!Start Hunting!