Reputation: 1475
when I use the lsqcurvefit
to calibrate the parameters of an arbitrary function fun
fun = @(p,x)(p(1)./x .* 1./(p(3)*sqrt(2*pi)).*exp(-(log(x)-p(2)).^2./(2*p(3)^2)));
for two cases p_in
, p_out
by doing
opts = optimoptions('lsqcurvefit','TolX',1e-4,'TolFun',1e-8);
p0 = [1,1,1];
p_in = lsqcurvefit(fun,p0,xR_in,yR_in,[],[],opts);
p_out = lsqcurvefit(fun,p0,xR_out,yR_out,[],[],opts);
I get on first glance a quite decent fit for both curves
However if I look at the same result in a logarithmic scale the fit does not look as good anymore:
This made me wonder if there is a possibility to consider the logarithmic error in the cost function of lsqcurvefit
, which would basically mean looking at the relative error at each x
value of the function.
Is there is possibility in Matlab to enforce this?
Example data:
xR_in =[0.0649, 0.0749, 0.0865, 0.1000, 0.1155, 0.1334, 0.1540, 0.1779, 0.2054, 0.2371, 0.2739, 0.3162, 0.3651, ...
0.4217, 0.4870, 0.5623, 0.6494, 0.7498, 0.8660, 1.0000, 1.1548, 1.3335, 1.5399, 1.7782, 2.0535, 2.3714, ...
2.7384, 3.1623, 3.6517, 4.2170, 4.8696, 5.6234, 6.4938, 11.5477 13.3351];
xR_out = [0.487, 0.562, 0.649, 0.750, 0.866, 1.000, 1.155, 1.334, 1.540, 1.778, 2.054, 2.371, 2.738, 3.162, 3.652, ...
4.217, 4.870, 5.623, 6.494, 7.499, 8.660, 10.000, 11.548, 13.335, 15.399, 17.783, 20.535, 23.714, 27.384, ...
31.623, 36.517, 42.170, 48.697, 56.234, 64.938, 74.989, 86.596, 100.00];
yR_in = [0.00455681508591336, 0.00873409885607543, 0.0181688255259165, 0.0538821352554514, 0.117259031001522, ...
0.193077037062548, 0.266434471781847, 0.325746362482833, 0.365146728802310, 0.386958383047475, ...
0.403635741471857, 0.432215334550296, 0.485674792559743, 0.567693518475570, 0.668583592821924, ...
0.768926132246355, 0.859501365700179, 0.933719545040531, 0.980404014586848, 1, 0.995168235818486, ...
0.968831382298403, 0.918925456426510, 0.840263581309774, 0.730217907888984, 0.593965562217998, ...
0.445252129988812, 0.302478487418430, 0.182455631766952, 0.0946623004432102, 0.0395136730456252, ...
0.0110944993303772, 0.00304918005164052, 0.000176066405779416, 0.000271107188644644];
yR_out = [0.141149758427413, 0.327528725181928, 0.531429476303118, 0.734825800245580, 0.905142105752982, ...
1, 0.994585150172040, 0.897227892811480, 0.737878031509986, 0.553911757285727, 0.378467001536220, ...
0.235489445927972, 0.136533896783523, 0.0811622468252899, 0.0597202443876324, 0.0577324907072722, ...
0.0649847546602922, 0.0739253772095743, 0.0770973088912625, 0.0732042102857309, 0.0642224578204625, ...
0.0538581912412821, 0.0446084800059044, 0.0369556660640144, 0.0301643235397618, 0.0235320482975639, ...
0.0170281463058672, 0.0111839380638397, 0.00660341791973352, 0.00352225498991166, 0.00174404920373791, ...
0.000833106531219361, 0.000466707400714911, 0.000321368144365539, 0.000238498897310069, 0.000187001782051892, ...
0.000152087422572435, 0.000120039487163363];
Upvotes: 1
Views: 131
Reputation: 4657
The best peak equation that I could find for both data sets was a power law with exponential cutoff equation, "y = C * pow(x, -1.0 * T) * exp(-1.0 * x / K)", see plots for both data sets below, and note the difference in the x axis scales.
For the "in" data, parameters are:
C = 3.7599874401256059E+00
T = -1.4597138492114836E+00
K = 7.5655555953645282E-01
yielding R-squared = 0.0.989 and RMSE = 0.037
The "out" data has both a sharper peak, and a "bump" at the bottom of the sharp peak that no individual peak function can model - effectively, this has a single large peak plus a much smaller and less sharp second peak.
For the "out" data, parameters are:
C = 7.5124684986001625E+01
T = -4.9620437310832193E+00
K = 2.2970202935383399E-01
yielding R-squared = 0.984 and RMSE = 0.045
Upvotes: 1