2017-09-04 413 views
0

我在RcppEigen中爲加權協方差寫了一個函數。在其中一個步驟中,我想獲取矩陣的第i列和第j列,並計算cwiseProduct,它應該返回某種向量。 cwiseProduct的輸出將進入一個可重複使用多次的中間變量。從文檔看來,cwiseProduct返回一個CwiseBinaryOp,它本身有兩種類型。我cwiseProduct兩個向量進行操作,所以我想正確的返回類型應該是Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>,但我得到的錯誤沒有名爲ColXpr在命名空間中的本徵Eigen - .cwiseProduct的返回類型?

#include <RcppEigen.h> 
// [[Rcpp::depends(RcppEigen)]] 

Rcpp::List Crossprod_sparse(Eigen::MappedSparseMatrix<double> X, Eigen::Map<Eigen::MatrixXd> W) { 
    int K = W.cols(); 
    int p = X.cols(); 

    Rcpp::List crossprods(W.cols()); 

    for (int i = 0; i < p; i++) { 
    for (int j = i; j < p; j++) { 
     Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr> prod = X.col(i).cwiseProduct(X.col(j)); 
     for (int k = 0; k < K; k++) { 
     //double out = prod.dot(W.col(k)); 
     } 
    } 
    } 
    return crossprods; 
} 

我也試圖保存到一個斯帕塞夫克託成員

Eigen::SparseVector<double> prod = X.col(i).cwiseProduct(X.col(j)); 

以及計算,但不是在所有

X.col(i).cwiseProduct(X.col(j)); 

節省如果我不救的產品所有這些功能都很快返回,暗示cwiseProduct不是一個昂貴的功能。當我將它保存到SparseVector中時,該函數非常慢,這讓我認爲SparseVector不是正確的返回類型,並且Eigen正在做額外的工作以使其進入該類型。

回答

3

回想一下,Eigen依賴表達式模板,所以如果你不分配表達式,那麼這個表達式本質上是一個無操作。在你的情況下,分配給SparseVector是正確的。關於速度,確保在編譯器優化ON的情況下編譯(如-O3)。

儘管如此,我相信有一種更快的方式來編寫您的整體計算。例如,你確定所有的X.col(i).cwiseProduct(X.col(j))都是非空的嗎?如果不是,則應該重寫第二個循環,以便只遍歷稀疏重疊列集合。循環也可以互換以利用高效矩陣產品。