I was trying to fit a data set into a sinusoidal function with the code below:
data = importdata('analisipicco.txt') ;
x = data(:,1) ; y = data(:,2) ;
yu = max(y);
yl = min(y);
yr = (yu-yl); % Range of ‘y’
yz = y-yu+(yr/2);
zx = x(yz .* circshift(yz,[0 1]) <= 0); % Find zero-crossings
per = 2*mean(diff(zx)); % Estimate period
ym = mean(y); % Estimate offset
fit = @(b,x) b(1).*(sin(2*pi*x./b(2) + 2*pi/b(3))) + b(4); % Function to fit
fcn = @(b) sum((fit(b,x) - y).^2); % Least-Squares cost function
s = fminsearch(fcn, [yr; per; -1; ym]) % Minimise Least-Squares
xp = linspace(min(x),max(x));
figure(1)
plot(x,y,'b', xp,fit(s,xp), 'r')
grid
Where the elements of output parameter vector, s ( b in the function ) are:
s(1): sine wave amplitude (in units of y)
s(2): period (in units of x)
s(3): phase (phase is s(2)/(2*s(3)) in units of x)
s(4): offset (in units of y)
But when I run the code with my set of data the command window show this:
Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
Current function value: NaN
s =
1.0e+05 *
1.0466
NaN
-0.0000
2.4885
I don't understand if my data are not fitting for a sinusoidal function or just the code is wrong for the sinusoidal fit.
For acknowledge this is my data set:
-200 183966
-192 189734
-184 195724
-176 201663
-168 207557
-160 213278
-152 219000
-144 224677
-136 229500
-128 236024
-120 241968
-112 247787
-104 252963
-96 257491
-88 261967
-80 267373
-72 273494
-64 278599
-56 281476
-48 282610
-40 283097
-32 283839
-24 284971
-16 286169
-8 287164
0 287968
8 288561
16 288626
24 288107
32 286967
40 285132
48 282828
56 279847
64 276296
72 272299
80 268080
88 263564
96 258926
104 254052
112 248894
120 243694
128 238177
136 232665
144 227143
152 221959
160 216874
168 211678
176 206540
184 201537
192 196748
200 192091
I'm sorry but I'm new to Matlab. Thank you in advance
Your code goes wrong on the line
zx = x(yz .* circshift(yz,[0 1]) <= 0);
yz
is a column vector, so circshift
ing it by 1 in the horizontal direction doesn't do anything at all.
Changing the [0 1]
into [1 0]
makes your code run correctly:
s =
1.0e+05 *
0.6986
0.0061
-0.0000
2.1975
To make your code more robust against changes in the input data orientation, you can use circshift(yz,1)
instead. Assuming that y
is always a vector, this will be correct no matter if it's a column or row vector.