MATLAB奇异误差伽马函数数值积分

MATLAB奇异误差伽马函数数值积分,matlab,error-handling,gamma-function,Matlab,Error Handling,Gamma Function,为了进行数值积分,我尝试运行以下程序: nu = 8; psi=-0.2; lambda = 1; git = @(u) tpdf((0 - lambda * skewtdis_inverse(u, nu, psi)), nu); g(t,i) = integral(git,1e-10,1-1e-10,'AbsTol',1e-16); 其中,tpdf是一个matlab函数,skewtdis:inverse如下所示: function inv = skewtdis_inverse(u, nu,

为了进行数值积分,我尝试运行以下程序:

nu = 8; 
psi=-0.2;
lambda = 1;
git = @(u) tpdf((0 - lambda * skewtdis_inverse(u, nu, psi)), nu);
g(t,i) = integral(git,1e-10,1-1e-10,'AbsTol',1e-16);
其中,tpdf是一个matlab函数,skewtdis:inverse如下所示:

function inv = skewtdis_inverse(u, nu, lambda)
% PURPOSE: returns the inverse cdf at u of Hansen's (1994) 'skewed t' distribution

c = gamma((nu+1)/2)/(sqrt(pi*(nu-2))*gamma(nu/2));
a = 4*lambda*c*((nu-2)/(nu-1));
b = sqrt(1 + 3*lambda^2 - a^2);

if (u<(1-lambda)/2);
inv = (1-lambda)/b*sqrt((nu-2)./nu)*tinv(u/(1-lambda),nu)-a/b;
elseif (u>=(1-lambda)/2);
inv = (1+lambda)/b*sqrt((nu-2)./nu).*tinv(0.5+1/(1+lambda)*(u-(1-lambda)/2),nu)-a/b;
end
函数inv=skewtdis\u逆(u,nu,lambda)
%目的:返回Hansen(1994)“歪斜t”分布u处的逆cdf
c=伽马((nu+1)/2)/(sqrt(pi*(nu-2))*伽马(nu/2));
a=4*lambda*c*((nu-2)/(nu-1));
b=sqrt(1+3*lambda^2-a^2);
如果(u=(1-lambda)/2);
inv=(1+lambda)/b*sqrt((nu-2)。/nu.*tinv(0.5+1/(1+lambda)*(u-(1-lambda)/2),nu)-a/b;
结束
我得到的是:

歪斜TDIS_倒数中的错误(第6行) c=伽马((nu+1)/2)/(sqrt(pi*(nu-2))*伽马(nu/2))

在调用“F:\Xyz\skewtdis\u inverse.m>skewtdis\u inverse”期间未指定输出参数“inv”(可能还有其他参数)

@(u)tpdf((0-lambda*skewtdis_逆(u,nu,psi))中的错误,nu)

integralCalc/IterateScalavalue中的错误(第314行) fx=乐趣(t)

integralCalc/vadapt中的错误(第133行) [q,errbnd]=迭代Calavaled(u,tinterval,pathlen)

积分计算错误(第76行) [q,errbnd]=vadapt(@AtoBInvTransform,interval)

积分误差(第89行) Q=积分计算器(fun、a、b、opstruct)

但是,如果我直接调用thr handle中的函数,则没有问题:

tpdf((0-lambda*skewtdis_倒数(1e-10,nu,psi)),nu)

ans=

1.4092e-11

tpdf((0-lambda*skewtdis_逆(1-1e-10,nu,psi)),nu)

ans=

7.0108e-10


非常感谢您的努力

默认情况下,
integral
希望函数句柄接受向量输入。 在您的代码中,
if
-语句会产生复杂的情况,因为只有当
u
的所有元素都满足该条件时,该条件才会计算为
true
。 因此,如果
u
是一个元素既大于又小于
(1-lambda)/2
的向量,则永远不会分配
inv

有两种选择:

  • if
    -语句放入
    for
    -循环中,并迭代
    u
    的所有元素
  • 为分配使用逻辑索引
  • 第二个选项对于较大的元素计数更快,并且在我看来更干净:

    inv = u; % Allocation
    
    IsBelow =  u <  (1-lambda)/2; % Below the threshold
    IsAbove =  ~IsBelow         ; % Above the threshold
    
    inv(IsBelow) = (1-lambda)/b*sqrt((nu-2)./nu)*tinv(u(IsBelow)/(1-lambda),nu)-a/b;
    inv(IsAbove) = (1+lambda)/b*sqrt((nu-2)./nu)*tinv(0.5+1/(1+lambda)*(u(IsAbove)-(1-lambda)/2),nu)-a/b;
    
    inv=u;%分配
    Isbellow=u<(1-lambda)/2;%低于阈值
    IsAbove=~IsBelow;%高于临界值
    inv(isbellow)=(1-lambda)/b*sqrt((nu-2)。/nu)*tinv(u(isbellow)/(1-lambda),nu)-a/b;
    inv(IsAbove)=(1+lambda)/b*sqrt((nu-2)。/nu)*tinv(0.5+1/(1+lambda)*(u(IsAbove)-(1-lambda)/2),nu)-a/b;
    
    先生,您的MATLAB知识令人印象深刻。非常感谢你!