Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare input into Rcpp functions?

Tags:

c++

r

rcpp

I am an absolute Rcpp-beginner, so please be warned that a beginner's question is about to come.

Consider this example:

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix mat_1(NumericMatrix X){
 do.stuff.with.X
}

My understanding is that this defines a function mat_1 in the workspace of R that takes a numeric matrix as an input and returns a numeric matrix in the end. However, looking e.g. here I understand that I can also define

SEXP mat_2(SEXP X){
Rcpp::NumericMatrix x(X);                 
 do.stuff.with.x
}

or alternatively

SEXP mat_3(SEXP X){
NumericMatrix x(as<NumericMatrix>(X))
 do.stuff.with.x
}

My understanding is that this defines the output of the function as an S-expression, and it requires an S-expression as an input, which is internally converted (?) to a numeric matrix.

Now, looking at this document, which has been a very valuable resource to me, I learn that I can also write

NumericMatrix mat_4( NumericMatrix X&){
 do.stuff.with.X
}

Here, my understanding is that instead of making a copy of X, the Rcpp-function uses a reference to the R object. I am actually not sure I understand what this means. Wasn't the point of using SEXP that no copy is made, or did I get something wrong? Also, if it saves memory and is thus more efficient, why would I ever use something else?

I am sure I missed some options. Anyway, my big question is this: from the point of view of the R user (me), I call each function mat_1, mat_2, mat_3 or mat_4 supplying a numeric matrix (which is an R object in my workspace, and hence an SEXP), and it seems I should get the same output (a numeric matrix, which will be a SEXP anyway from R's perspective, right?). I would appreciate some guidance as to the relative merits of these seemingly identical ways to define a function. That is, assuming we know exactly what the function input will be and what the output will be,

  1. Why and when does it pay off to use NumericMatrix instead of SEXP for the argument, or vice versa?
  2. Why and when to use &?
  3. If I know the function will return a numeric matrix, are there reasons to declare the function as a SEXP? Are there reasons to stick to NumericMatrix?

Or am I completely missing the point?

Furthermore, is there any practial difference between the conversion used in mat_2 and mat_3? That is, are there differences between Rcpp::NumericMatrix x(X) and NumericMatrix x(as<NumericMatrix>(X))?

Any feedback is appreciated.

like image 285
coffeinjunky Avatar asked Jul 23 '14 22:07

coffeinjunky


People also ask

How to call r function in Rcpp?

Using the Function class, you can call R functions from Rcpp. The argument given to the R function is determined based on position and name. Use Named() or _[] to pass a value to an argument by specifying argument name.

How Rcpp works?

In particular, Rcpp is designed to facilitate interfacing libraries written in C++ or C to R. Hence, if there is a specific feature within a C++ or C library, then one can create a bridge to it using Rcpp to enable it from within R.

What is RCPP sugar?

Rcpp sugar defines the usual binary arithmetic operators : +, -, *, /. // two numeric vectors of the same size. NumericVector x ; NumericVector y ; // expressions involving two vectors.

What is RCPP package?

The 'Rcpp' package provides R functions as well as C++ classes which offer a seamless integration of R and C++. Many R data types and objects can be mapped back and forth to C++ equivalents which facilitates both writing of new code as well as easier integration of third-party libraries.


1 Answers

Alright. Trying to give some clues. First of all, if you are a beginner, you got it right with the first function, use mat_1. As your skills improve, you might understand some of the differences between mat_1 and the other one, and eventually move to ... use mat_1, because that's the one you want to use.

  1. Always. Most users should not use SEXP, ever.
  2. It does not make a difference in this case. Rcpp will know what to do with the reference, but what happens is pretty much the same, it creates an object locally somewhere and gives you a reference to it. The distinction between pass by value and by reference makes a difference if you were to call if you were to call mat_4 from another C++ function.
  3. If you know the type, use the type. That's the whole point of Rcpp. SEXP is R's catch all type, if you return a SEXP it can be anything, if you return a NumericMatrix you know by design that you return a numeric matrix, huge advantage and pretty much the whole reason Rcpp exists.

I let you decide if you were missing the point.

In general as<> will tend to try harder, but it does not make a difference in that case.

In short: use mat_1. There's lots of other stuff to learn, don't concern yourself with this yet.

like image 59
Romain Francois Avatar answered Sep 21 '22 11:09

Romain Francois