2017-09-04 7 views
0

Ich schreibe eine Funktion in RcppEigen für gewichtete Kovarianzen. In einem der Schritte möchte ich Spalte i und Spalte j einer Matrix X nehmen und das cwiseProduct berechnen, das eine Art Vektor zurückgeben soll. Die Ausgabe von cwiseProduct wird in eine Zwischenvariable gehen, die viele Male wiederverwendet werden kann. Aus der Dokumentation scheint cwiseProduct eine CwiseBinaryOp zurückgibt, die selbst zwei Arten nimmt. Mein cwiseProduct arbeitet auf zwei Spaltenvektoren, so dachte ich, der richtige Rückgabetyp Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr> sein soll, aber ich habe den Fehler kein Mitglied namens ColXpr im Namensraum EigenEigen - Rückgabetyp von .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; 
} 

Ich habe auch versucht, in eine sparsevector Spar

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

sowie Computing, aber Speicher nicht an allen

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

Wenn ich das Produkt nicht speichern Die Funktionen kehren sehr schnell zurück und weisen darauf hin, dass cwiseProduct keine teure Funktion ist. Wenn ich es in einen SparseVector speichere, ist die Funktion extrem langsam, was mich denken lässt, dass SparseVector nicht der richtige Rückgabetyp ist und Eigen zusätzliche Arbeit leistet, um es in diesen Typ zu bekommen.

Antwort

3

Erinnern Sie sich daran, dass Eigen auf Ausdrucksvorlagen angewiesen ist. Wenn Sie also keinen Ausdruck zuweisen, ist dieser Ausdruck im Wesentlichen ein Nicht-Op. In Ihrem Fall ist es richtig, es einer SparseVector zuzuweisen. In Bezug auf Geschwindigkeit, stellen Sie sicher, mit Compiler-Optimierungen ON (wie -O3) zu kompilieren.

Nichtsdestotrotz glaube ich, dass es einen schnelleren Weg gibt, Ihre Gesamtberechnungen zu schreiben. Sind Sie beispielsweise sicher, dass alle X.col(i).cwiseProduct(X.col(j)) nicht leer sind? Wenn nicht, sollte die zweite Schleife neu geschrieben werden, um nur über die spärliche Menge überlappender Spalten zu iterieren. Schleifen könnten auch ausgetauscht werden, um effiziente Matrixprodukte zu nutzen.