RcppEigen:对正定矩阵进行平方的最快方法?

时间:2015-02-20 15:01:02

标签: r matrix rcpp

假设我有一个正定矩阵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);

但这并没有改善简单乘法的计算时间。

1 个答案:

答案 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