user-2147482565
user-2147482565

Reputation: 463

How to pass in functions as arguments in Rcpp / C++?

I'm trying to write a function which can take in functions as its arguments in Rcpp. I have written an example function in R that shows the kind of functionality that I'm aiming for:

simulate_and_evaluate <- function(simulate, evaluate) {
  y <- simulate(1)
  eval <- evaluate(y)
  return(eval)
}

simulate_fun <- function(n) rnorm(n, 0, 1)
evaluate_fun <- function(x) dnorm(x, 0, 1)

simulate_and_evaluate(simulate = simulate_fun,
                      evaluate = evaluate_fun)

In this function simulate_and_evaluate, this takes in two arguments which are both functions, one that simulates a number and one that evaluates a function with this simualted number. So as an example, we can simulate a value from a standard normal and evaluate the density of a standard normal at that point. Does anyone know if there's a way to do this in Rcpp?

Upvotes: 0

Views: 491

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368181

Rcpp aims for seamless interfacing of R and C++ objects. As functions are first class R objects represented internally as a type a SEXP can take, we can of course also ship them with Rcpp. There are numerous examples.

So here we simply rewrite your function as a C++ function:

Rcpp::cppFunction("double simAndEval(Function sim, Function eval) {
  double y = as<double>(sim(1));
  double ev = as<double>(eval(y));
  return(ev);
}")

And we can then set the RNG to the same value, run your R function and this C++ function and get the same value. Which is awesome.

R> set.seed(123)
R> simulate_and_evaluate(simulate = simulate_fun,
+ evaluate = evaluate_fun)
[1] 0.341
R> set.seed(123) # reset RNG
R> simAndEval(simulate_fun, evaluate_fun)
[1] 0.341
R> 

But as @MrFlick warned you, this will not run any faster because we added no compiled execution of the actual functions we are merely calling them from C++ rathern than R.

The topic has been discussed before. Please search StackOverflow, maybe with a string [rcpp] Function to get some meaningful hits.

Upvotes: 6

Related Questions