我们已经花了一些时间通过我们的Rcpp包使从C ++到R的包装变得容易(然后再返回)。
而且由于线性代数已经是一个易于理解和编码的领域,因此,Armadillo是当前,现代,令人愉悦,饱满,小巧,模板化的...库,非常适合我们的第一个扩展包装:RcppArmadillo。
这也引起了其他MCMC用户的注意。去年夏天,我在罗切斯特大学商学院做了一天的工作,并通过类似的探索帮助了中西部的另一位研究人员。给RcppArmadillo一个尝试-它运作良好,正在积极维护(新犰狳今日发布1.1.4,我会以后新RcppArmadillo)和支持。
而且由于我只是非常喜欢这个示例,所以这里是lm()
返回系数和std.errors 的快速“快速”版本:
extern "C" SEXP fastLm(SEXP ys, SEXP Xs) {
try {
Rcpp::NumericVector yr(ys); // creates Rcpp vector
Rcpp::NumericMatrix Xr(Xs); // creates Rcpp matrix
int n = Xr.nrow(), k = Xr.ncol();
arma::mat X(Xr.begin(), n, k, false); // avoids extra copy
arma::colvec y(yr.begin(), yr.size(), false);
arma::colvec coef = arma::solve(X, y); // fit model y ~ X
arma::colvec res = y - X*coef; // residuals
double s2 = std::inner_product(res.begin(), res.end(),
res.begin(), double())/(n - k);
// std.errors of coefficients
arma::colvec std_err =
arma::sqrt(s2 * arma::diagvec( arma::pinv(arma::trans(X)*X) ));
return Rcpp::List::create(Rcpp::Named("coefficients") = coef,
Rcpp::Named("stderr") = std_err,
Rcpp::Named("df") = n - k);
} catch( std::exception &ex ) {
forward_exception_to_r( ex );
} catch(...) {
::Rf_error( "c++ exception (unknown reason)" );
}
return R_NilValue; // -Wall
}
最后,您还可以通过内联立即获得原型,这可以使“编码时间”更快。