2017-03-10 188 views
2

我可以訪問大量的矩陣庫,但對於這個項目,我使用Eigen,因爲它的編譯時間定義和包含SVD。現在Eigen中有效的矩陣轉置矩陣乘法

,我做以下操作:

Eigen::Matrix<double,M,N> A;  // populated in the code 

Eigen::Matrix<double,N,N> B = A.transpose() * A; 

據我所知,這使得A的副本,並形成轉置,這是由一個又成倍增加。這個操作是在相對較小的矩陣(M = 20-30,N = 3)上執行的,但是每秒要執行數百萬次,這意味着它必須儘可能快。

,我讀了使用下面的更快:

B.noalias() = A.transpose() * A; 

我可以寫我自己的子程序接受一個作爲輸入和填充B,但我在想,如果有一個使用一個有效的,現有的實現最少的週期。

+0

考慮看看這個:http://scicomp.stackexchange.com/questions/25283/beating-typical-blas-libraries-matrix-multiplication-performance –

+0

這有幫助嗎? http://stackoverflow.com/questions/39606224/does-eigen-have-self-transpose-multiply-optimization-like-h-transposeh – kennytm

回答

1

首先,由於Eigen依賴於模板表達式,所以A.transpose()不會評估爲臨時值。

其次,在:

Matrix<double,N,N> B = A.transpose() * A; 

徵知道B不能出現在表達式的右手邊(因爲這裏的編譯器調用B的構造函數),因此,沒有臨時創建的所有。

Matrix<double,N,N> B;    // declare first 
B.noalias() = A.transpose() * A; // eval later 

最後,對於這樣的小矩陣,我不認爲使用B.selfadjointView().rankUpdate(A)將幫助(如kennytm評論建議):這是等價的。

在otherhand,與N = 3,這可能是值得嘗試的懶惰實現:

B = A.transpose().lazyProduct(A)

只是要確定。 Eigen的內置啓發式方法可以選擇最佳的產品實現方式,但由於啓發式方法必須簡單且快速進行評估,因此它可能不是100%正確的。

+0

謝謝。懶惰的項目提示是如何。現在,我最終做了一些完全不同的事情,因爲我在發現後發現Eigen不能在GPU上運行cuda。儘管我喜歡圖書館。另外,完全不建立A是最有效的,這就是我所做的。 –