通过我们的Rcpp包 ,我们花了一些时间使从 C++ 到R的包装(以及返回)变得更加容易。
而且因为线性代数已经是一个很好理解和编码的领域,犰狳,一个当前的、现代的、令人愉快的、记录良好的、小型的、模板化的......库非常适合我们的第一个扩展包装器:RcppArmadillo .
这也引起了其他 MCMC 用户的注意。去年夏天,我在罗切斯特大学商学院做了一天的工作,并帮助了中西部的另一位研究人员进行了类似的探索。试试 RcppArmadillo -它运行良好,得到积极维护(今天发布了新的 Armadillo 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
}
最后,您还可以通过内联获得即时原型设计,这可能会使“编码时间”更快。