How to constrain the lower and upper bounds in lsqcurvefit?

7 views (last 30 days)
Hi,
For a data set (x, y), I am trying to fit a function f(m, x) using lsqcurvefit. I write as follow:
x=xdata;
y=ydata;
fun=f(m,x);
m0=[m01; m02; m03]; %these are real numbers
lb=[0; 0; 0];
ub=[ub1; ub2; ub3]; %these are real numbers
m=lsqcurvefit(fun, m0, xdata, ydata, lb, ub);
However, sometimes it obeys the bounds and sometimes it does not while fitting. Could anyone please help me if there is any way of constraining the bounds?
Thank you very much in advance!
Kind regards,
Arun
  7 Comments
Arun Kumar Bar
Arun Kumar Bar on 2 Jan 2019
Edited: Matt J on 2 Jan 2019
Hi Matt,
Glad to see that you would like to chek yourself. I did not provide initially in details as the equation is a complex one. Anyway, I am providing here a small set of data, particularly where I face problem.
The rlprt is a 24x2 double, see the attached file, same is the imprt.
In the equation (see below), there are three independent parameters m1, m2 and m3.
Notably, all m(i) must be > 0;
When I fit individually (i.e. using xdata=rlprt(:, 1) and ydata=imprt(:, 1)), it results out all m(i) > 0. But when I run in loop, see bellow for the code I use, m(2) come out as negative values.
Thanks and regards,
Arun
-
--------
figure()
for i=1:2
xdata=rlprt(:, i);
ydata=imprt(:, i);
fun=@(m,xdata) ((((m(2)-m(1)).*tan(pi.*m(3)/2))/2)+((sqrt((((m(2)-m(1)).*tan(pi.*m(3)/2)).^2)-(4.*((xdata.*xdata)-(xdata.*(m(1)+m(2)))+(((m(1)+m(2)).^2)/4)-(((m(2)-m(1)).^2)/(4.*((sin(pi.*(m(3)-1)/2)).^2)))+(((m(2)-m(1)).^2).*((tan(pi.*m(3)/2)).^2)/4)))))/2));
m0=[0.45; 0.1815; 0.0735];
lb=[0; 0; 0];
ub=[2, 0.75, 0.25];
m=lsqcurvefit(fun, m0, xdata, ydata, lb, ub);
plot(xdata, ydata, 'o', 'linewidth', 1.5); hold on;
plot(xdata, fun(m, xdata), '-', 'linewidth', 1.5);
output(i, 1:3)=m(1:3, 1);
end
hold off;
--------
Matt J
Matt J on 2 Jan 2019
Edited: Matt J on 2 Jan 2019
I don't get negative values when I run this code. I get complex ones,
output =
0.3528 + 0.0001i -3.5428 - 1.5825i 0.2693 + 0.0047i
0.3698 + 0.0000i -0.0523 - 0.0029i 0.2063 + 0.0017i
Your function is not real-valued at certain m in the search space.

Sign in to comment.

Accepted Answer

Matt J
Matt J on 2 Jan 2019
Edited: Matt J on 2 Jan 2019
This seems to work okay,
for i=1:2
[xdata,is]=sort(realpart(:, i));
ydata=imaginarypart(is, i);
fun=@(m,xdata) ((((m(2)-m(1)).*tan(pi.*m(3)/2))/2)+((sqrt((((m(2)-m(1)).*tan(pi.*m(3)/2)).^2)-(4.*((xdata.*xdata)-(xdata.*(m(1)+m(2)))+(((m(1)+m(2)).^2)/4)-(((m(2)-m(1)).^2)/(4.*((sin(pi.*(m(3)-1)/2)).^2)))+(((m(2)-m(1)).^2).*((tan(pi.*m(3)/2)).^2)/4)))))/2));
m0=[0.45; 0.1815; 0.0735];
lb=[0; 0; 0];
ub=[2, 0.75, 0.25];
[m,resnorm,residual,exitflag,stats]=lsqcurvefit(@(m,xd) abs(fun(m,xd)), m0, xdata, ydata, lb, ub);
plot(xdata, ydata, 'o', 'linewidth', 1.5); hold on;
plot(xdata, fun(m, xdata), '-', 'linewidth', 1.5);
output(i, 1:3)=m(1:3, 1);
end
output =
0.3522 0.0000 0.1771
0.3676 0.0239 0.1444
untitled.png
  2 Comments
Arun Kumar Bar
Arun Kumar Bar on 2 Jan 2019
Hi Matt,
Thank you very much for your efforts to reply so promptly!
Yes, these codes do work for this data set. Notably, It appears quite surprising to me now. For the data sets where I used to get -ve values of the real parts of the output m(i) using the codes I provided in my previous comment, now I get better fittings and more reliable outputs through the way you suggested. However, the data sets which give better fitting and more reliable outputs through the way I used to use, now result out very poor fitting and unrliable outputs through the way you suggested. It appears strange to me, at least at the moment. Let me see if I can figure out where it's going wrong.
Thanks a lot once again!
Kind regards,
Arun.
Arun Kumar Bar
Arun Kumar Bar on 3 Jan 2019
Thanks a lot, dear Matt! It's working fine now.
Kind regards,
Arun

Sign in to comment.

More Answers (0)

Categories

Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!