特征 - 返回类型.cwiseProduct?

时间:2017-09-04 05:04:47

标签: eigen rcpp

我正在RcppEigen中编写加权协方差函数。在其中一个步骤中,我想要获取矩阵的第i列和第j列,并计算cwiseProduct,它应返回某种向量。 cwiseProduct的输出将进入一个中间变量,可以多次重复使用。从文档中可以看出cwiseProduct返回CwiseBinaryOp,它本身有两种类型。我的cwiseProduct在两个列向量上运行,所以我认为正确的返回类型应该是Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>,但我得到错误在名称空间Eigen中没有名为ColXpr的成员

#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;
}

我也尝试过保存到SparseVector

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

以及计算,但根本不保存

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

如果我根本不保存产品,函数会很快返回,暗示cwiseProduct不是一个昂贵的功能。当我将它保存到SparseVector时,该函数非常慢,让我认为SparseVector不是正确的返回类型,而Eigen正在做额外的工作以使其进入该类型。

1 个答案:

答案 0 :(得分:3)

回想一下,Eigen依赖于表达式模板,所以如果你没有分配一个表达式,那么这个表达式本质上就是一个无操作。在您的情况下,将其分配给SparseVector是正确的做法。关于速度,请确保在编译器优化开启时进行编译(如-O3)。

尽管如此,我相信有更快的方法来编写整体计算。例如,您确定所有X.col(i).cwiseProduct(X.col(j))都是非空的吗?如果不是,则应重写第二个循环以仅迭代稀疏的重叠列集。循环也可以互换,以利用有效的矩阵产品。