Improving LSQCcurvefit solutions through improving x0 through loops
1 view (last 30 days)
Show older comments
Hello everyone,
I had a quick question in regards to attempting to improve my lsqccurvefit values by improving x0 through multiple datasets.
Data1=[0.596421471 0.06
0.5859375 0.119284294
0.566037736 0.29296875
0.530035336 0.622641509
0.418994413 1.219081272
0.388619855 3.058659218
];
Data2=[5.00E+04 3.82E+04 3.45E+04 3.42E+04 3.74E+04 3.21E+04 2.81E+04 2.88E+04
5.00E+04 3.82E+04 3.45E+04 3.42E+04 3.74E+04 3.21E+04 2.81E+04 2.88E+04
3.08E+04 3.07E+04 2.19E+04 2.23E+04 2.53E+04 2.05E+04 1.98E+04 1.89E+04
2.05E+04 1.87E+04 1.30E+04 1.10E+04 1.62E+04 1.31E+04 1.05E+04 1.05E+04
8963 1.11E+04 6243 3504 6454 4346 4448 4357
0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00
];
Pt=Data1(:,1);
Lt=Data1(:,2);
for n = 1:size( Data2, 2 )
Int=Data2(:,n);
...
plot(Lt,Int, 'ro');
xdata=[Pt,Lt]
F=@(x,xdata)((xdata(:,1)+xdata(:,2)+x(2))-((xdata(:,1)+xdata(:,2)+x(2)).^2-4.*xdata(:,1).*xdata(:,2).^1/2).*x(1)/2.*xdata(:,1))
x0=[1 1]
options=optimoptions('lsqcurvefit','MaxFunEvals',5e2)
lb=[];
up=[]
[x,resnorm,~,exitflag,output]=lsqcurvefit(F,x0,xdata,Int,lb,up,options)
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');
lb = [];
ub = [];
[x2,resnorm2,~,exitflag2,output2]=lsqcurvefit(F,x0,xdata,Int,lb,up,options)
M=mean(x)
M=mean(x2)
hold on
plot (Lt, F(x,xdata))
plot (Lt, F(x2,xdata))
hold off
end
In a nutshell, I have a function F that is trying to fit my Data 2 using 2 different algorithms. My end plot currently has a poor fit with my initial plot. I've seen that the initial starting values [x0] can have a signifigant impact on your results. Is there a way to have the later iterations in my loop change the x0 value and sample various x0 values and try and get closer to the real value that fits my data well (this can be done by doing an RMSD or something like that with my initial plot and vlues). The simplest way I was thinking of having this done is using having x0 change to the results of the previous run. I.E. The first run using the x0 I gave it, the 2nd x0 that is used in the 2nd run uses the results of the previous run as it's own x0.
I don't quite know how to do this, whether this is a modification through x0 (like my example), or through using a loop within my current loop that runs the same dataset n=1 repeatedly through multiple iterations using the RMSD example I gave above to try and improve it. Then do the same thing for the 2nd dataset (n=2), although I can see this method taking quite a while and maybe potentially creating an endless loop.
0 Comments
Answers (2)
Matt J
on 12 Mar 2019
For such a small problem, it is a simple matter to do a vectorized exhaustive search, rather than looping
[X1,X2]=meshgrid(linspace(-50000,0,500), linspace(-60,60,100));
[mm,nn]=size(X1);
XX1=reshape(X1,1,1,[]);
XX2=reshape(X2,1,1,[]);
Y=reshape(vecnorm(F([XX1,XX2],xdata)-Int,inf,1),mm,nn);
[minval,idx]=min(Y(:)),
x0=[X1(idx),X2(idx)]
17 Comments
Matt J
on 13 Mar 2019
Note that x.^1/2 is not the square root of x. Compare:
>> 2.^1/2
ans =
1
>> sqrt(2)
ans =
1.4142
Matt J
on 13 Mar 2019
Edited: Matt J
on 13 Mar 2019
I can see that your model function derives in some way from the quadratic formula, but I can't quite see where all the pieces are supposed to go. In any case, using the implementation below, I get a fit that approaches sensible. Maybe you can tweak it to perfection.
for n = 1:size( Data2, 2 )
Int=Data2(:,n);
xdata=[Pt,Lt]
%F=@(x,xdata)((xdata(:,1)+xdata(:,2)+x(1,2,:))-((xdata(:,1)+xdata(:,2)+x(1,2,:)).^2-4.*xdata(:,1).*xdata(:,2).^1/2).*x(1,1,:)/2.*xdata(:,1))
F=@modelfun;
[X1,X2]=meshgrid(linspace(0,1e4,500), linspace(0,60,100));
[mm,nn]=size(X1);
xx1=reshape(X1,1,1,[]);
xx2=reshape(X2,1,1,[]);
Y=reshape(vecnorm(F([xx1,xx2],xdata)-Int,inf,1),mm,nn);
[minval,idx]=min(Y(:)),
x0=[X1(idx),X2(idx)];
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');
[x2,resnorm2,~,exitflag2,output2]=lsqcurvefit(F,x0,xdata,Int,[],[],options)
plot (Lt,Int,'ro',Lt, F(x2,xdata))
xlabel 'Lt'
end
function out=modelfun(x,xdata)
Pt=xdata(:,1);
Lt=xdata(:,2);
x1=x(1,1,:);
x2=x(1,2,:);
A=Lt.*x1;
B=-(Pt+Lt+x2);
C=Pt;
out = ( -B + sqrt(B.^2-4.*A.*C) )./(2.*A);
end
See Also
Categories
Find more on Graph and Network Algorithms in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!