Scaling Objective Function for Widely Varying Parameters: Data Fitting with lsqcurvefit
10 次查看(过去 30 天)
显示 更早的评论
I have am struggling to fit a dataset to a function which has fit parameters may orders of magnitude different from each other. From what I can tell, I need to scale the parameters inside the function so that there are meaningful changes to the output value when the fitting routine tweaks the parameters looking for optimal values. I have tried scaling the p(1) parameter inside the function to fit, "PAnumberSpectra", but have not yet found a method that works. Could someone provide direction?
My code/data are attached below. Sorry it's long, but it should be self-contained, and suffient to run by itself. I am using Matlab R2019B on Windows 10.
0 个评论
采纳的回答
Thiago Henrique Gomes Lobato
2020-3-8
The main problem actually isn't the scaling but rather the optimization algorithm. Your function seems to be extremely non-smooth with plently of local minima, and thus a gradient based approach isn't able to find a good solution. Using a non-gradient based algorithm can somewhat solve this problem. Here is my result when I use fminsearch that optimizes it with the Nelder-Mead algorithm:
The changes that I made in your code were:
lb = NftBnds(1,:); ub = NftBnds(2,:);
%[betaParams,~,residual] = lsqcurvefit(@PAnumberSpectra,guessVec,indVar,binAvgNum,lb,ub,options); % Fit the function (defined at bottom).
[betaParams,residual] = fminsearch(@PAnumberSpectra2,guessVec,options); % Fit the function (defined at bottom).
...
function Nft = PAnumberSpectra2(p,indVar)
% Parameter Labels
% p(1) = A, the amplitude param
% p(2) = sigma, the width param
% p(3) = f0, the center frequency
% p(4) = A0, the constant offset
% p(5) = Gamma, the one-body loss rate
% indVar(1) = Frequency of the PA beam
% indVar(2) = Exposure time
[binAvgFreq,tExp,binAvgNum] = loadData();
indVar = [binAvgFreq,tExp];
beta = p(1)*Gamma_mol/(sqrt(2*pi)*p(2))*exp((-(indVar(:,1)-p(3)).^2./(2*p(2)^2)))+p(4);
numerator = meanN0.*exp(-p(5).*indVar(:,2));
denomFactor = (meann0*beta*xi)./(2^(3/2)*p(5));
denominator = 1 + denomFactor.*(1 - exp(-p(5).*indVar(:,2)));
Nft = numerator./denominator;
Nft = rms(binAvgNum-Nft);
end
And you had a little error by the plotting:
plotNumFit = PAnumberSpectra(betaParams,indVarPlot);
initGuessAtomNum = PAnumberSpectra(guessVec,indVarPlot);%PAnumberSpectra(betaParams,indVarPlot);
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Surrogate Optimization 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!