2013-03-09 101 views
3

我想要一個具有mpz/mpfr值的numpy數組。因爲我的代碼:numpy數組與mpz/mpfr值

import numpy as np 
import gmpy2 
A=np.ones((5,5)); 
print A/gmpy2.mpfr(1); 

產生:

RuntimeWarning: invalid value encountered in divide 
    print A/gmpy2.mpfr(1); 
[[1.0 1.0 1.0 1.0 1.0] 
[1.0 1.0 1.0 1.0 1.0] 
[1.0 1.0 1.0 1.0 1.0] 
[1.0 1.0 1.0 1.0 1.0] 
[1.0 1.0 1.0 1.0 1.0]] 

這是我能理解是轉換gmpy MPFR到NumPy的float64是不可能的。那麼我怎樣才能首先獲得一個具有mpfr值的numpy數組呢?

謝謝。

回答

6

你需要用dtype=object創建你的數組,然後你可以在你的數組中使用任何python類型。我沒有安裝gmpy2,但下面的例子應該顯示它是如何工作的:

In [3]: a = np.ones((5, 5), dtype=object) 

In [5]: import fractions 

In [6]: a *= fractions.Fraction(3, 4) 

In [7]: a 
Out[7]: 
array([[3/4, 3/4, 3/4, 3/4, 3/4], 
     [3/4, 3/4, 3/4, 3/4, 3/4], 
     [3/4, 3/4, 3/4, 3/4, 3/4], 
     [3/4, 3/4, 3/4, 3/4, 3/4], 
     [3/4, 3/4, 3/4, 3/4, 3/4]], dtype=object) 

具有dtype=object一個numpy的陣列可以是liitle誤導,因爲強大的numpy的機器,使操作超標準dtypes快,現在由默認對象的蟒蛇運營商的照顧,這意味着速度不會存在了:

In [12]: b = np.ones((5, 5)) * 0.75 

In [13]: %timeit np.sum(a) 
1000 loops, best of 3: 1.25 ms per loop 

In [14]: %timeit np.sum(b) 
10000 loops, best of 3: 23.9 us per loop 
+0

然後'fractions.Fraction'不是一個特別快的類。我想知道原生Numpy數組和一個'mpfr'數組之間的速度增量,看作'mpfr'是一個相對低級別的C封裝類。 – nneonneo 2013-03-09 07:19:20

+1

@nneonneo我認爲問題不在於操作的速度,而在於Python函數調用涉及到每一個函數調用,而其他numpy dtypes不會發生這種情況。 – Jaime 2013-03-09 07:31:25

+0

是的,有Python函數調用,但對於在C中實現的類,這些調用的開銷可能很小。 'Fraction'是用純Python實現的,所以每次調用都是很多字節碼指令。 – nneonneo 2013-03-09 07:33:50

0

我相信這是在兩個庫中的一個錯誤。我也相信它是固定的。

輸入:

import sys 
import numpy as np 
import gmpy2 

print(sys.version) 
print(np.__version__) 
print(gmpy2.version) 

A=np.ones((5,5)); 
print(A/gmpy2.mpfr(1)) 

輸出:

3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] 
1.9.1 
2.0.5 
[[mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')] 
[mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')] 
[mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')] 
[mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')] 
[mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')]] 

要麼numpy的沒有正確地說,做什麼,當它遇到一個未知類型,或gmpy2沒有說明如何獲得除以東西(__rdiv__)。

除非您打算覆蓋其元素,否則沒有必要指定的dtype。像乘法這樣的運算會產生一個新的ndarray,Numpy會計算出使用什麼dtype