2017-02-01 62 views
1

我正在嘗試使用numpy獲得Python列表/矩陣的「強大」。我唯一的當前工作的解決方案是一個反覆的使用功能np.dot():Numpy 2D數組 - 功率 - 沒有返回答案?

def matr_power(matrix, power): 
    matrix_a = list(matrix) 
    matrix_b = list(matrix) 
    for i in range(0, power-1): 
     matrix_a = np.dot(matrix_a, matrix_b) 
    return matrix_a 

工作適合我的需要,但我知道這可能不是最有效的方法。

我已經嘗試將我的列表轉換爲一個numpy數組,然後對其執行電源操作,然後返回列表以便它可用於我需要的形式。轉換似乎發生,但功率計算不會。

while (foo != bar): 
    matr_x = np.asarray(matr_a) 
    matr_y = matr_x ** n 
    matr_out = matr_y.tolist() 
    n += 1 
    # Other code here to output certain results 

的問題是,該矩陣被轉換爲預期的陣列,但是在執行動力作業時(**matr_y最終被相同matr_x彷彿是有史以來執行任何計算。我曾嘗試使用np.power(matr_y, n)和Stack Overflow的相關問題中找到的一些其他解決方案。

我試過使用numpy文檔,但是(或者我誤解了它,或者)它只是確認這應該按預期工作。

當在PyCharm中檢查調試控制檯時,除了計算matr_x ** i從未被計算(或者從未存儲在matr_y中)之外,一切看起來都不錯(所有的矩陣/列表/數組都被轉換爲預期的)。


回答

雖然可以使用numpy的矩陣與所述操作者**,最好的解決方案是使用numpy的陣列(如numpy的矩陣被棄用)聯合numpy的的linalg matrix_power方法。

matr_x = np.array(mat_a) 
matr_y = np.linalg.matrix_power(matr_x, path_length) 
work_matr = matr_y.tolist() 

這也是現在很明顯的**功能被逐元素可能已經發現前面要不是我一直在使用鄰接矩陣(僅零和的)。

+1

對於numpy的陣列,''** *行爲逐個元件*。 –

+0

好吧,謝謝,但權力(matr_y,我)也似乎沒有按照我的預期行事,這是否也是元素明智?通過np.dot()我唯一的選擇迭代? – Matchoo

+0

是的,'power'也是元素明智的,正如其文檔字符串的第一行所解釋的那樣。 :) –

回答

1

有(至少)兩個選項,用於計算使用沒有多個呼叫numpy的一個矩陣的力量來dot

例如,

In [38]: a 
Out[38]: 
array([[0, 1, 0], 
     [1, 0, 1], 
     [0, 1, 0]]) 

In [39]: np.linalg.matrix_power(a, 2) 
Out[39]: 
array([[1, 0, 1], 
     [0, 2, 0], 
     [1, 0, 1]]) 

In [40]: np.linalg.matrix_power(a, 3) 
Out[40]: 
array([[0, 2, 0], 
     [2, 0, 2], 
     [0, 2, 0]]) 

In [41]: m = np.matrix(a) 

In [42]: m ** 2 
Out[42]: 
matrix([[1, 0, 1], 
     [0, 2, 0], 
     [1, 0, 1]]) 

In [43]: m ** 3 
Out[43]: 
matrix([[0, 2, 0], 
     [2, 0, 2], 
     [0, 2, 0]]) 
+1

馬修,如果你不確定使用哪一個。這裏是[官方位置](http://stackoverflow.com/a/20964252/7207392)。 –

+1

@Matthew我只是把這個連接起來,以防你在Warren提供的兩個完美的解決方案之間被撕裂。就我個人而言,我傾向於認同'matrix'類不足以抵消它引起的混淆。所以我會選擇'linalg.matrix_power'。如果您必須自己編寫一個有效的整數乘法程序:您可以通過重複平方操作數(M,M^2,M^4,M^8 ...)來節省大量乘法運算,然後將其位指數的二進制表示被設置。 –

+0

@PaulPanzer這聽起來很有趣,但我有點困惑,如何工作。有沒有機會擴展或鏈接到一個簡潔的解釋? – Matchoo

1

沃倫的答案是非常好的。

根據OP的特別要求,我簡要介紹瞭如何手動構建一個高效的整數功率算子。

我不知道這個算法叫什麼,但它是這樣工作的: 假設你想計算X^35。如果你天真地這麼做,它會花費你34次乘法。但你可以做得比這更好。寫X^35 = X^32 x X^2 x X.您在這裏完成的是根據35的二進制表示形式拆分產品,即100011。現在,計算X^32其實很便宜,因爲你只需要重複(5次)平方X就可以到達那裏。因此,在總你只需要7個乘法比34

更好的在代碼:

def my_power(x, n): 
    out = None 
    p = x 
    while True: 
     if n % 2 == 1: 
      if out is None: 
       out = p 
      else: 
       out = out @ p # this requires a fairly up-to-date python 
           # if yours is too old use np.dot instead 
      if n == 1: 
       return out 
     n //= 2 
     p = p @ p