0
>>> from scipy.special import erf
>>> print (erf(0.j))
__main__:1: RuntimeWarning: invalid value encountered in erf
0j

这个警告只打印一次(即使我这样做scipy.special.errprint(0)了),但我不明白为什么要打印它。真的,0.j是相同的数字0.,它没有问题。

我想有两个问题:1)有没有办法抑制这个警告?2)这个警告是一个错误,还是我错过了什么?

更新

我(想我)在 scipy 源代码树中追踪了错误函数。它位于:scipy/special/specfun/specfun.f( subroutine CERROR)。此函数不会引发警告(从简单的 fortran 程序调用时它工作正常)。

4

1 回答 1

1

您可以使用以下命令关闭警告numpy.seterr

    numpy.seterr(invalid='ignore')

0.j不一样0.。前者是一个复数,后者只是一个浮点数。

>>> type(0.j)
<class 'complex'>
>>> type(0.)
<class 'float'>

复数 erf 和实数 erf 使用不同的算法,例如

>>> erf(complex(1))
(0.84270079294971512+0j)
>>> erf(1)
0.84270079294971478

由于真实erf和复数erf使用不同的算法,所以复数erf中的一些警告不会出现在真实erf中。如果我们检查Fortran 实现,我们会发现:

    SUBROUTINE CERROR(Z,CER)
C   ...
    Z1=Z
C   ...
    CS=Z1
    CR=Z1
    DO 10 K=1,120
        CR=CR*Z1*Z1/(K+0.5D0)
        CS=CS+CR
        IF (CDABS(CR/CS).LT.1.0D-15) GO TO 15
10  CONTINUE

特别是Z = 0 + 0j,所以Z1 = 0 + 0j,所以循环前CS = CR = 0 + 0j。在循环的第一次迭代中,我们得到:

  • CR ← CR × Z1 2 / (K + 0.5) = 0 + 0j
  • CS ← CS + CR = 0 + 0j

然后条件需要CR/CS,这是一个0/0,这是一个无效的浮点运算,因此是警告。

这是一个小问题,可以通过在开头检查 Z == 0 来轻松“修复”。如果您发现此行为不稳定,您可以报告错误。

于 2012-07-12T14:01:17.020 回答