2017-09-04 355 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))都是非空的吗?如果不是,则应该重写第二个循环,以便只遍历稀疏重叠列集合。循环也可以互换以利用高效矩阵产品。