Reputation: 123
enter image description hereI don't know how choose the lb
and ub
for lsqcurvefit
in MATLAB , as well as x0
, to fit my function to data, I mean I have some output but they are not correct,
Here is my data:
xdata= [22.8700000000000;7.92000000000000;3.45000000000000;1.78000000000000;
1.57000000000000;6.41000000000000;12.9000000000000;1.82000000000000;
1.86000000000000;3.71000000000000;12.0900000000000;15.9900000000000;
18.9600000000000;23.1500000000000;23.4500000000000;24.8200000000000;
25.0700000000000;13.2800000000000];
ydata= [8.44300000000000;7.92100000000000;7.64600000000000;7.51600000000000;
7.47100000000000;7.82100000000000;8.03200000000000;7.76200000000000;
7.77400000000000;7.87800000000000;8.07000000000000;8.26000000000000;
8.40000000000000;8.52000000000000;8.52000000000000;8.57000000000000;
8.58000000000000;8.03200000000000];
and then I will have myfunc in a separate m file:
function F = myfun(x,xdata)
F=x(1)*(1-x(2)^2)./((1+x(2)^2+2*x(2)*cosd(xdata)).^1.5);
I have x(1)
and x(2)
, unknown which I like to estimate after fitting to my data, and I know that k x(2)
will not be a negative value.
So I set lsqcurvefit
like this:
[x, resnorm]=lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, 0, 1.5, options)
And this is the result:
x = 1.5000 -0.4945
resnorm = 52.1739
which shows a negative value for x(2)
!
could you please help me?
Thanks a lot for answer my question, and now after the command calculated the x and resnorm, I use the results in my function it means that I used x(1)=92.8054 x(2)=0.7427
so;
F=92.8054*(1-(0.7427)^2)./((1-0.7427)^2+2*(0.7427)*cosd(xdata)).^1.5;
now I have vector F , when I plot my data and results , plot(xdata, ydata, 'o', xdata, F, '*')
I don't why the range of axis y is so different! maybe I need to add x(3) to my function.
I attached the figure.
Upvotes: 0
Views: 6804
Reputation: 14108
Why not to use simple least squares solution:
in = [ones(size(xdata, 1), 1), xdata];
w = in \ ydata;
ydata_fit = in * w;
Result:
>> disp(w)
7.5744
0.0401
Upvotes: 0
Reputation: 45752
Your upper and lower boundaries must be vectors with the same number of elements as what you are trying to estimate, in your case x.
So for example if you want x(1) to be unbounded and x(2) to be between 0 and 1.5 then try
[x, resnorm]=lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, [-inf, 0], [inf, 1.5], options)
To calculate F use your objective function you have already created:
F = myfun(x, xdata)
and then plot it the way you already have. In your comment below you have switch a +
to a -
, this is why your graphs aren't aligning.
Upvotes: 1
Reputation: 8527
The parameters lb
and ub
are the lower and upper bounds of your output, i.e. your optimized value xopt
will satisfy lb <= xopt <= ub
.
As you already know, that x(2)
cannot be negative, you already have one lower bound, which
is zero, i.e. lb(2) = 0
. Now you only need to define a lower bound for x(1)
and upper bounds for both x(1)
and x(2)
.
The following code will restrict x(1) to [-inf, 1e3]
and x(2) to [0, 1e3]
:
lb = [-inf, 0];
ub = [1e3, 1e3];
[x, resnorm] = lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, 0, 1.5, ...
lb, ub, options)
I'm also a bit puzzeled that your approach worked. According to the documentation,
you should pass empty vectors, if you do not have upper or lower bounds but want to provide options
, i.e. your example should read
[x, resnorm] = lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, 0, 1.5, ...
[], [], options)
Probably, we have different versions of Matlab.
Upvotes: 1