首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RcppArmadillo传递用户定义函数

RcppArmadillo传递用户定义函数
EN

Stack Overflow用户
提问于 2013-01-20 20:02:33
回答 1查看 2.7K关注 0票数 40

考虑下面的R码,

代码语言:javascript
复制
## ----------- R version -----------

caller <- function(x=1:3, fun = "identity", ...){

  ## do some other stuff
  ## ...
  ## then call the function
  eval(call(fun, x))

}

fun1 <- function(x, ...){
  x + x
}

fun2 <- function(x, a = 10) a * x

caller(fun = "fun1")
caller(fun = "fun2")

用户可以传递一个函数名“好玩”,这是由caller使用的。我希望对RcppArmadillo对象执行同样的任务(显然,这是更复杂的任务的一部分)。函数将在C++中定义,用户在R级通过引用其名称来选择它:

代码语言:javascript
复制
caller_cpp(1:3, "fun1_cpp")

代码语言:javascript
复制
caller_cpp(1:3, "fun2_cpp")

等。

下面是我对调用方函数的天真尝试,它甚至无法编译:

代码语言:javascript
复制
## ----------- C++ version -----------

library(Rcpp)
require( RcppArmadillo )    

sourceCpp( code = '

       // [[Rcpp::depends("RcppArmadillo")]]

       #include <RcppArmadillo.h>

       using namespace arma ; 
       using namespace Rcpp ;


       colvec fun1_cpp(const colvec x)
      {
       colvec y ;
       y = x + x;
       return (y);
      }

       colvec fun2_cpp(const colvec x)
      {
       colvec y ;
       y = 10*x;
       return (y);
      }

     // mysterious pointer business in an attempt 
     // to select a compiled function by its name

      typedef double (*funcPtr)(SEXP);
      SEXP putFunPtrInXPtr(SEXP funname) {
            std::string fstr = Rcpp::as<std::string>(funname);
            if (fstr == "fun1")
                return(Rcpp::XPtr<funcPtr>(new funcPtr(&fun1_cpp)));
            else if (fstr == "fun2")
            return(Rcpp::XPtr<funcPtr>(new funcPtr(&fun2_cpp)));

       }

       // [[Rcpp::export]]
       colvec caller_cpp(const colvec x, character funname)
      {
       Rcpp::XPtr fun = putFunPtrInXPtr(funname);
       colvec y ;
       y = fun(x);
       return (y);
      }

   ')

编辑:在按照Dirk的建议查看RcppDE之后对示例进行了修改。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-20 20:10:36

(有时您需要在文件上使用svn log ...来查看它们的日期.)

我认为一个更好的用例是在基于C的DEoptim到Rcpp / RcppArmadillo: RcppDE的“端口”中。在它中,我允许优化例程使用R函数(如DEoptim所做的)或用户提供的编译函数--正如我所理解的,这就是您在这里想要的。

有一点C++脚手架,但您应该没有问题遵循这一点。

编辑在2013-01-21是一个完整的解决方案,我也只是张贴在Rcpp画廊的这篇新文章 -包括一些评论和样本使用。

代码语言:javascript
复制
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

using namespace arma; 
using namespace Rcpp;

vec fun1_cpp(const vec& x) {    // a first function 
    vec y = x + x;
    return (y);
}

vec fun2_cpp(const vec& x) {    // and a second function
    vec y = 10*x;
    return (y);
}

typedef vec (*funcPtr)(const vec& x);

// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr(std::string fstr) {
    if (fstr == "fun1")
        return(XPtr<funcPtr>(new funcPtr(&fun1_cpp)));
    else if (fstr == "fun2")
        return(XPtr<funcPtr>(new funcPtr(&fun2_cpp)));
    else
        return XPtr<funcPtr>(R_NilValue); // runtime error as NULL no XPtr
}

// [[Rcpp::export]]
vec callViaString(const vec x, std::string funname) {
    XPtr<funcPtr> xpfun = putFunPtrInXPtr(funname);
    funcPtr fun = *xpfun;
    vec y = fun(x);
    return (y);
}

// [[Rcpp::export]]
vec callViaXPtr(const vec x, SEXP xpsexp) {
    XPtr<funcPtr> xpfun(xpsexp);
    funcPtr fun = *xpfun;
    vec y = fun(x);
    return (y);
}
票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14428687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档