user1331843
user1331843

Reputation: 123

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.enter image description here

enter image description here

enter image description here

Upvotes: 0

Views: 6804

Answers (3)

Serg
Serg

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:

enter image description here

>> disp(w)
    7.5744
    0.0401

Upvotes: 0

Dan
Dan

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

Mehrwolf
Mehrwolf

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

Related Questions