2

I'm trying to fit some data to a sum of sines function in MATLAB, however, the number of terms of sine function in MATLAB is limited,i.e. to 1 ≤ n ≤ 8. However, I want more terms in my fit functions, i.e. over 50 term. Is there anyway to make MATLAB to fit my data to a sum of sine function with over 8 sinusoidal terms? Why there is such constraint in MATLAB (is it technically or arbitrary)? Is there any toolbox to fit sinusoidal function (especially something that is capable of supporting wieghted data)?

>f = fit(X,Y, 'sin10')
>Error using fittype>iCreateFromLibrary (line 412)
>Library function sin10 not found.

It is o.k up to 'sin8' or 'sin9' parameters.

I appreciate any answer.

Mehdi
  • 293
  • 4
  • 13
  • 2
    Use Fourier fitting instead http://www.mathworks.com/help/curvefit/fourier.html?searchHighlight=fourier%20fitting For more than 8 terms you should implement the fit yourself though. However, 8 terms of fourier fitting is probably more than enough for most cases. – NKN Aug 08 '16 at 15:03

2 Answers2

1

I'v found a solution to my question accidentally, while browsing MATLAB help. I post this answer in hope of helping people who have the same problem.

As the first shot to solve this , I tried 'fit' instruction. For some reasons, customized 'fit' based fitting code like below, didn't workout:

FitOptions = fitoptions('Method','NonlinearLeastSquares', 'Algorithm', 'Trust-Region', 'MaxIter');
FitType = fittype('a*sin(1*f) + b*sin(2*f) + c*sin(3*f) + d*sin(4*f) + e*sin(5*f) + g*sin(6*f) + h*sin(7*f) + k*sin(8*f) + l*sin(9*f) + m*sin(10*f) + n*sin(11*f)', 'independent', 'f');
[FittedModel, GOF] = fit(freq, data, FitType)
% `In above code, phase parameters are not included, they might be added.

What I found is that using 'lsqcurvefit' instruction from Optimization Toolbox, customized function fitting is more feasible and easier than 'fit' function. I tested it to fit my data to sum of 12 (>8) sines in below code:

clear;clc
xdata=1:0.1:10; % X or Independant Data
ydata=sin(xdata+0.2)+0.5*sin(0.3*xdata+0.3)+ 2*sin( 0.2*xdata+23 )+...
    0.7*sin( 0.34*xdata+12 )+.76*sin( .23*xdata+.3 )+.98*sin(.76 *xdata+.56 )+...
    +.34*sin( .87*xdata+.123 )+.234*sin(.234 *xdata+23 ); % Y or Dependant data 
x0 = randn(36,1);  % Initial Guess
fun = @(x,xdata)x(1)*sin(x(2)*xdata+x(3))+... 
                x(4)*sin(x(5)*xdata+x(6))+...
                x(7)*sin(x(8)*xdata+x(9))+...
              x(10)*sin(x(11)*xdata+x(12))+...
              x(13)*sin(x(14)*xdata+x(15))+...
              x(16)*sin(x(17)*xdata+x(18))+...
              x(19)*sin(x(20)*xdata+x(21))+...
              x(22)*sin(x(23)*xdata+x(24))+...
              x(25)*sin(x(26)*xdata+x(27))+...
              x(28)*sin(x(29)*xdata+x(30))+...
              x(31)*sin(x(32)*xdata+x(33))+...
              x(34)*sin(x(35)*xdata+x(36)); % Goal function which is Sum of 12 sines
options = optimoptions('lsqcurvefit','Algorithm','trust-region-reflective');% Options for fitting 
x=lsqcurvefit(fun,x0,xdata,ydata) % the main instruction
times = linspace(xdata(1),xdata(end));
plot(xdata,ydata,'ko',times,fun(x,times),'r-')
legend('Data','Fitted Sum of 12 Sines')
title('Data and Fitted Curve')

The results is satisfactory (till now), it is shown in below:

result

SergV
  • 1,269
  • 8
  • 20
Mehdi
  • 293
  • 4
  • 13
1

The above problem is that when I use matlab fit function, with specified argument for Sum of Sines fitting (e.g fit(xdata,ydata,'sin6')), it easily converges to an optimum solution and fitting results are acceptable as below: Image 1

but when I tried to fit same data using a customarily defined function, it results are not satisfactory at all as you see in figure below:

fun=@(x,xdata)a1*sin(b1*xdata+c1)+...+a6*sin(b6*xdata+c6); %Sum if Six Sines
f=fit(xdata,ydata,fun);

Image 2

First, I felt it is the fit instruction so I tried other instructions like lsqcurvefit , it worked well for some data but as soon as other data were ued it started to ill-behave. From Maltab documentations, I figured out Sum of Sine fitting and Fourier fitting are extremely sensitive to Starting points or initial points, or values that fitting algorithm assumes for fitting parameters (amplitudes, frequencies and phases) for its first iteration. Through inspection of Matlab fitting toolbox .m files , I noticed matlab does some clever trick to obtain starting point when you use predefined function fitting (e.g. fit(x,y,'sin1'), or fit(x,y,'sin2'),... but when you chose ti enter your custom function the initial points are generated randomly! This is why Matlab build functions work and my custom function fitting does not (even though I enter the same function). By the way, Matlab computes FFT of the ydata and through some (seems greedy) method extracts initial points for amplitudes, frequencies and phases (a function called startpt.m does this).

SergV
  • 1,269
  • 8
  • 20
Mehdi
  • 293
  • 4
  • 13