Syntax problems when passing numerical integral into lsqcurvefit
3 views (last 30 days)
Show older comments
I am trying to fit an function which cannot be evaluated analytically. My script consists of a multitude of steps. (MATLAB 2013b)
Initalisation, 71024.mat contains among other variables V3 and Gzoomin:
clear all
close all
clc
filename='71024';
load(strcat(filename,'.mat'))
clc
syms V E
x = sym('x',[3,1]);
kB=1.38e-23;
delta1=200e-6;
T=.270;
xdata=V3(1:end-1);
ydata=Gzoomin;
Cn=1;
delta2=200e-6;
gamma2=10e-6;
As a second step, I want to evaluate this derivative analytically, and then turn it into a function handle.
Fun1 = x(1)*real(abs(E)/sqrt(E^2-delta1^2))*(diff(real((E+V-1i*x(3))/sqrt((E+V-1i*x(3))^2-x(2)^2)),V)*(1/(exp(E/(kB*T))+1)-1/(exp((E+V)/(kB*T))+1))-real((E+V-1i*x(3))/sqrt((E+V-1i*x(3))^2-x(2)^2))*diff(1/(exp((E+V)/(kB*T))+1),V));
Fun2 = matlabFunction (Fun1);
So far it's all fine. Fun2 depends on the following variables: E,V,x1,x2,x3 In the next step I want to integrate over E for given V,x1,x2,x3. V corresponds to xdata, x1,x2,x3 are the fit parameters. Note that this function can not be integrated analytically.
x0=[Cn delta2 gamma2];
x= lsqcurvefit(integral(@(E)Fun2,-Inf,Inf), x0,xdata, ydata);
This gives the following error:
Error using integralCalc/finalInputChecks (line 512)
Input function must return 'double' or 'single' values. Found 'function_handle'.
Error in integralCalc/iterateScalarValued (line 316)
finalInputChecks(x,fx);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 104)
[q,errbnd] = vadapt(@minusInfToInfInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
How can i solve this problem? Thank you in advance.
0 Comments
Answers (1)
Walter Roberson
on 29 May 2015
What you pass to be fitted needs to be a function. You are passing integral() of something, so you are expecting integral() to return a function. But integral() is a numeric integrator and cannot return a function. You need another layer which does symbolic integration and does a matlabFunction() on that result.
I did see your remark about the integral not being analytic. I do not have the symbolic toolbox so I do not know whether it is able to convert unevaluated integrals into numeric integrals.
Now as to why integral() is what complained: you tried to use
integral(@(E)Fun2,-Inf,Inf)
@(E)Fun2 designates an anonymous function that expects one input argument and ignores that argument and always returns Fun2. But Fun2 is a function handle. If you want to evaluate Fun2 at a specific value then you need to pass in the appropriate parameters, such as
integral(@(E)Fun2(E,xdata,x1,x2,x3),-Inf,Inf)
Here, x1, x2, x3 need to have some value. In the general case, it does not matter what data type (numeric, symbolic, cell, struct) gets passed in: integral() doesn't care. But the function called upon (Fun2) needs to be able to process whatever is passed in, in a way that results in that function returning a specific numeric result for integral() to process. And there you have a problem, as you want the integral to return a formula so you can fit it.
So... you write something like
helper = @(x,xdata) integral(@(E) Fun2(E,xdata,x(1),x(2),x(3)),-Inf,Inf);
x = lsqcurvefit(helper, x0, xdata, ydata);
and there, you are passing in a function handle to lsqcurvefit(), not an integral. The function handle takes the given parameter and does a specific integral with them, returning the numeric result that will be matched against ydata.
Note: This particular formulation will fail if your ydata is not a scalar! It also assumes that xdata as a whole needs to be passed to the integral. If your setup were that you wanted each row of xdata to correspond to one value in the column vector ydata, then this code would need to be adjusted.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!