Mpmath 超几何函数显示出高精度和低精度的不同行为
Mpmath hypergeometric function shows different behaviour for high & low precision
对于我的一个项目,我需要反复计算涉及一般超几何函数的表达式。虽然 SciPy 不支持一般的 HypGeo 函数,但 MPMath 支持。但是,使用 mp.hyper(..)
非常耗时。因此,我决定使用他们的快速精度库函数 fp.hyper(..)
。不幸的是,行为似乎完全不同。我的例子如下:
from mpmath import mp, fp
from math import sin, cos, pi
H = 0.2
k = 2
A = 4 * sqrt(H) / (1 + 2 * H)
B = 4 * pi / (3 + 2 * H)
C = H/2 + 3/4
f_high = lambda t: (B * k * t * sin(pi * k) *
mp.hyper([1], [C+1/2, C+1], -(k*pi*t)**2) +
cos(pi * k) * mp.hyper([1], [C, C + 1/2],
-(k*pi*t)**2)) * A * t**(H + 1/2)
f_low = lambda t: (B * k * t * sin(pi * k) *
fp.hyper([1], [C+1/2, C+1], -(k*pi*t)**2) +
cos(pi * k) * fp.hyper([1], [C, C + 1/2],
-(k*pi*t)**2)) * A * t**(H + 1/2)
第一个图显示fp.plot(f_high,[0,1])
,第二个图显示fp.plot(f_low,[0,1])
。如果有人想知道:这些函数看起来很丑,但一个是另一个的副本,只是 mp
被 fp
替换了,所以它们不可能有任何其他差异。
我也是用Mathematica画的,图更像上图(精度高)
看起来fp.hyper
函数的实现有错误,对吧?
fp
的 documentation 说(强调):
Due to intermediate rounding and cancellation errors, results computed with fp arithmetic may be much less accurate than those computed with mp using an equivalent precision (mp.prec = 53), since the latter often uses increased internal precision. The accuracy is highly problem-dependent: for some functions, fp almost always gives 14-15 correct digits; for others, results can be accurate to only 2-3 digits or even completely wrong. The recommended use for fp is therefore to speed up large-scale computations where accuracy can be verified in advance on a subset of the input set, or where results can be verified afterwards.
如果 fp
只是 mp
的临时替代品,具有更快的计算速度且没有任何缺点,那么 mp
就没有存在的理由。在这种情况下,fp
似乎不适合您的任务,因此您必须使用 mp
.
对于我的一个项目,我需要反复计算涉及一般超几何函数的表达式。虽然 SciPy 不支持一般的 HypGeo 函数,但 MPMath 支持。但是,使用 mp.hyper(..)
非常耗时。因此,我决定使用他们的快速精度库函数 fp.hyper(..)
。不幸的是,行为似乎完全不同。我的例子如下:
from mpmath import mp, fp
from math import sin, cos, pi
H = 0.2
k = 2
A = 4 * sqrt(H) / (1 + 2 * H)
B = 4 * pi / (3 + 2 * H)
C = H/2 + 3/4
f_high = lambda t: (B * k * t * sin(pi * k) *
mp.hyper([1], [C+1/2, C+1], -(k*pi*t)**2) +
cos(pi * k) * mp.hyper([1], [C, C + 1/2],
-(k*pi*t)**2)) * A * t**(H + 1/2)
f_low = lambda t: (B * k * t * sin(pi * k) *
fp.hyper([1], [C+1/2, C+1], -(k*pi*t)**2) +
cos(pi * k) * fp.hyper([1], [C, C + 1/2],
-(k*pi*t)**2)) * A * t**(H + 1/2)
第一个图显示fp.plot(f_high,[0,1])
,第二个图显示fp.plot(f_low,[0,1])
。如果有人想知道:这些函数看起来很丑,但一个是另一个的副本,只是 mp
被 fp
替换了,所以它们不可能有任何其他差异。
我也是用Mathematica画的,图更像上图(精度高)
看起来fp.hyper
函数的实现有错误,对吧?
fp
的 documentation 说(强调):
Due to intermediate rounding and cancellation errors, results computed with fp arithmetic may be much less accurate than those computed with mp using an equivalent precision (mp.prec = 53), since the latter often uses increased internal precision. The accuracy is highly problem-dependent: for some functions, fp almost always gives 14-15 correct digits; for others, results can be accurate to only 2-3 digits or even completely wrong. The recommended use for fp is therefore to speed up large-scale computations where accuracy can be verified in advance on a subset of the input set, or where results can be verified afterwards.
如果 fp
只是 mp
的临时替代品,具有更快的计算速度且没有任何缺点,那么 mp
就没有存在的理由。在这种情况下,fp
似乎不适合您的任务,因此您必须使用 mp
.