Python scipy.special.erf使用0.j引发运行时警告
此警告仅打印一次(即使我执行了Python scipy.special.erf使用0.j引发运行时警告,python,algorithm,scipy,Python,Algorithm,Scipy,此警告仅打印一次(即使我执行了scipy.special.errprint(0)),但我完全不明白为什么要打印它。实际上,0.j是与0相同的数字。这个数字没有问题 我想有两个问题: 1) 有没有办法抑制此警告? 2) 这个警告是错误还是我遗漏了什么 更新 我(想我)在scipy源代码树中找到了错误函数。它位于:scipy/special/specfun/specfun.f(子程序CERROR)。此函数不会引发警告(从简单的fortran程序调用时工作正常)。您可以通过以下方式关闭警告: 0.j
scipy.special.errprint(0)
),但我完全不明白为什么要打印它。实际上,0.j
是与0相同的数字。
这个数字没有问题
我想有两个问题:
1) 有没有办法抑制此警告?
2) 这个警告是错误还是我遗漏了什么
更新
我(想我)在scipy源代码树中找到了错误函数。它位于:
scipy/special/specfun/specfun.f
(子程序CERROR
)。此函数不会引发警告(从简单的fortran程序调用时工作正常)。您可以通过以下方式关闭警告:
0.j
与0不同。
。前者是一个复数,后者只是一个浮点数
numpy.seterr(invalid='ignore')
由于实际erf和复杂erf使用不同的算法,因此复杂erf中的某些警告不会出现在实际erf中。如果我们检查,我们会发现:
>>> erf(complex(1))
(0.84270079294971512+0j)
>>> erf(1)
0.84270079294971478
特别是,在循环之前,Z=0+0j,所以Z1=0+0j,所以CS=CR=0+0j。在循环的第一次迭代中,我们得到:
- 铬← CR×Z12/(K+0.5)=0+0j
- CS← CS+CR=0+0j
这是一个小问题,可以通过在开始时检查Z==0轻松“修复”。如果您发现这种行为不稳定,您可能会发现。我知道,就python而言,它们是不同的数字。但从数学上讲,它们并没有什么不同。我的观点是如果0。不是无效数字,0.j也不应该是。但是,谢谢你关闭警告的方法。@mgilson:问题不在于0j对erf无效。每当在计算过程中遇到无效的浮点操作(例如0/0)时,就会发出无效警告。您完全正确。使用
-ffpe trap=invalid
(gfortran)编译我的测试程序会导致FPE终止SIGFPE上的进程。这仍然有点奇怪,因为使用函数CERF
而不是CERROR
不会导致任何问题。两者都声称返回复杂参数的error函数。有什么理由我不应该提交一份错误报告,要求scipy开发人员在CERROR
中使用CERF
算法?@mgilson:CERROR只计算erf,CERF也计算其导数,可能CERF不太准确。提交错误报告时,最好只描述错误,让开发人员确定最佳解决方案。谢谢。我提交了一份错误报告。球现在在他们的场上。
>>> type(0.j)
<class 'complex'>
>>> type(0.)
<class 'float'>
>>> erf(complex(1))
(0.84270079294971512+0j)
>>> erf(1)
0.84270079294971478
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