RcppArmadillo übergeben benutzerdefinierte Funktion

Betrachten Sie den folgenden R-Code,

## ----------- 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")

Der Benutzer kann einen Funktionsnamen "fun" übergeben, der von verwendet wirdcaller. Ich möchte die gleiche Aufgabe mit ausführenRcppArmadillo Objekte (offensichtlich als Teil einer komplexeren Aufgabe). Die Funktion würde in definiert werdenC++und der Benutzer wählt es auf der R-Ebene aus, indem er sich auf seinen Namen bezieht:

caller_cpp(1:3, "fun1_cpp")

oder

caller_cpp(1:3, "fun2_cpp")

usw.

Hier ist mein naiver Versuch für die Caller-Funktion, die sogar nicht kompiliert werden kann:

## ----------- 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);
      }

   ')

Bearbeiten: hat das Beispiel angepasst, nachdem Dirk vorgeschlagen hatte, sich RcppDE anzuschauen.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage