0

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

user1331843
  • 123
  • 1
  • 6
  • 15
  • Are you sure this is the right model for your data? Making a plot of xdata vs. ydata doesn't really deviate much from a straight line. Leaving out the lb and ub entirely and trying a few hundred starting values consistently converges onto something that doesn't resemble the data much...Also, the cosine part looks like something derived from the law of cosines, but then messed-up...are you really sure this is the correct formula? – Rody Oldenhuis Jul 30 '12 at 11:37
  • I am pretty sure about the function, my question is that for example in observation data, the rang of variation is from 7.4 to 8.8, but when I use the result in my function the range is between 21.5 to 25 as you can see above in graphs. and sorry i didn't get your comment you ean I should change the value of x0, which already is [-0.5:0.5]? – user1331843 Jul 30 '12 at 13:32
  • Your mistake is that you have gone 1-0.7427 to calculate F instead of 1+0.7427. i.e. try F=92.8054*(1-(0.7427)^2)./((1+0.7427)^2+2*(0.7427)*cosd(xdata)).^1.5; – Dan Jul 30 '12 at 14:00
  • wow, I am really sorry what a stupid mistake, and thanks a lot. – user1331843 Jul 30 '12 at 15:20

3 Answers3

1

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.

Dan
  • 45,079
  • 17
  • 88
  • 157
  • 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 – user1331843 Jul 30 '12 at 13:11
  • See my edit, this is because your formula above is different to your objective function. You have switched a + into a - – Dan Jul 30 '12 at 13:22
  • yep, you are right, thanks and if I want to use more parameter, how should I write bounds for them, I mean if I increase x(3), and x(4) somehow, so is it correct? for example [-Inf -Inf 0 -Inf] or it needs comma between? – user1331843 Jul 31 '12 at 07:28
  • yes you are correct. The would set no lower bound for x(1), x(2) or x(4) but force x(3) to be positive (or zero! the bounds are inclusive). In matlab [a b c] is the same as [a, b, c] the comma or space mean column concatenation where as a semi colon would be row concat. – Dan Jul 31 '12 at 07:50
1

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.

Mehrwolf
  • 8,208
  • 2
  • 26
  • 38
0

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
Serg
  • 13,470
  • 8
  • 36
  • 47
  • It is not possible to specify bounds for the optimization variable using a simple least squares approach. – Mehrwolf Jul 31 '12 at 13:26