我有一些代码,它使用了修改后的一阶和二阶贝塞尔函数(iv和kv)。令人恼火的是,它们似乎有极限,即iv(0,713)和kv(0,697),每个加1,你就分别得到无穷大和0。这对我来说是一个问题,因为我需要使用比这个更高的值,通常高达2000或更多。当我尝试除以这些时,我最终除以0或无穷大,这意味着我要么得到错误,要么得到零,这两个我都不想要。
我正在使用scipy bessel functions,有没有更好的函数可以处理更小和更大的数字,或者修改Python来处理这些大数字。我不确定真正的问题是什么,为什么Python不能在超过700的情况下解决这些问题,是函数还是Python?
我不知道Python是否已经在这么做了,但我只需要前5-10位数字*例如10^x;也就是说我不需要所有的1000位数字,也许这就是Python如何解决它与Wolfram Alpha如何解决它的问题?
发布于 2012-12-06 00:56:13
如果使用双精度机器浮点,Scipy中的iv
和kv
函数或多或少是最好的。正如在上面的注释中所指出的,您正在从浮点范围溢出结果的范围中工作。
您可以使用mpmath
库来解决这个问题,该库实现了可调精度(软件)浮点运算。(它类似于MPFR,但在Python中):
In [1]: import mpmath
In [2]: mpmath.besseli(0, 1714)
mpf('2.3156788070459683e+742')
In [3]: mpmath.besselk(0, 1714)
mpf('1.2597398974570405e-746')
发布于 2018-06-16 05:34:21
您可以使用指数级扩展的修改过的Bessel函数直接执行此操作,该函数不会溢出。它们被实现为special.ive
和special.kve
。例如,修改后的第一类贝塞尔函数special.iv(0, 1714)
将溢出。但是,只要你没有记录已经溢出的东西,它的对数就会被很好地定义:
In [1]: import numpy as np
In [2]: from scipy import special
In [3]: np.log(special.iv(0, 1714))
Out[3]: inf
In [4]: np.log(special.kv(0, 1714))
Out[4]: -inf
In [5]: np.log(special.ive(0, 1714)) + 1714
Out[5]: 1709.3578418673253
In [6]: np.log(special.kve(0, 1714)) - 1714
Out[6]: -1717.4975741044941
其他容易溢出的函数也可以作为日志或扩展版本使用。
发布于 2015-01-20 17:58:21
可能是函数有问题。对于大的正x,对任意nu存在渐近的kv(nu,x) ~ e^{-x}/\sqrt{x}。所以对于很大的x,你最终得到了非常小的值。如果您能够使用Bessel函数的日志,问题将会消失。Scilab利用了这个渐近性:它有一个默认为0的参数ice,但当设置为1时,将返回exp(x)*kv(nu,x),这将使所有内容保持合理的大小。
实际上,在scipy - scipy.special.kve中也提供了同样的功能
https://stackoverflow.com/questions/13726464
复制相似问题