回答
忽略CSC業務,也許回答一個比你問的更簡單的問題。給出C索引值的元組列表,我將如何計算C的元素子集。
既然你正在評估C = ATdot(B)你是B.所以列乘以列,
for i, j in indexList:
C[i, j] = np.dot(A[:,i], B[:,j])
我猜,是不是你在找什麼,但我發現簡單的答案有時有助於澄清問題。
是的,這或多或少是我現在使用的方法,但不幸的是對np.dot()的循環調用非常緩慢。 – bluecat
如果您事先知道您需要哪些C部分以及這些部分中的某些部分是連續的和矩形區域*,那麼您可以使用與分區矩陣乘法(1)或塊矩陣乘法相關的矩陣代數規則2)來加速其中一些計算。因此,例如,您可以使用@GaryBishop的相同基本邏輯,但不是具有「i」和「j」元素的列表,而是具有i_start,i_end和j_start的四元組的列表(或數組),j_end定義C的子矩陣,那麼你可以使用這些指數(儘管在這些鏈接中建立的規則)來找出需要爲所需的C塊求解的A和B的子矩陣。
對於簡單的例子,假設你只想要C的中間塊,所以我們將C分割成C1,C2和C3,我們關心的只有C2。如果A^{T}同樣被劃分成三組A1,A2,A3,那麼C2 = A2 * B。這個想法推廣到任何形狀的矩形,它只需要計算A和B的不同分區。這個想法是一樣的。
- - 這很平凡,但如果區域大於單個元素,則只會節省時間。
這和我想的一樣。我懷疑構成C2和A2的行甚至可能是非連續的(不連續的切片) – heltonbiker
我認爲你是正確的,它們不必是連續的,儘管代數可能有點棘手。非連續的A2可能被認爲是更精細分區的元素,例如, A1(輸出),A2a(輸入),A2b(輸出),A2C(輸入),A3(輸出),但仔細索引並很好地理解您關心它的哪些元素可能會更快地使用非連續子集直接使用一塊連續的分區進行處理。 – BKay
相反在使用Python(GaryBishop的答案)座標迭代的,你可以有numpy的做循環,從而構成實質性加速(以下計時):
def sparse_mult(a, b, coords) :
rows, cols = zip(*coords)
rows, r_idx = np.unique(rows, return_inverse=True)
cols, c_idx = np.unique(cols, return_inverse=True)
C = np.dot(a[rows, :], b[:, cols])
return C[r_idx, c_idx]
>>> A = np.arange(12).reshape(3, 4)
>>> B = np.arange(15).reshape(3, 5)
>>> np.dot(A.T, B)
array([[100, 112, 124, 136, 148],
[115, 130, 145, 160, 175],
[130, 148, 166, 184, 202],
[145, 166, 187, 208, 229]])
>>> sparse_mult(A.T, B, [(0, 0), (1, 2), (2, 4), (3, 3)])
array([100, 145, 202, 208])
sparse_mult
返回扁平您提供的座標值的數組作爲元組列表。我不是很熟悉,稀疏矩陣格式,所以我不知道如何從上面的數據定義CSC,但以下工作:
>>> coords = [(0, 0), (1, 2), (2, 4), (3, 3)]
>>> sparse.coo_matrix((sparse_mult(A.T, B, coords), zip(*coords))).tocsc()
<4x5 sparse matrix of type '<type 'numpy.int32'>'
with 4 stored elements in Compressed Sparse Column format>
這是各種替代方案的時機:
>>> import timeit
>>> a = np.random.rand(2000, 3000)
>>> b = np.random.rand(3000, 5000)
>>> timeit.timeit('np.dot(a,b)[[0, 0, 1999, 1999], [0, 4999, 0, 4999]]', 'from __main__ import np, a, b', number=1)
5.848562187263569
>>> timeit.timeit('sparse_mult(a, b, [(0, 0), (0, 4999), (1999, 0), (1999, 4999)])', 'from __main__ import np, a, b, sparse_mult', number=1)
0.0018596387374678613
>>> np.dot(a,b)[[0, 0, 1999, 1999], [0, 4999, 0, 4999]]
array([ 758.76351111, 750.32613815, 751.4614542 , 758.8989648 ])
>>> sparse_mult(a, b, [(0, 0), (0, 4999), (1999, 0), (1999, 4999)])
array([ 758.76351111, 750.32613815, 751.4614542 , 758.8989648 ])
- 1. 本徵稀疏矩陣乘法似乎計算全矩陣
- 2. 遞歸矩陣乘法算法未能計算
- 3. Java矩陣運算,並行柯爾特矩陣 - 矩陣乘法
- 4. SSE矩陣,矩陣乘法
- 5. 算法矩陣加法和乘法
- 6. PageRank計算矩陣向量乘積的稀疏矩陣
- 7. 矩陣乘法
- 8. 矩陣乘法
- 9. 矩陣乘法
- 10. 矩陣乘法
- 11. 矩陣的乘法
- 12. 的矩陣乘法
- 13. 什麼是矩陣 - 矩陣乘法/矩陣 - 向量乘法的不同類型的算法
- 14. Strassen具有遞歸的子立方矩陣乘法算法
- 15. 矩陣(scipy稀疏) - 矩陣(密集; numpy陣列)乘法效率
- 16. 矩陣乘矢量乘法
- 17. 用稀疏矩陣乘二次形式矩陣的算法
- 18. ilnumerics矩陣乘法運算符
- 19. 矩陣序列的矩陣乘法
- 20. 矩陣的矩陣列乘法
- 21. 如何計算C中的矩陣乘法?
- 22. 更快的矩陣向量乘法實現[並行計算]
- 23. 計算矩陣乘法的遞歸函數
- 24. 矩陣乘法採用IAS指令集
- 25. C++矩陣乘法
- 26. 矩陣乘法。 Python
- 27. Accord.NET矩陣乘法
- 28. 乘法矩陣Matlab
- 29. Hadoop矩陣乘法
- 30. hlsl矩陣乘法
儘管這是編程社區,但您可能需要在Math SO上檢查這一點。 – jdotjdot
@jdotjdot:對我來說,這純粹是一個編程問題,幾乎沒有數學內容。 – NPE
我檢查mathexchange,同時爲帖子製作標籤,但它沒有像scipy和numpy或甚至稀疏似乎相關的。 – bluecat