简体   繁体   中英

levenberg marquardt curve fitting MATLAB

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. 在此输入图像描述

在此输入图像描述

在此输入图像描述

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.

The parameters lb and ub are the lower and upper bounds of your output, ie 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, ie 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 , ie 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM