Hi everyone,
I struggle with fitting my measured data to an integral function. I already tried this with the curve fitting toolbox and "lsqnonlin" from the Optimization Toolbox.
Let's say I have the following data set:
x = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];
y = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];
I want to fit the the following equation to the data set:
y =
where a,b,c,d are the coeffients to fit. i think my problem is the integration part of the fitting function
I tried different approaches.
1) With Curve Fitting Toolbox
%% data set
x = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];y = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];plot(x,y,'x'); fun= @(a,b,c,d,x) 1/2/x*(integral(b * (log(1 + a/b * (exp(x/c) - 1))) *exp(-x/d) * (1/(x/c)), 0, 2*x));g = fittype('(1/2/x*integral(b * (log(1 + a/b * (exp(x/c) - 1))) *exp(-x/d) * (1/(x/c)), 0, 2*x))',... 'dependent', {'y'},'independent', {'x'}, 'coefficients', {'a','b','c','d'}); [fitobject,gof] = fit(x, y, g);
Thats the error message:
Error using fittype/testCustomModelEvaluation (line 12)
Expression (integral(b * (log(1 + a/b * (exp(x/c) – 1))) *exp(-x/d) * (1/(x/c)), 0, 2*x)) is not a valid MATLAB expression, has non-scalar
coefficients, or cannot be evaluated:
Error in fittype expression ==> (integral(b .* (log(1 + a./b .* (exp(x./c) – 1))) .*exp(-x./d) .* (1./(x./c)), 0, 2.*x))
??? First input argument must be a function handle.
[…]
2) "lsqnonlin"-approach
xdata = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];ydata = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];plot(xdata,ydata,'x'); fun= @(x,xdata) 1/2/xdata*(integral(x(2) * (log(1 + x(1)/x(2) * (exp(xdata/x(3)) - 1))) *exp(-xdata/x(4)) * (1/(xdata/x(3))), 0, 2*xdata)) - ydata;x0 = [0.65, 0.8, 8, 100000];x = lsqnonlin(fun, x0);
Error message:
Not enough input arguments.
Error in try2>@(x,xdata)1/2/xdata*(integral(x(2)*(log(1+x(1)/x(2)*(exp(xdata/x(3))-1)))*exp(-xdata/x(4))*(1/(xdata/x(3))),0,2*xdata))-ydata
Error in lsqnonlin (line 196)
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Error in try2 (line 18)
x = lsqnonlin(fun, x0);
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
Another way I tried first was this, where I solve the problem with a loop and simply guess the parameters:
xdata = [228.1194 179.7485 149.5914 121.6736 91.7255 60.6427 40.8913 23.9615 14.4217 11.9658 9.7682 7.4930 5.4940 3.8771 2.6096];ydata = [0.7440 0.7349 0.7276 0.7049 0.6939 0.6607 0.6417 0.6069 0.5868 0.5818 0.5781 0.5748 0.5704 0.5606 0.5611];plot(xdata,ydata,'x'); hold onx = [0.558, 0.78, 25, 100000];fun = @(xdata) (x(2) .* (log(1 + x(1)./x(2) .* (exp(xdata./x(3)) - 1))) .* exp(-xdata./x(4)) .* (1./(xdata./x(3))));for i=1:length(xdata) y_fit(i) = integral(fun, 0, 2*xdata(i)); y_fit2(i) = 1/(2*xdata(i)) *y_fit(i); endplot(xdata,y_fit2,'o');
I found some similar questions in the forum but I wasn't able to adapt these to my case. I'm very thankful for any tip / hint.
Thanks in advance
Best Answer