![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/275847/image.png)
Scaling Objective Function for Widely Varying Parameters: Data Fitting with lsqcurvefit
2 ビュー (過去 30 日間)
古いコメントを表示
Joshua Hill
2020 年 3 月 8 日
コメント済み: Joshua Hill
2020 年 3 月 10 日
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:![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/275847/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/275847/image.png)
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!