2013-11-22 45 views
3

我正在使用NumPy版本1.7.1。 現在我遇到了一個奇怪的取消,我不明白:在numpy數組操作中取消,包括標量

>>> import numpy as np 
>>> a = np.array([ 883, 931, 874], dtype=np.float32) 

數學a+0.1-a應該0.1。 現在,讓我們計算的 值這個表達式和絕對和相對誤差:

>>> a+0.1-a 
array([ 0.09997559, 0.09997559, 0.09997559], dtype=float32) 
>>> (a+0.1-a)-0.1 
array([ -2.44155526e-05, -2.44155526e-05, -2.44155526e-05], dtype=float32) 
>>> ((a+0.1-a)-0.1)/0.1 
array([-0.00024416, -0.00024416, -0.00024416], dtype=float32) 

第一個問題:這是一個相當高的絕對和相對誤差,這只是災難性取消,不是嗎?

第二個問題:當我使用一個數組,而不是標量,NumPy的是能夠與更精確計算,見相對誤差:

>>> a+np.array((0.1,)*3)-a 
array([ 0.1, 0.1, 0.1]) 
>>> (a+np.array((0.1,)*3)-a)-0.1 
array([ 2.27318164e-14, 2.27318164e-14, 2.27318164e-14]) 

這只是0.1我猜的數字表示。

但是,爲什麼,如果一個標量使用數組,而不是在a+0.1-a是與NumPy無法處理這種以同樣的方式?

回答

4

如果使用雙精度,則情景會發生變化。你所得到的是預計單精度(np.float32):

a = np.array([ 883, 931, 874], dtype=np.float64) 

a+0.1-a 
# array([ 0.1, 0.1, 0.1]) 

((a+0.1-a)-0.1)/0.1 
# array([ 2.27318164e-13, 2.27318164e-13, 2.27318164e-13]) 

在表達式中使用np.array((0.1,)*3)把一切都向float64,這也解釋了在第二次的結果精度更高。

+1

好的,謝謝,我還沒有看到隱含的64位類型!據我所知,numpy的不能只是把64位在''一個+ 0.1 a''而不被指示這樣做。 – roettm