使用 `sourceCpp` 编译 `fastLm` [英] Using `sourceCpp` to compile `fastLm`

查看:62
本文介绍了使用 `sourceCpp` 编译 `fastLm`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始尝试使用 Rcpp 并希望使用 fastLm 函数作为示例(也是因为它对潜在的后续工作很有用).我知道 fastLmRcppArmadillo 包的一部分,但我想使用 sourceCpp 编译它.代码可以在这里找到,也在下面.我遇到的第一个问题是在安装和加载RcppRcppArmadillosourceCpp("fastLm.cpp")>.我收到此错误 error: RcppArmadillo.h: No such file or directory 然后是所有类型的东西,我猜是从那开始的.

I started playing around with Rcpp and would like to use the fastLm function as an example (also because it's useful for potential later work). I know that fastLm is part of the RcppArmadillo package but I would like to compile it using sourceCpp. The code can be found here and is also below. The first problem I encounter is that I can't simply run sourceCpp("fastLm.cpp") in R after installing and loading Rcpp and RcppArmadillo. I get this error error: RcppArmadillo.h: No such file or directory and then all kind of things, which I guess follow from that.

第二个问题是我认为我需要更改fastLm.cpp 中的一些内容.我的更改也在下面,但我确定缺少某些内容或错误.我包括 #include using namespace Rcpp;//[[Rcpp::export]] 来导出函数到 R,我将参数从 SEXP 更改为 NumericVectorNumericMatrix.我不明白为什么这不可行,并且可能对返回值进行类似的调整?

The second issue is that I think I need to change some stuff in the fastLm.cpp. My changes are also below but I am sure something is missing or wrong. I included #include <Rcpp.h> and using namespace Rcpp; and // [[Rcpp::export]] to export the function to R and I changed the arguments from SEXP to NumericVector and NumericMatrix. I don't see why that shouldn't work and a similar adjustment is probably possible for the return value?

fastLm.cpp

#include <RcppArmadillo.h>

extern "C" SEXP fastLm(SEXP ys, SEXP Xs) {

    Rcpp::NumericVector yr(ys);                 // creates Rcpp vector from SEXP
    Rcpp::NumericMatrix Xr(Xs);                 // creates Rcpp matrix from SEXP
    int n = Xr.nrow(), k = Xr.ncol();

    arma::mat X(Xr.begin(), n, k, false);       // reuses memory and avoids extra copy
    arma::colvec y(yr.begin(), yr.size(), false);

    arma::colvec coef = arma::solve(X, y);      // fit model y ~ X
    arma::colvec resid = y - X*coef;            // residuals

    double sig2 = arma::as_scalar( arma::trans(resid)*resid/(n-k) );
                                                // std.error of estimate
    arma::colvec stderrest = arma::sqrt( sig2 * arma::diagvec( arma::inv(arma::trans(X)*X)) );

    return Rcpp::List::create(
        Rcpp::Named("coefficients") = coef,
        Rcpp::Named("stderr")       = stderrest
    ) ;

}

fastLm.cpp 已更改

#include <Rcpp.h>
#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
extern "C" SEXP fastLm(NumericVector yr, NumericMatrix Xr) {

    int n = Xr.nrow(), k = Xr.ncol();

    arma::mat X(Xr.begin(), n, k, false);       // reuses memory and avoids extra copy
    arma::colvec y(yr.begin(), yr.size(), false);

    arma::colvec coef = arma::solve(X, y);      // fit model y ~ X
    arma::colvec resid = y - X*coef;            // residuals

    double sig2 = arma::as_scalar( arma::trans(resid)*resid/(n-k) );
                                                // std.error of estimate
    arma::colvec stderrest = arma::sqrt( sig2 * arma::diagvec( arma::inv(arma::trans(X)*X)) );

    return Rcpp::List::create(
        Rcpp::Named("coefficients") = coef,
        Rcpp::Named("stderr")       = stderrest
    ) ;

}

推荐答案

您需要使用 Rcpp::depends 伪属性指示对 RcppArmadillo 的依赖.这将负责查找 RcppArmadillo 标头和针对 blaslapack 等的链接......

You need to indicate dependency on RcppArmadillo with the Rcpp::depends pseudo attribute. This will take care of finding RcppArmadillo headers and link against blas, lapack etc ...

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;

// [[Rcpp::export]]
List fastLm(NumericVector yr, NumericMatrix Xr) {

    int n = Xr.nrow(), k = Xr.ncol();

    arma::mat X(Xr.begin(), n, k, false);       // reuses memory and avoids extra copy
    arma::colvec y(yr.begin(), yr.size(), false);

    arma::colvec coef = arma::solve(X, y);      // fit model y ~ X
    arma::colvec resid = y - X*coef;            // residuals

    double sig2 = arma::as_scalar( arma::trans(resid)*resid/(n-k) );
                                                // std.error of estimate
    arma::colvec stderrest = arma::sqrt( sig2 * arma::diagvec( arma::inv(arma::trans(X)*X)) );

    return Rcpp::List::create(
        Rcpp::Named("coefficients") = coef,
        Rcpp::Named("stderr")       = stderrest
    ) ;

}

此外,使用 #include 而不是 #include 非常重要.RcppArmadillo.h 负责包含 Rcpp.h 在正确的时间,包含文件的顺序在这里非常重要.

Also, it is very important that you use #include <RcppArmadillo.h> and not #include <Rcpp.h>. RcppArmadillo.h takes care of including Rcpp.h at the right time, and order of include files is very important here.

此外,您可以返回一个 List 并删除 extern "C".

Also, you can return a List and drop the extern "C".

这篇关于使用 `sourceCpp` 编译 `fastLm`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆