consideri il seguente codice R,RcppArmadillo passaggio definito dall'utente funzione
## ----------- 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")
L'utente può passare un nome funzione "fun", che viene utilizzato da caller
. Desidero eseguire lo stesso compito con gli oggetti RcppArmadillo
(come parte di un'attività più complessa, ovviamente). La funzione dovrebbe essere definita in C++
, e l'utente lo seleziona a livello di R facendo riferimento al suo nome:
caller_cpp(1:3, "fun1_cpp")
o
caller_cpp(1:3, "fun2_cpp")
ecc
Ecco il mio tentativo ingenuo per la funzione del chiamante, che non riesce nemmeno a compilare:
## ----------- 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);
}
')
Modifica: adattato l'esempio dopo aver seguito il suggerimento di Dirk per esaminare RcppDE.
grazie, cercherò questo! spero che la mia totale ignoranza di C++ non mi impedisca di copiare e incollare ancora le cose. – baptiste
Sfortunatamente c'è un po 'troppo in RcppDE per me da seguire. In 'evaluate.h' vedo la definizione di nuove classi, alcune presumibilmente chiamano una funzione arbitraria R, altre (immagino) chiamano una funzione C++ (voglio solo quest'ultima). Se un'anima gentile ha tempo da perdere, sarebbe un ottimo esempio per quanto riguarda la bella http://gallery.rcpp.org/. – baptiste
leggere la vignetta conferma l'impressione che ho avuto guardando il codice. Se voglio occuparmi solo di funzioni compilate, selezionate in base al loro nome, ho bisogno di questo business di classe virtuale? – baptiste