Why 'lsqcurvefit' doesn't work well?

Hi,
I'm trying to fit a data vector with 'lsqcurvefit', using a sine type function, but it always give me wrong coefficients.
Which the wrong part of my code?
What are the things I've to know in order to use this function in the best way?
Here's the part of the code:
clear
xdata = [0
0.00435001279502956
0.0143500127950347
0.0243500127950256
0.0343500127950307
0.0443500127950358
0.0543500127950267
0.0643500127950318
0.0743500127950370
0.0843500127950279
0.0943500127950330
0.104350012795038
0.114350012795029
0.124350012795034
0.134350012795025
0.144350012795030
0.154350012795035
0.164350012795026
0.174350012795031
0.184350012795036
0.194350012795027
0.204350012795032
0.214350012795038
0.224350012795028
0.234350012795034
0.244350012795024
0.254350012795030
0.264350012795035
0.274350012795026
0.284350012795031
0.294350012795036
0.304350012795027
0.314350012795032
0.324350012795037
0.334350012795028
0.344350012795033
0.354350012795038
0.364350012795029
0.374350012795034
0.384350012795025
0.394350012795030
0.404350012795035
0.414350012795026
0.424350012795031
0.434350012795036
0.444350012795027
0.454350012795032
0.464350012795038
0.474350012795028
0.484350012795034
0.494350012795024
0.504350012795030
0.514350012795035
0.524350012795026
0.534350012795031
0.544350012795036
0.554350012795027
0.564350012795032
0.574350012795037
0.584350012795028
0.594350012795033
0.604350012795038
0.614350012795029
0.624350012795034
0.634350012795025
0.644350012795030
0.654350012795035
0.664350012795026
0.674350012795031
0.684350012795036
0.694350012795027
0.704350012795032
0.714350012795038
0.724350012795028
0.734350012795034
0.744350012795024
0.754350012795030
0.764350012795035
0.774350012795026
0.784350012795031
0.794350012795036
0.804350012795027
0.814350012795032
0.824350012795037
0.834350012795028
0.844350012795033
0.854350012795038
0.864350012795029
0.874350012795034
0.884350012795025
0.894350012795030
0.904350012795035
0.914350012795026
0.924350012795031];
ydata = [0
0.662955000000011
2.14122499999999
2.15647500000000
3.46713500000001
4.88450499999999
6.16466500000001
7.55152500000000
8.77077500000002
9.66995499999999
10.4929250000000
11.0110650000000
11.7121250000000
11.9864450000000
11.9864450000000
12.1084050000000
12.1084050000000
12.1084050000000
12.1084050000000
11.7883250000000
10.6300850000000
9.56324500000000
8.11542499999999
6.62189500000000
4.99116500000000
4.97591500000002
3.58904500000000
2.29363499999999
1.25730500000000
0.129514999999998
-1.02873500000001
-2.30889500000001
-3.61955499999999
-5.38744499999999
-7.18579499999999
-8.77078499999999
-8.78603500000000
-9.94427500000001
-11.0720750000000
-12.1084050000000
-12.1084050000000
-12.1084050000000
-12.1084050000000
-10.5691350000000
-9.68520500000000
-8.19163499999999
-6.80476500000000
-6.78956500000001
-5.05217500000001
-3.61955499999999
-1.88220500000000
-0.236224999999990
1.25730500000000
2.58321500000000
3.98532499999999
5.44840500000001
6.86572500000000
8.11542499999999
8.13067500000000
9.30417500000002
10.1423950000000
10.7215350000000
11.4073450000000
11.7730750000000
12.0779050000000
12.0779050000000
12.0779050000000
12.0779050000000
11.7273750000000
11.7273750000000
11.4378050000000
10.6757850000000
9.19751500000001
7.44486499999999
5.44840500000001
4.22915499999999
2.93374499999999
1.86690500000000
0.525794999999988
-0.358174999999989
-0.388634999999994
-1.77549500000001
-3.14711499999999
-5.05217500000001
-6.28662499999999
-7.47537499999999
-8.84698499999999
-10.5691350000000
-11.7883350000000
-12.0322050000000
-12.0322050000000
-12.0322050000000
-12.0322050000000
-11.6816750000000];
% Fitting with sine
fitfun = @(x,xdata)x(1)*sin(x(2)*xdata);
x0 = [1 1];
lb = [0 0];
ub = [20 20];
x = lsqcurvefit(fitfun,x0,xdata,ydata,lb,ub);
I expect x(1) = 12 and x(2) = 12.5 (or around that values).
Thank you,
Alberto

Answers (3)

John D'Errico
John D'Errico on 11 Sep 2017
Edited: John D'Errico on 11 Sep 2017
Your starting values were terrible.
x = lsqcurvefit(fitfun,[10 15],xdata,ydata,lb,ub)
Local minimum possible.
lsqcurvefit stopped because the final change in the sum of squares relative to
its initial value is less than the default value of the function tolerance.
<stopping criteria details>
x =
11.835 12.054
Think of an optimization as a blind man placed on the surface of the earth, and asked to find the point of lowest elevation. (I hope you gave the fellow some scuba gear. Pay him well too.)
His search can be based on only tapping his cane around him, to learn which direction goes down hill. Of course, he does remember previous searches, so he will learn about the local environment.
Now, start him off near the Dead Sea. Do you think he will find the Marianas trench, in the depths of the Pacific?
Supply poor starting values to an optimization, then you should expect failure.
The point [11.8345078268441686, 12.0538585044576223] has a residue of 208.47.
There is a better minima at approximately 11.9184661364229907, 9412.4660804057512, residue 163.8
Note: because sin(-x) = -sin(x), if you take the negative of both x(1) and x(2), the function would calculate the same value. You can therefore constrain one of the two to be non-negative.
Note: we can predict that if a given value of x(2) produced a global minima, that integer multiples of the value should produce the same minima because of harmonics.

1 Comment

>> f = @(ab)sum((ab(1)*sin(ab(2)*xdata)-ydata).^2)
>> fminsearch(f, [12 12])
ans =
11.8345431177906 12.0538592442378
>> f(ans)
ans =
208.468756601986

Sign in to comment.

Categories

Asked:

on 11 Sep 2017

Answered:

on 12 Sep 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!