gpt4 book ai didi

c++ - RcppEigen - 从内联到包中的 .cpp 函数和 "Map"

转载 作者:搜寻专家 更新时间:2023-10-31 01:02:19 26 4
gpt4 key购买 nike

一切似乎都在我的包中工作,但我想检查制作它的步骤是否正确以及使用“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 包中,我将代码重写如下,将其保存在新的 src 文件夹中的 rcppeigen_max_over_columns.cpp 中一个现有的 R 包:

// 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;
}

(事实上,它有点长,因为我还需要包括查找最大行数。)

然后:

  • 使用以下行修改了描述文件:

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

    链接到:Rcpp、RcppEigen

  • 使用以下行修改了 NAMESPACE 文件:

    使用动态库(玩具包)

    导入(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++ 时不会被复制?

    <

我知道这是一个初学者问题,但我在理解 .cpp 文件中的语法时遇到了一些困难,因为我不懂任何 C++。我想也许这个问题可能会帮助其他人也在尝试向他们的包中添加一个简单的功能。 :)

此外,如果您对使用 RcppEigen 而不是 RcppArmadillo 有任何强烈的感觉,请告诉我。我读了http://thread.gmane.org/gmane.comp.lang.r.rcpp/3522这很有用。对于我采用 max over columns 的示例,RcppEigen 似乎快得多,不知道为什么。

最佳答案

First question is whether this process for including an RcppEigen function into an existing R package is correct? (I completely ignored any Makevars files or any .h files -- I don't really know what they do... Also don't really understand the changes to the NAMESPACE file. I tried to copy the RcppEigen.package.skeleteon() set-up but I am adding my function to an existing package. So it would be good to know if it's okay in case I missed something that could be a problem later.)

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

换句话说——你所做的一切都很好。对于简单的情况,可以只使用 src/ 目录中的 .cpp 文件(并让 Rcpp、属性和它的其他兄弟包处理剩下的)

Second question is whether I need a "Map" somewhere in rcppeigen_max_over_columns.cpp so that the matrix isn't copied when it's passed from R to C++?

好吧,当将 R 对象传输到(非 Rcpp)类时,数据几乎总是会被复制,除非您专门使用可以重用底层数据的构造函数。我不知道 Eigen 是否有一个可以重复使用内存的构造函数,但我建议除非你知道它很重要,否则不要担心它(因为复制一系列数据是通常相当快)

关于c++ - RcppEigen - 从内联到包中的 .cpp 函数和 "Map",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27490659/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com