在Rcpp RcppEigen中的ols回归中乘以对角线

时间:2014-04-23 11:38:24

标签: r regression rcpp

我试图通过运行RcppEigen来加速我的慢速OLS估计。

我在Rcpp中有以下ols函数但是想在XX矩阵中乘以对角线,就像在下面的常规R情况下一样?

fastolsCpp <- '
const MapMatd X(as<MapMatd>(XX));
const MapVecd y(as<MapVecd>(yy));
const LLT<MatrixXd> llt(AtA(X));
const VectorXd betahat(llt.solve(X.adjoint() * y));
return wrap(betahat);
'
fastols <- cxxfunction(signature(XX = "matrix", yy = "numeric"), fastolsCpp, "RcppEigen",incl)

常规R

ols <- function (y, x) {
xrd<-crossprod(x)
xry<-crossprod(x, y)
diag(xrd)<-1.1*diag(xrd)
solve(xrd,xry)

Tks P

1 个答案:

答案 0 :(得分:4)

这很简单:

library(RcppEigen)
library(inline)

set.seed(42)
x <- 1:10
y <- 3+2*x+rnorm(10)

incl <- '
using Eigen::LLT;
using Eigen::Lower;
using Eigen::Map;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Rcpp::as;
typedef Eigen::Map<Eigen::MatrixXd>  MapMatd;
typedef Eigen::Map<Eigen::VectorXd>  MapVecd;
inline MatrixXd AtA(const MapMatd& A) {
int  n(A.cols());
return  MatrixXd(n,n).setZero().selfadjointView<Lower>().rankUpdate(A.adjoint());
}
'

fastolsCpp <- '
const MapMatd X(as<MapMatd>(XX));
const MapVecd y(as<MapVecd>(yy));
MatrixXd A=AtA(X);
const int   k=A.rows();
for (int i=0; i<k; i++) {
A(i,i) *= 1.1;
}
const LLT<MatrixXd> llt(A);
const VectorXd betahat(llt.solve(X.adjoint() * y));
return wrap(betahat);
'

fastols <- cxxfunction(signature(XX = "matrix", yy = "numeric"), fastolsCpp, "RcppEigen", incl)

all.equal(fastols(cbind(1,x), y),
          c(ols(y, cbind(1,x))))
#[1] TRUE


library(microbenchmark)
microbenchmark(ols(y, cbind(1,x)), fastols(cbind(1,x), y))
# Unit: microseconds
#                    expr     min      lq   median       uq     max neval
#     ols(y, cbind(1, x)) 137.585 139.1775 140.571 148.2945 359.642   100
# fastols(cbind(1, x), y)  12.533  13.4830  15.904  16.1720  55.743   100