2011-03-01 14 views
6

Desde anoche he estado probando Rcpp y inline, y hasta ahora estoy realmente disfrutando. Pero soy un poco nuevo en el C en general y solo puedo hacer cosas básicas todavía, y estoy teniendo dificultades para encontrar ayuda en línea en cosas como funciones.Encontrar mínimo de vector en Rcpp

Algo en lo que estaba trabajando era una función que encuentra el mínimo de un vector en el entorno global. Se me ocurrió:

library("inline") 
library("Rcpp") 

foo <- rnorm(100) 

bar <- cxxfunction(signature(), 
' 
Environment e = Environment::global_env(); 
NumericVector foo = e["foo"]; 
int min; 

for (int i = 0; i < foo.size(); i++) 
{ 
    if (foo[i] < foo[min]) min = i; 
} 
return wrap(min+1); 
', plugin = "Rcpp") 

bar() 

pero parece que no debe haber una manera más fácil de hacer esto, y es bastante más lento que which.max()

system.time(replicate(100000,bar())) 
    user system elapsed 
    0.27 0.00 0.26 
system.time(replicate(100000,which.min(foo))) 
    user system elapsed 
    0.2  0.0  0.2 

estoy pasando por alto una función básica c++ o Rcpp que ¿Haz esto? Y si es así, ¿dónde podría encontrar una lista de tales funciones?

supongo que esta pregunta está relacionada con: Where can I learn how to write C code to speed up slow R functions?

pero diferente en que no estoy realmente interesado en cómo incorporar c++ en R, pero más sobre cómo y dónde aprender código básico c++ que se puede utilizar en R.

+1

Dudo mucho que acelere las operaciones como mínimo y máximo con C++; probablemente ya estén implementadas con instrucciones SSE (rápidas) en R. Además, la transición de C++ a R y viceversa no es gratuita. –

+0

Me doy cuenta de que esto es más conceptual, y esto es parte de una función C++ mucho más grande que estoy tratando de implementar en R. –

Respuesta

9

Me alegra encontrar la Rcpp útil.

El primer comentario de Billy es bastante correcto. Hay una sobrecarga en la búsqueda de funciones y hay una sobrecarga en la búsqueda [] para cada elemento, etc.

Además, un enfoque mucho más común es tomar un vector que tiene en R, pasarlo a una función compilada que crea a través de en línea y Rcpp, y que devuelva el resultado. Trata eso. Hay muchos ejemplos en el paquete y dispersos en los archivos de la lista de correo rcpp-devel.

Edit: No pude evitar intentar configurar una respuesta de estilo muy C++/STL.

R> src <- ' 
+ Rcpp::NumericVector x(xs); 
+ Rcpp::NumericVector::iterator it =  // iterator type 
+  std::min_element(x.begin(), x.end()); // STL algo 
+ return Rcpp::wrap(it - x.begin()); ' 
R> minfun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp") 
R> minfun(c(7:20, 3:5)) 
[1] 14 
R> 

Eso no es exactamente la respuesta más fácil pero muestra cómo mediante el uso de lo que ofrece C++ se puede encontrar un elemento mínimo sin un bucle (explícito) incluso en el nivel C++. Pero la función integrada min() es aún más rápida.

* Editar 2: corregido según el comentario de Romain a continuación.

+0

Pero su versión STL implementa 'min', que no es lo que Sacha quería:' which.min '. –

+1

Bien visto - pero como 'min_element()' devuelve un iterador, podemos arreglarlo fácilmente como acabo de hacerlo - en el ejemplo ahora (correctamente) devuelve 14. –

+0

Rcpp 0.9.16 tendrá 'which_min' –

Cuestiones relacionadas