一切似乎都在我的程序包中正常工作,但是我想检查使其正确的步骤以及使用“Map”的内存使用情况。 (这是一个简单的示例,位于内联示例和fastLm()示例之间。)

这是一个内联函数,它在矩阵的每一列上取最大值:

library(Rcpp);
library(inline);
library(RcppEigen);

maxOverColCpp <- '
    using Eigen::Map;
    using Eigen::MatrixXd;

   // Map the double matrix AA from R
   const Map<MatrixXd> A(as<Map<MatrixXd> >(AA));

   // evaluate and columnwise maximum entry of A
   const MatrixXd Amax(A.colwise().maxCoeff());
   return wrap(Amax);
'

rcppeigen_max_over_columns <- cxxfunction(signature(AA = "matrix"), maxOverColCpp, plugin = "RcppEigen")

然后,要更改功能以将其包含在现有R包中,我将代码重写如下,将其保存在现有R包中新rcppeigen_max_over_columns.cpp文件夹中的src中:
// we only include RcppEigen.h which pulls Rcpp.h in for us
#include <RcppEigen.h>

// via the depends attribute we tell Rcpp to create hooks for
// RcppEigen so that the build process will know what to do
//
// [[Rcpp::depends(RcppEigen)]]

// via the exports attribute we tell Rcpp to make this function
// available from R
//
// [[Rcpp::export]]
Eigen::MatrixXd rcppeigen_max_over_columns(const Eigen::MatrixXd & A){
    Eigen::MatrixXd Amax = A.colwise().maxCoeff();
    return Amax;
}

(实际上,这花了更长的时间,因为我还需要在行中查找最大值。)

然后:
  • 用以下行修改了DESCRIPTION FILE:

    导入:Rcpp(> = 0.11.3),RcppEigen(> = 0.3.2.2.0)

    链接至:Rcpp,RcppEigen
  • 用以下行修改了NAMESPACE文件:

    useDynLib(toyRpackage)

    导入(RcppEigen)

    importFrom(Rcpp,evalCpp)
  • 在R终端中的
  • ,键入以下内容,我假设将R和C++粘合在一起:

    Rcpp::compileAttributes(pkgdir =“toyRpackage”,verbose = getOption(“verbose”))

  • 然后,对于常规软件包,我做了R CMD checkR CMD build
  • 第一个问题是,将RcppEigen函数包含到现有R包中的此过程是否正确? (我完全忽略了任何Makevars文件或任何.h文件-我真的不知道它们的作用...也不太了解NAMESPACE文件的更改。我试图复制RcppEigen.package.skeleteon()设置,但是我将我的函数添加到现有程序包中。因此,如果以后我错过了可能会成为问题的东西,最好知道是否可以。)
  • 第二个问题是,我是否需要在rcppeigen_max_over_columns.cpp中的某个地方放置“映射”,以便在将矩阵从R传递到C++时不复制该矩阵?

  • 我知道这是一个初学者的问题,但是由于不了解任何C++,在理解.cpp文件中的语法时遇到了一些麻烦。我以为这个问题可能会对其他也在尝试向其程序包中添加简单功能的人有所帮助。 :)

    另外,如果您对在RcppArmadillo上使用RcppEigen有强烈的兴趣,请告诉我。我读了http://thread.gmane.org/gmane.comp.lang.r.rcpp/3522这很有用。对于我采用max over列的示例,RcppEigen看起来要快得多,但不确定为什么。

    最佳答案



    对于具有相对简单C++代码的基本R包,您不需要包括头文件,自定义Makevars / Makefile或类似的东西。如果您构建更复杂的东西,则可能需要Makefile / Makevars来帮助处理构建过程,并且可能想要使用头文件将接口(interface)与实现分开-但是为此,您必须深入研究并挑选一些C++书籍,因为有很多东西要学习。

    换句话说-您正在做的事很好。对于简单的情况,最好只使用.cpp目录中的src/文件(并让Rcpp,属性及其其他同级包处理其余部分)



    嗯,除非将R对象传输到(非Rcpp)类,否则几乎总是会复制数据,除非您专门使用可以重用基础数据的构造函数。我不知道Eigen是否具有可以重用内存的构造函数,但是我建议除非您知道它很重要,否则不要担心(因为复制一定范围的数据通常会很快)

    10-06 01:00