8

我正在尝试在 MATLAB 中计算修改后的第二类 Bessel 函数的对数,即类似的东西:

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)))'));

但是,我收到以下错误:

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

sym/double 错误(第 514 行) Xstr = mupadmex('symobj::double', Ss, 0)`;

我怎样才能避免这个错误?

4

3 回答 3

5

你做错了一些事情。double将两个参数用于 tobesselk并将输出转换为符号是没有意义的。您还应该避免使用旧的基于字符串的输入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}))

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

于 2015-09-09T19:35:45.663 回答
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。因此,对于 nu >= 750 和 z=1,至少 5 个有效数字是正确的!如果这对您来说足够好,这将比符号数学快得多。

于 2015-09-09T18:54:58.863 回答
0

您是否尝试过积分表示?

对数[积分[Cosh[Nut]/E^(Z Cosh[t]), {t, 0, Infinity}]]

于 2015-09-09T17:13:37.640 回答