@hadley: desafortunadamente, no tengo recursos específicos en mente para ayudarlo a comenzar con C ++. Lo tomé de los libros de Scott Meyers (C ++ efectivo, C ++ más efectivo, etc.) pero estos no son realmente lo que uno podría llamar introductorios.
Usamos casi exclusivamente la interfaz .Call para llamar al código C ++. La regla es bastante fácil:
- La función C ++ debe devolver un objeto R. Todos los objetos R son SEXP.
- La función C ++ toma entre 0 y 65 objetos R como entrada (nuevamente SEXP)
- debe (no realmente, pero podemos guardar para más tarde) ser declarado con C vinculación, ya sea con extern "C" o la RcppExport alias que define RCPP.
Entonces, una función .Call se declara así en algún archivo de encabezado:
#include <Rcpp.h>
RcppExport SEXP foo( SEXP x1, SEXP x2 ) ;
e implementado así en un archivo .cpp:
SEXP foo( SEXP x1, SEXP x2 ){
...
}
No hay mucho más que saber sobre la API de R para usar Rcpp.
La mayoría de la gente solo quiere trabajar con vectores numéricos en Rcpp. Haz esto con la clase NumericVector. Hay varias formas de crear un vector numérico:
De un objeto existente que pasa de R:
SEXP foo( SEXP x_) {
Rcpp::NumericVector x( x_ ) ;
...
}
Con valores dados usando la función :: crear estática:
Rcpp::NumericVector x = Rcpp::NumericVector::create( 1.0, 2.0, 3.0 ) ;
Rcpp::NumericVector x = Rcpp::NumericVector::create(
_["a"] = 1.0,
_["b"] = 2.0,
_["c"] = 3
) ;
De un tamaño dado:
Rcpp::NumericVector x( 10 ) ; // filled with 0.0
Rcpp::NumericVector x( 10, 2.0 ) ; // filled with 2.0
Luego, una vez que tenga un vector, lo más útil es extraer un elemento de él. Esto se hace con el operador [], con indexación basada en 0, por lo que, por ejemplo, la suma de valores de un vector numérico es algo como esto:
SEXP sum( SEXP x_ ){
Rcpp::NumericVector x(x_) ;
double res = 0.0 ;
for( int i=0; i<x.size(), i++){
res += x[i] ;
}
return Rcpp::wrap( res ) ;
}
Pero con el azúcar Rcpp podemos hacer esto mucho mejor ahora:
using namespace Rcpp ;
SEXP sum( SEXP x_ ){
NumericVector x(x_) ;
double res = sum( x ) ;
return wrap( res ) ;
}
Como dije antes, todo depende del tipo de código que quieras escribir. Mire qué hace la gente en los paquetes que dependen de Rcpp, revise las viñetas, las pruebas unitarias, regrese a nosotros en la lista de correo. Siempre estamos felices de ayudar.