Vettori STL
La Standard Template Library (STL) è una libreria C++ che contiene algoritmi e strutture dati flessibili. Per esempio, il vettore di double della STL è l'equivalente "C++ nativo" del NumericVector di Rcpp. Il codice seguente crea un vettore standard di double chiamato x con dieci elementi.
std::vector<double> x(10);
In genere ha più senso restare sui tipi di vettore di Rcpp perché ti danno accesso a molti metodi pratici che funzionano come gli equivalenti in R, inclusi mean(), round() e abs(). Tuttavia, i vettori STL hanno il vantaggio di poter cambiare dimensione dinamicamente senza dover copiare i dati ogni volta. Questo ci permette di scrivere codice più semplice, come la funzione "bad" dell'esercizio precedente, mantenendo però le prestazioni del codice "good".
Questo esercizio fa parte del corso
Ottimizzare il codice R con Rcpp
Istruzioni dell'esercizio
- Completa la definizione di
select_positive_values_std(), una funzione basata su vettori STL che seleziona i numeri positivi.- Imposta il tipo di ritorno della funzione a un vettore standard di
doubleusandostd::vector<double>. - Definisci un vettore standard di
double,positive_x, con dimensione0. - All'interno del blocco
ifnel ciclofor, usapush_back()dipositive_xper aggiungere l’elemento i-esimo dix.
- Imposta il tipo di ritorno della funzione a un vettore standard di
good_select_positive_values_cpp()dell'esercizio precedente è disponibile nel tuo workspace per confronto. Esamina l'output della console per vedere le velocità relative delle due funzioni.
Esercizio pratico interattivo
Prova a risolvere questo esercizio completando il codice di esempio.
#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)
)
*/