2017-09-04 33 views
0

私は重み付き共分散についてRcppEigenに関数を書いています。 1つのステップでは、行列Xの列iと列jをとり、何らかのベクトルを返すcwiseProductを計算します。 cwiseProductの出力は何度も再利用できる中間変数に入ります。ドキュメントからはcwiseProductCwiseBinaryOpを返します。それ自体は2種類あります。私cwiseProductは、2つの列ベクトルで動作するので、私は正しい戻り値の型がEigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>あるべきと思ったが、私はエラー名前空間にColXpr固有.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))が空ではないことを確認してください。そうでない場合は、2番目のループを書き換えて、重複する列の疎なセットだけを反復処理する必要があります。効率的なマトリックス製品を活用するために、ループを交換することもできます。