假设我有一个正定矩阵S
。我想使用RcppEigen计算S %*% S
。我能做到:
using Eigen::Map;
using Eigen::MatrixXd;
const Map<MatrixXd> S(as<Map<MatrixXd> >(AA));
const MatrixXd SS(S * S);
return wrap(SS);
但这看起来很浪费,因为S
是肯定的(虽然它确实将R的计算时间提高了大约5倍)。如何利用对称性来减少计算时间?我试过了:
using Eigen::Map;
using Eigen::MatrixXd;
const Map<MatrixXd> S(as<Map<MatrixXd> >(AA));
const MatrixXd SS(S.selfAdjointView<Lower>() * S.selfAdjointView<Lower>());
return wrap(SS);
但这并没有改善简单乘法的计算时间。
答案 0 :(得分:1)
首先,您使用对称的代码不起作用。其次,他们实际上是RcppEigen Intro中的一个例子。
sqCpp <- "
using Eigen::Map;
using Eigen::MatrixXd;
const Map<MatrixXd> S(as<Map<MatrixXd> >(AA));
const MatrixXd SS(S * S);
return wrap(SS);
"
triCpp <- "
using Eigen::Map;
using Eigen::MatrixXd;
using Eigen::Lower;
const Map<MatrixXd> S(as<Map<MatrixXd> >(AA));
const int m(S.rows());
const MatrixXd SS(MatrixXd(m,m).setZero().
selfadjointView<Lower>().rankUpdate(S.adjoint()));
return wrap(SS);
"
library(inline)
fsq <- cxxfunction(signature(AA="matrix"), sqCpp,
plugin="RcppEigen")
ftri <- cxxfunction(signature(AA="matrix"), triCpp,
plugin="RcppEigen")
# Create symmetric matrix in R
library(Matrix)
x<-Matrix(rnorm(10000), 100)
# convert to normal matrix to pass to Rcpp
A <- as.matrix(forceSymmetric(x))
# Check to make sure same output
identical(fsq(A), ftri(A))
[1] TRUE
# Let's benchmark!!!
library(microbenchmark)
microbenchmark(A%*%A, fsq(A), ftri(A))
Unit: microseconds
expr min lq mean median uq max neval
A %*% A 1427.696 1465.6900 1546.9210 1491.217 1517.443 6442.999 100
fsq(A) 296.617 315.8230 387.1591 342.957 355.039 5299.837 100
ftri(A) 201.424 224.0515 247.9144 254.468 263.896 352.281 100