Vectores de la STL
La standard template library (stl) es una biblioteca de C++ que incluye algoritmos y estructuras de datos flexibles. Por ejemplo, el vector de dobles de la stl es el equivalente "C++ nativo" del NumericVector de Rcpp. El siguiente código crea un vector estándar de dobles llamado x con diez elementos.
std::vector<double> x(10);
Normalmente tiene más sentido quedarse con los tipos de vector de Rcpp porque te dan acceso a muchos métodos prácticos que funcionan como sus equivalentes en R, incluidos mean(), round() y abs(). Sin embargo, los vectores de la stl tienen la ventaja de que pueden cambiar de tamaño dinámicamente sin pagar el coste de copiar los datos cada vez. Eso nos permite escribir un código más sencillo, como la función "mala" del ejercicio anterior, manteniendo el rendimiento del código "bueno".
Este ejercicio forma parte del curso
Optimizar código de R con Rcpp
Instrucciones del ejercicio
- Completa la definición de
select_positive_values_std(), una función basada en vectores de la stl para seleccionar números positivos.- Establece el tipo de retorno de la función como un vector estándar de dobles usando
std::vector<double>. - Define un vector estándar de dobles,
positive_x, con tamaño0. - Dentro del bloque
ifen el buclefor, usapush_back()depositive_xpara añadir el elemento i-ésimo dex.
- Establece el tipo de retorno de la función como un vector estándar de dobles usando
good_select_positive_values_cpp()del ejercicio anterior está disponible en tu espacio de trabajo para comparar. Examina la salida de la consola para ver la velocidad relativa de las dos funciones.
Ejercicio interactivo práctico
Prueba este ejercicio y completa el código de muestra.
#include
using namespace Rcpp;
// Set the return type to a standard double vector
// [[Rcpp::export]]
___ select_positive_values_std(NumericVector x) {
int n = x.size();
// Create positive_x, a standard double vector
___;
for(int i = 0; i < n; i++) {
if(x[i] > 0) {
// Append the ith element of x to positive_x
___;
}
}
return positive_x;
}
/*** R
set.seed(42)
x <- rnorm(1e6)
# Does it give the same answer as R?
all.equal(select_positive_values_std(x), x[x > 0])
# Which is faster?
microbenchmark(
good_cpp = good_select_positive_values_cpp(x),
std = select_positive_values_std(x)
)
*/