拥有 - return 类型或 .cwiseProduct?
Eigen - return type of .cwiseProduct?
我正在 RcppEigen 中编写一个函数用于加权协方差。在其中一个步骤中,我想获取矩阵 X 的第 i 列和第 j 列,并计算 cwiseProduct,它应该 return 某种向量。 cwiseProduct 的输出将进入一个可以多次重复使用的中间变量。从文档看来 cwiseProduct returns a CwiseBinaryOp,它本身有两种类型。我的 cwiseProduct 在两个列向量上运行,所以我认为正确的 return 类型应该是 Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>
,但我得到错误 no member named ColXpr in namespace Eigen
#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));
如果我根本不保存乘积,函数 return 会非常快,这表明 cwiseProduct 不是一个昂贵的函数。当我将它保存到 SparseVector 中时,该函数非常慢,让我认为 SparseVector 不是正确的 return 类型,而 Eigen 正在做额外的工作以使其成为该类型。
回想一下,Eigen 依赖于表达式模板,因此如果您不分配表达式,那么该表达式本质上是一个空操作。在您的情况下,将其分配给 SparseVector
是正确的做法。关于速度,确保使用编译器优化进行编译(如 -O3
)。
尽管如此,我相信有一种更快的方法来编写您的整体计算。例如,您确定所有 X.col(i).cwiseProduct(X.col(j))
都是非空的吗?如果不是,则应重写第二个循环以仅迭代稀疏的重叠列集。循环也可以互换以利用有效的矩阵产品。
我正在 RcppEigen 中编写一个函数用于加权协方差。在其中一个步骤中,我想获取矩阵 X 的第 i 列和第 j 列,并计算 cwiseProduct,它应该 return 某种向量。 cwiseProduct 的输出将进入一个可以多次重复使用的中间变量。从文档看来 cwiseProduct returns a CwiseBinaryOp,它本身有两种类型。我的 cwiseProduct 在两个列向量上运行,所以我认为正确的 return 类型应该是 Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>
,但我得到错误 no member named ColXpr in namespace Eigen
#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));
如果我根本不保存乘积,函数 return 会非常快,这表明 cwiseProduct 不是一个昂贵的函数。当我将它保存到 SparseVector 中时,该函数非常慢,让我认为 SparseVector 不是正确的 return 类型,而 Eigen 正在做额外的工作以使其成为该类型。
回想一下,Eigen 依赖于表达式模板,因此如果您不分配表达式,那么该表达式本质上是一个空操作。在您的情况下,将其分配给 SparseVector
是正确的做法。关于速度,确保使用编译器优化进行编译(如 -O3
)。
尽管如此,我相信有一种更快的方法来编写您的整体计算。例如,您确定所有 X.col(i).cwiseProduct(X.col(j))
都是非空的吗?如果不是,则应重写第二个循环以仅迭代稀疏的重叠列集。循环也可以互换以利用有效的矩阵产品。