2012-07-12 40 views
0
>>> from scipy.special import erf 
>>> print (erf(0.j)) 
__main__:1: RuntimeWarning: invalid value encountered in erf 
0j 

這個警告只打印一次(即使我做scipy.special.errprint(0))運行時警告,但我不明白爲什麼它打印在所有。真的,0.j0.的數字是一樣的,它沒有問題。scipy.special.erf提高與0.j

我想有兩個問題: 1)有沒有什麼辦法來壓制這個警告? 2)這是警告一個錯誤,還是我錯過了什麼?

UPDATE

我(我認爲)在SciPy的源代碼樹追查誤差函數。它位於:scipy/special/specfun/specfun.fsubroutine CERROR)。此函數不會引發警告(從簡單的Fortran程序中調用時可以正常工作)。

回答

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 implementation,我們會發現:

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 /(K + 0.5)= 0 + 0j的
  • CS←CS + CR = 0 + 0j的

然後條件需要CR/CS,這是一個0/0,這是一個無效的浮點運算,因此是警告。

這是一個小問題,可以通過在開頭檢查Z == 0來輕鬆「固定」。如果您發現這種行爲不穩定,您可以使用report a bug

+0

據我所知,他們是不同的數字就python而言。但數學上,它們並沒有不同。我的觀點是,如果0.不是無效數字,0.j也不應該是。但是,感謝關閉警告的方式。 – mgilson 2012-07-12 14:06:11

+0

@mgilson:問題不在於0j對erf無效。無論何時在計算過程中遇到無效的浮點操作時都會引發無效警告,例如, 0/0。 – kennytm 2012-07-12 14:13:48

+0

@mgilson:有關警告的原因,請參閱更新。 – kennytm 2012-07-12 14:23:35