对于非常小的x,计算1/tanh(x)1/x

2024-04-24 04:24:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要计算数量

1/tanh(x) - 1/x

对于x > 0,其中{}既可以非常小也可以非常大。在

对于小x,我们有

^{pr2}$

对于大的x

^{3}$

不管怎样,在计算表达式时,已经从10^-7和更小的舍入错误会导致表达式被精确地计算为0:

import numpy
import matplotlib.pyplot as plt


x = numpy.array([2**k for k in range(-30, 30)])
y = 1.0 / numpy.tanh(x) - 1.0 / x

plt.loglog(x, y)
plt.show()

enter image description here


Tags: inimportnumpyfor数量matplotlib表达式as
3条回答

对于非常小的x,可以使用the Taylor expansion of ^{} around ^{}

y = x/3.0 - x**3 / 45.0 + 2.0/945.0 * x**5

误差为O(x**7)级,因此如果选择10^-5作为断点,相对和绝对误差将远低于机器精度。在

^{pr2}$

enter image description here

使用python包^{}可获得任意十进制精度。例如:

import mpmath
from mpmath import mpf

mpmath.mp.dps = 100 # set decimal precision

x = mpf('1e-20')

print (mpf('1') / mpmath.tanh(x)) - (mpf('1') / x)
>>> 0.000000000000000000003333333333333333333333333333333333333333311111111111111111111946629156220629025294373160489201095913

它变得非常精确。在

查看^{} plottingmpmath与您正在使用的matplotlib配合得很好,因此这应该可以解决您的问题。在


下面是一个如何将mpmath集成到您上面编写的代码中的示例:

^{pr2}$

enter image description here

一个可能更简单的解决方案是更改numpy运行时的数据类型:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-30, 30, dtype=np.longdouble)
x = 2**x
y = 1.0 / np.tanh(x) - 1.0 / x

plt.loglog(x, y)
plt.show()

使用longdouble作为数据类型确实可以在没有舍入错误的情况下给出正确的解决方案。在


我确实修改了你的例子,在你的例子中,你唯一需要修改的是:

^{pr2}$

收件人:

x = numpy.array([2**k for k in range(-30, 30)], dtype=numpy.longdouble)

相关问题 更多 >