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,
NumericMatrix
instead of SEXP
for the argument, or vice versa? &
? 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.
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.
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.
Rcpp sugar defines the usual binary arithmetic operators : +, -, *, /. // two numeric vectors of the same size. NumericVector x ; NumericVector y ; // expressions involving two vectors.
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.
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.
SEXP
, ever. mat_4
from another C++ function. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With