贝塞尔函数的自然对数,溢出

时间:2015-09-09 16:21:03

标签: algorithm matlab math bessel-functions

我试图在MATLAB中计算第二类修改贝塞尔函数的对数,即类似:

log(besselk(nu, Z)) 

例如

nu = 750;
Z = 1;

我遇到问题,因为log(besselk(nu, Z))的值变为无穷大,因为besselk(nu, Z)是无穷大。但是,log(besselk(nu, Z))确实应该很小。

我正在尝试写一些类似

的内容
f = double(sym('ln(besselk(double(nu), double(Z)))'));

但是,我收到以下错误:

  

在MuPAD命令中使用mupadmex时出错:DOUBLE无法将输入表达式转换为double数组。如果输入表达式包含符号变量,请改用VPA函数。

     

sym / double中的错误(第514行)Xstr = mupadmex(' symobj :: double',S.s,0)`;

如何避免此错误?

3 个答案:

答案 0 :(得分:5)

你做错了一些事情。将double用于besselk的两个参数并将输出转换为符号是没有意义的。您还应该避免使用基于字符串的旧输入sym。相反,您希望以符号方式评估besselk(将返回大约1.02×10 2055 ,远大于realmax),以符号方式记录结果的日志,然后转换回到双精度。

以下就足够了 - 当一个或多个输入参数是符号时,将使用besselk的符号版本:

f = double(log(besselk(sym(750), sym(1))))

或旧的字符串形式:

f = double(sym('log(besselk(750, 1))'))

如果您想让您的参数符号化并在以后评估:

syms nu Z;
f = log(besselk(nu, Z))
double(subs(f, {nu, Z}, {750, 1}))

请确保您没有翻转数学中的nuZ值,因为大订单(nu)并不常见。

答案 1 :(得分:4)

正如njuffa指出的那样,DLMF为大nu提供了K_nu(z)的渐近展开式。从10.41.2开始,我们找到了真实的正面论证z:

besselk(nu,z) ~ sqrt(pi/(2nu)) (e z/(2nu))^-nu

经过一些简化后给出了

log( besselk(nu,z) ) ~ 1/2*log(pi) + (nu-1/2)*log(2nu) - nu(1 + log(z))

所以它是O(nu log(nu))。毫无疑问,nu的直接计算失败了。 750。

我不知道这种近似是多么准确。也许您可以将besselk小于数值无穷大的值进行比较,看它是否符合您的目的?

编辑:我刚试过nu = 750和z = 1:上面的近似给出了4.7318e + 03,而有了horchler的结果我们得到了log(1.02 * 10 ^ 2055)= 2055 * log(10)+ log(1.02)= 4.7318e + 03。因此对于至少5个有效数字是正确的,因为nu> = 750且z = 1!如果这对你来说足够好,那么它将比符号数学快得多。

答案 2 :(得分:0)

您是否尝试过积分表示法?

  
    

Log [Integrate [Cosh [Nu t] / E ^(Z Cosh [t]),{t,0,Infinity}]]