【问题标题】:RuntimeWarning: overflow encountered in cosh -- Python. What does this mean?RuntimeWarning: 在 cosh -- Python 中遇到溢出。这是什么意思?
【发布时间】:2021-10-15 21:43:37
【问题描述】:

我正在运行以下计算:

N = 2**15
dx = 0.1
x = np.arange(-N/2,N/2)
u0 = np.zeros([N, 1])
L = N * dx
x0 = x[1] + 2 * delta
delta = 15

while x0 < L - delta:

    l1 = 1.267;
    x0 = x0 + delta
    r = 1/(l1*np.cosh(x)**2)
    u0 = r + u0

基本上,当 x0

这可以很好地翻译成 MATLAB,但是 python 给了我这个错误:

RuntimeWarning:在 cosh 中遇到溢出
r = 1/(l1*np.cosh(x)**2)

【问题讨论】:

  • 你为什么要一遍遍地计算1/(l1*np.cosh(x)**2)?表达式中的所有变量都不会在循环过程中改变它们的值。同样,您也不需要在循环中定义l1
  • 嗯...您认为合适的替代方案是什么?
  • 好吧......不要这样做。把它放在循环之外。
  • 这似乎并没有阻止错误:(

标签: python numpy runtime-error hyperbolic-function


【解决方案1】:

cosh 变得非常大:

In [70]: np.cosh(2**10)
<ipython-input-70-c4511154ec1e>:1: RuntimeWarning: overflow encountered in cosh
  np.cosh(2**10)
Out[70]: inf

为什么你的x 这么宽?对于大部分范围,cosh 的倒数将为 0。

In [72]: N=2**15; x = np.arange(-N/2,N/2)
In [73]: len(x)
Out[73]: 32768
In [74]: r = 1/(np.cosh(x)**2)
<ipython-input-74-404fbe3be390>:1: RuntimeWarning: overflow encountered in cosh
  r = 1/(np.cosh(x)**2)
<ipython-input-74-404fbe3be390>:1: RuntimeWarning: overflow encountered in square
  r = 1/(np.cosh(x)**2)
In [75]: r[:10]
Out[75]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

In [77]: np.sum(r<1e-16)
Out[77]: 32729

查看x 的 +-20 范围

In [88]: x = np.arange(-20,20)
In [89]: r = 1/(np.cosh(x)**2)
In [90]: r
Out[90]: 
array([1.69934170e-17, 1.25565312e-16, 9.27809132e-16, 6.85563373e-15,
       5.06566622e-14, 3.74304919e-13, 2.76576004e-12, 2.04363561e-11,
      ...
       1.00000000e+00, 4.19974342e-01, 7.06508249e-02, 9.86603717e-03,
       ...
       1.51005382e-10, 2.04363561e-11, 2.76576004e-12, 3.74304919e-13,
       5.06566622e-14, 6.85563373e-15, 9.27809132e-16, 1.25565312e-16])

抑制警告

In [148]: x=np.array([-2**15,-2**4,0,2**4,2**15])

In [155]: np.cosh(x)
<ipython-input-155-1e743139b88e>:1: RuntimeWarning: overflow encountered in cosh
  np.cosh(x)
Out[155]: 
array([           inf, 4.44305526e+06, 1.00000000e+00, 4.44305526e+06,
                  inf])
In [156]: 1/(np.cosh(x)**2)
<ipython-input-156-5cf76600c0c7>:1: RuntimeWarning: overflow encountered in cosh
  1/(np.cosh(x)**2)
Out[156]: 
array([0.00000000e+00, 5.06566622e-14, 1.00000000e+00, 5.06566622e-14,
       0.00000000e+00])

警告不会阻止您获得有用的值。这是警告,而不是错误

但可以抑制警告。在路上是errstate

In [157]: with np.errstate(over='ignore'):
     ...:     y = 1/(np.cosh(x)**2)
     ...: 
In [158]: y
Out[158]: 
array([0.00000000e+00, 5.06566622e-14, 1.00000000e+00, 5.06566622e-14,
       0.00000000e+00])

np.seterr 也可以使用,但它会改变整个脚本的处理,而不仅仅是这个上下文。所以with np.errstate是首选。

请务必花时间阅读文档。

In [159]: np.geterr()
Out[159]: {'divide': 'warn', 'over': 'warn', 'under': 'ignore', 'invalid': 'warn'}

还有一个warnings模块

Why can't I suppress numpy warnings

【讨论】:

  • 有什么办法可以避免这种情况吗?
  • 不要让你的x 这么大!
  • 即使在八度音阶中 cosh(2**10) 也会提供 inf。它可能不会给出警告,但值仍然很大。
  • 我认为它与this有关。我只是对代码应该在 matlab 中工作感到困惑。
  • 它在numpy 中确实有效,但它只是给了我们警告。这是警告,而不是错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多