Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make inline C++ function calls in R?

Tags:

c++

r

inline

rcpp

All right, so I'm programming in R and I want to make a C++ function. I've imported the Rcpp and inline libraries. For right now, I'm just trying to make a simple function that adds 2 numbers, but no matter what I try, I get errors.

Here's my code:

cppstring = 'double ss = RcppSexp(s).asDouble(); return RcppSexp(ss+4).asSexp();'
hi <- cfunction(body=cppstring, signature(s="double"), Rcpp = TRUE)

and when I enter that second line, I get

file628a34ce.cpp: In function ‘SEXPREC* file628a34ce(SEXPREC*)’:
file628a34ce.cpp:9: error: ‘RcppSexp’ was not declared in this scope
make: *** [file628a34ce.o] Error 1

ERROR(s) during compilation: source code errors or compiler configuration errors!

Program source:
1: #include <Rcpp.h>
2: 
3: 
4: extern "C" {
5:   SEXP file628a34ce ( SEXP s );
6: }
7: 
8: SEXP file628a34ce ( SEXP s ) {
9: double ss = RcppSexp(s).asDouble(); return RcppSexp(ss+4).asSexp();
10:   Rf_warning("your C program does not return anything!");
11:   return R_NilValue;
12: }
Error in compileCode(f, code, language, verbose) : 
Compilation ERROR, function(s)/method(s) not created! file628a34ce.cpp: In function    ‘SEXPREC* file628a34ce(SEXPREC*)’:
file628a34ce.cpp:9: error: ‘RcppSexp’ was not declared in this scope
make: *** [file628a34ce.o] Error 1

I've tried everything I could possibly think of, from casting, to moving code around, to #including RcppSexp, to just plain returning s, and every time I get some error, whether it's

cannot convert ‘double’ to ‘SEXPREC*’ in return

or

invalid use of undefined type ‘struct SEXPREC’

or

forward declaration of ‘struct SEXPREC’

...I'm so confused :( I've looked at several examples online, and what I currently have seems to be what everyone else is doing, and it magically works for them...

What is this SEXPREC* thing I keep seeing everywhere? And what is that extern "C" function thing that it makes? And why does it generate statements AFTER my return statement and tell me that my function doesn't return anything, even though it does?

like image 673
Pojo Avatar asked Feb 22 '23 15:02

Pojo


1 Answers

Is there a reason you are not starting from the (literally!!) dozens of Rcpp examples using inline?

Also, what on earth is RcppSexp? What documentation are your following?

Here is an example I did last night for someone on the rcpp-devel (which you should probably join):

library(Rcpp)
library(inline)

xorig <- c(1, -2, 3, -4, 5, -6, 7)

code <- '
    Rcpp::NumericVector x(xs);
    Rcpp::NumericVector xa = sapply( x, ::fabs );
    return(xa);
    '

xabs <- cxxfunction(signature(xs="numeric"),
                    plugin="Rcpp",
                    body=code)

xabs(xorig)

This is a more advanced example as it uses Rcpp sugar to give us vectorised expression a la R in C++, which we demonstrate here with a the simple sapply() from Rcpp sugar:

R> library(Rcpp)
R> library(inline)
R> 
R> xorig <- c(1, -2, 3, -4, 5, -6, 7)
R> 
R> code <- '
+     Rcpp::NumericVector x(xs);
+     Rcpp::NumericVector xa = sapply( x, ::fabs );
+     return(xa);
+     '
R> 
R> xabs <- cxxfunction(signature(xs="numeric"),
+                     plugin="Rcpp",
+                     body=code)
R> 
R> xabs(xorig)
[1] 1 2 3 4 5 6 7
R> 

This most clearly demonstrates two of your requests: we use the implicit template converters as<>() to go from a SEXP given from R to the initial vector, and then use the implicit template converter wrap() to return the transformed second vector.

All this is explained in detail in the Rcpp-introduction vignette and the other vignettes in the Rcpp documentation,.

like image 145
Dirk Eddelbuettel Avatar answered Feb 25 '23 12:02

Dirk Eddelbuettel