lsqcurvefit issues due to variables being several orders of magnitude different

6 次查看(过去 30 天)
I am trying to use lsqcurvefit to fit an equation to some data in order to solve for a couple variables. I have included the part of the code below that covers this. I am trying to solve for coeff(1) and coeff(2), The problem is that when I run lsqcurvefit, it is just using whatever my initial guesses are and outputting that as the solution. I suspect it is because my values for the coefficients will be several orders of magnitude different. You can kind of get an idea for this by looking at coeff0. Has anyone else run into this problem and/or do you know how to work around it? Any insight would be greatly appreciated.
load('V1.mat')
load('Vp.mat')
load('data.mat')
V = [V1, Vp]; %voltages
a = 1.1792;
b = 0.5;
e = 1.60217662e-19;
Area = 4.7909e-7;
mi = 39.948./(6.022e23.*1000);
coeff0 = [7e10 4]; %initial guess
qn7 = @(coeff, VV) e^1.5*coeff(1)*Area*sqrt(coeff(2)/(2*pi*mi))*100^3*...
(a*(-VV(:,1)/coeff(2)).^b.*tanh(VV(:,2)/(2*coeff(2))) + ...
(a*(-VV(:,1)/coeff(2)).^b - a*(-(VV(:,1)+VV(:,2))/coeff(2)).^b)./(exp(VV(:,2)/coeff(2))+1));
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt','OptimalityTolerance',1e-16,'FunctionTolerance',1e-16);
lb = [];
ub = [];
Unrecognized function or variable 'Ip'.
[vals, resnorm, out, flag] = lsqcurvefit(qn7, coeff0, V, data(:,2),lb,ub);
plot(data(:,1),data(:,2),'x',data(:,1),qn7(vals,V),'b-')
  5 个评论
Andrew
Andrew 2024-7-31
Thank you for the help. How do I look at the gradient calculations?
This is actually one of hundreds of points I need to look at so I need to figure out how to get it to work without me manually finding the best values.
Andrew
Andrew 2024-7-31
编辑:Andrew 2024-7-31
So I tried scaling the variables and even the equation to see if it did have to do with my variables being to different in terms of order of magnitude. That didn't do anything.
I also tried using the trust-region-reflective algorithm. It didn't improve the fit most of the time. Interesting enough though, I have some data points that were near the edge of my plasma where my densities are pretty low and I didn't get the signature "S" shape I was looking for. Trust-region-reflective did tend to work better for those cases.
I ended messing around with the options and the bounds. The following options and bounds get me a pretty good fit for the majority of my data points. I realized my OptimalityTolerance and FunctionTolerance were causing it to step out. I cranked those down and then it started having issues with the StepTolerance the majority of the time and on occasion the ConstraintTolerance. It appears that the majority of the time, my stepsize is getting extremely small and causing it to step out. I need to look in to how the step size is calculated and figure out why this would be happening when the fit is still pretty far off. Also, my tolerances are probably overkill right now. I was just cranking them down to see what happens, but after a certain point it didn't really make a difference.
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt','OptimalityTolerance',1e-100,'FunctionTolerance',1e-100,'StepTolerance',1e-100,'ConstraintTolerance',1e-100);
lb = [1e8 0];
ub = [1e13 20];
Edit: Adding the following option to the options appears to make it converge succesfully more often.
'ScaleProblem','jacobian'

请先登录,再进行评论。

回答(1 个)

Torsten
Torsten 2024-7-31
编辑:Torsten 2024-7-31
load('V1.mat')
load('Vp.mat')
load('data.mat')
V = [V1, Vp]; %voltages
a = 1.1792;
b = 0.5;
e = 1.60217662e-19;
Area = 4.7909e-7;
mi = 39.948./(6.022e23.*1000);
coeff0 = [1e-5 10]; %initial guess
Eqn7 = @(coeff, VV) coeff(1)*sqrt(coeff(2))*...
(a*(-VV(:,1)/coeff(2)).^b.*tanh(VV(:,2)/(2*coeff(2))) + ...
(a*(-VV(:,1)/coeff(2)).^b - a*(-(VV(:,1)+VV(:,2))/coeff(2)).^b)./(exp(VV(:,2)/coeff(2))+1));
%options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt','OptimalityTolerance',1e-16,'FunctionTolerance',1e-16);
lb = [];
ub = [];
[vals, resnorm, out, flag] = lsqcurvefit(Eqn7, coeff0, V, data(:,2));
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
plot(data(:,1),data(:,2),'x',data(:,1),Eqn7(vals,V),'b-')
format long
vals(1)
ans =
2.620938226982966e-06
vals(1)=vals(1)*sqrt(2*pi*mi)/(e^1.5*Area*100^3);
vals(1)
ans =
5.507330928625227e+10
vals(2)
ans =
9.902502214206862

类别

Help CenterFile Exchange 中查找有关 Get Started with Curve Fitting Toolbox 的更多信息

标签

产品


版本

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by