Error using integral; First input argument must be a function handle.

5 views (last 30 days)
I am trying to fit my equation using the modelE which is the sum of two functions exciton and continum. Continum is the integral of function cont. I am having error while using matlab inbuilt integral function. Can someone guide me where I am messing up on this code?
A=xlsread('Data');
xdata=1240./A(:,1);
ydata=A(:,2);
plot(xdata,ydata,'r.','markersize',30)
box on
energy=xdata;
Absorption=ydata;
options =optimoptions(@lsqcurvefit,'Algorithm','trust-region-reflective',...
'StepTolerance',1e-19,'MaxFunctionEvaluations',1e10, ...
'MaxIterations',1e3)
options =
lsqcurvefit options: Options used by current Algorithm ('trust-region-reflective'): (Other available algorithms: 'levenberg-marquardt') Set properties: Algorithm: 'trust-region-reflective' MaxFunctionEvaluations: 1.0000e+10 MaxIterations: 1000 StepTolerance: 1.0000e-19 Default properties: CheckGradients: 0 Display: 'final' FiniteDifferenceStepSize: 'sqrt(eps)' FiniteDifferenceType: 'forward' FunctionTolerance: 1.0000e-06 JacobianMultiplyFcn: [] OptimalityTolerance: 1.0000e-06 OutputFcn: [] PlotFcn: [] SpecifyObjectiveGradient: 0 SubproblemAlgorithm: 'factorization' TypicalX: 'ones(numberOfVariables,1)' UseParallel: 0
var=[0.0529 2.3926 0.0307 1.002];
MI=lsqcurvefit(@modelE,var,energy,Absorption,[],[],options);
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.
fitdata=modelE(MI,energy);
hold on
plot(energy,modelE(var,energy),'co')
Warning: Imaginary parts of complex X and/or Y arguments ignored.
plot(energy,exciton(var,energy),'m.','markersize',30)
plot(energy, continum(var,energy),'k.')
Error using integral
First input argument must be a function handle.

Error in solution>continum (line 40)
z = integral(cont(var,energy),2.39,inf);
function alpha = modelE(var,energy)
alpha = cont(var,energy) +var(2).* exciton(var,energy);
end
function x= exciton(var,energy)
x= 2.*var(1).*sech((energy-var(2)+var(1))./var(3))+...
0.125.*var(1).*sech((energy-var(2)+(var(1)./8))./var(3))+...
(2/27).*var(1).*sech((energy-var(2)+(var(1)./27))./var(3));
end
function y= cont(var,energy)
y=(sech((energy-var(2))./var(3))).*(1./(1-exp(-2.*pi.*sqrt(var(1)./(energy-var(2)))))).*(1./(1-(var(4).*energy-var(2))));
end
function z= continum(var,energy)
z = integral(cont(var,energy),2.39,inf);
end
  2 Comments
Bibek Dhami
Bibek Dhami on 30 Jun 2022
@Torsten I had typo in my integral, so I was getting the constant value. Actually the integral should be not over energy.
But now I am having some issue with the curve fitting. I am using lower and upper bound to restrict the values but I am getting following error.
Lower and upper bounds not supported with complex-valued initial
A=xlsread('Data');
xdata=1240./A(:,1);
ydata=A(:,2);
plot(xdata,ydata,'r.','markersize',30)
box on
energy=xdata;
Absorption=ydata;
options =optimoptions(@lsqcurvefit,'Algorithm','levenberg-marquardt',...
'StepTolerance',1e-19,'MaxFunctionEvaluations',1e10, ...
'MaxIterations',1e3);
lb=[0.03, 2.35, 0.02, 2];
ub=[0.09, 2.40, 0.05, 5];
var=[0.0429 2.3776 0.0207 2.902];
MI=lsqcurvefit(@modelE,var,energy,Absorption,lb,ub,options);
fitdata=modelE(MI,energy);
hold on
% plot(energy,modelE(var,energy),'co')
% plot(energy,exciton(var,energy),'m.','markersize',30)
% plot(energy, continum(var,energy),'k.')
plot(energy,fitdata,'ro')
plot(energy,exciton(MI,energy),'g.','markersize',30)
plot(energy, continum(MI,energy),'b.')
function alpha = modelE(var,energy)
alpha = continum(var,energy) + exciton(var,energy);
end
function x= exciton(var,energy)
x= 2.*var(1).*sech((energy-var(2)+var(1))./var(3))+...
0.125.*var(1).*sech((energy-var(2)+(var(1)./8))./var(3))+...
(2/27).*var(1).*sech((energy-var(2)+(var(1)./27))./var(3));
end
function y= cont(var,energy,x)
y=(sech((energy-x)./var(3))).*(1./(1-exp(-2.*pi.*sqrt(var(1)./(x-var(2)))))).*(1./(1-(var(4).*(x-var(2)))));
end
function z= continum(var,energy)
z = integral(@(x)cont(var,energy,x),2.25,200,'ArrayValued',true);
end
Torsten
Torsten on 30 Jun 2022
During the integration in "continuum", the expression
var(1)./(x-var(2))
becomes or is negative and thus
sqrt(var(1)./(x-var(2)))
becomes complex-valued.
This makes MATLAB's "lsqcurvefit" throw an error and stop.

Sign in to comment.

Answers (1)

Torsten
Torsten on 28 Jun 2022
function z= continum(var,energy)
z = integral(@(x)cont(var,x),2.39,inf);
end
  2 Comments
Bibek Dhami
Bibek Dhami on 28 Jun 2022
Edited: Bibek Dhami on 28 Jun 2022
@Torsten Thank you so much it works. But I am having another issue. The plot of this function should give us something like this but it is just giving a line parallel to x axis.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!