我有我要乘在一起的兩個N×N的矩陣:A和B.在NumPy的,我用:NumPy的矩陣乘法效率的矩陣結構已知
import numpy as np
C = np.dot(A, B)
但是,我碰巧知道矩陣B只有第n行和第n列非零(這直接來自產生矩陣的分析公式,毫無疑問總是這種情況)。
希望能利用這一事實的優點和減少以生成C需要的乘法的數量,我取代了以上:
import numpy as np
for row in range(0, N):
for col in range(0, N):
if col != n:
C[row, col] = A[row, n]*B[n, col] #Just one scalar multiplication
else:
C[row, col] = np.dot(A[row], B[:, n])
分析上,這應該減少總複雜性如下:在一般的情況下(不使用任何花哨的技巧,只是基本的矩陣乘法)C = AB,其中A和B都是NxN,應該是O(N^3)。也就是說,所有N行必須乘以所有N列,並且這些點積中的每一個都包含N次乘法=> O(N N N)= O(N^3)#
利用B的結構作爲我做過上面的事情,但是應該是O(N^2 + N^2)= O(2N^2)= O(N^2)。也就是說,所有N行必須乘以所有N列,但是,對於所有這些(除了涉及'B [:,n]'的那些行),只需要一個標量乘法:只有'B [:, m]'中的一個元素對於m!= n是非零的。當n == m時,會發生N次(每次A行必須乘以B的列n),必須發生N次標量乘法。#
但是,第一塊代碼(使用np.dot (A,B))實質上更快。我知道(通過如下信息:Why is matrix multiplication faster with numpy than with ctypes in Python?)np.dot的低層實現細節很可能會歸咎於此。所以我的問題是:如何在不犧牲NumPy的實現效率的情況下利用矩陣B的結構來提高乘法效率,而無需在c中構建自己的低級矩陣乘法?
該方法是對許多變量進行數值優化的一部分,因此,O(N^3)是棘手的,而O(N^2)可能會完成工作。
謝謝你的幫助。另外,我是新手,所以請原諒任何新手錯誤。
你有沒有考慮用'cython'或其他方式將你的乘法函數直接編譯成機器代碼?在好日子裏,我可能會用'f2py'來做這件事,但我知道不是每個人都想在fortran中編寫代碼;-) – mgilson
我對此也不完全確定,但是scipy可能已經解決了一些問題類似的問題使用稀疏矩陣。任何scipy大師都知道嗎? – mgilson
看看'scipy.sparse',如果通過稀疏結果來稀疏結果,可以使'B'爲稀疏矩陣'B = scipy.sparse.csr_matrix(B)',然後只做'A * B'密集。我的直覺是我沒有測試過,所以這樣更有效率。 – Akavall