为什么 mpmath 在相同精度上比 gsl 慢?哪些结果是正确的?

Why mpmath slower than gsl on the same precision? And Which results are right?

我简单测试了mpmath and gsl的子句功能。代码如下:

mp.prec = 53
time_begin = time.time()
print "mpmath results:"
print clsin(2,3.1415926535897327)
print "time1:"
print (time.time() - time_begin)
time_begin = time.time()
print "gsl results:"
print gsl_sf_clausen(3.1415926535897327)
print "time2"
print (time.time() - time_begin)

结果如下:

mpmath results:
4.19482951966115e-14
time1:
0.00391387939453
gsl results:
4.18544219761e-14
time2
2.69412994385e-05

从我查到的相同精度的结果来看,结果相差很大(mpmath:4.19... but gsl:4.18...),我想知道哪个更准确? 而mpmath在相同精度下比gsl_sf_clausen慢100多倍,为什么?

谢谢

您可能知道,克劳森函数在 x = pi 时恰好为 0。你给它提供了一个非常接近 pi 的数字。根据克劳森函数的评估实现方式,此时的计算可能涉及 loss of significance,因为项几乎完全取消。

据推测,gsl 和 mpmath 没有相同的克劳森函数实现,因此它们的 运行宁时间和输出不同。这并不罕见。即使对于求逆矩阵这样看似简单的事情,您有时也会遇到不同的程序包返回不同的结果,同时以相同的精度级别运行。

Wolfram Alpha returns 4.19620646966946940430...e-14,更接近mpmath值。如果精度提高,mpmath 本身将与 WolframAlpha 一致。

>>> mp.dps = 25
>>> clsin(2, mpf('3.1415926535897327'))
mpf('4.196206469668926047718406898e-14')

这让我们想到了另一点:mpmath 旨在处理任何给定精度的浮点数,而 gsl 似乎使用双精度浮点数(我真的不知道它内部)。因此,mpmath 的算法在设计时考虑到可能需要非常高的准确性,因此花费更长的时间到 运行 也就不足为奇了。