IniziaInizia gratis

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

Visualizza il corso

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 double usando std::vector<double>.
    • Definisci un vettore standard di double, positive_x, con dimensione 0.
    • All'interno del blocco if nel ciclo for, usa push_back() di positive_x per aggiungere l’elemento i-esimo di x.
  • 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)
)
*/
Modifica ed esegui il codice