CommencezCommencez gratuitement

Vecteurs de la STL

La bibliothèque standard template (STL) est une bibliothèque C++ qui regroupe des algorithmes et des structures de données flexibles. Par exemple, le vecteur de doubles de la STL est l'équivalent « C++ natif » du NumericVector de Rcpp. Le code suivant crée un vecteur standard de doubles nommé x comptant dix éléments.

std::vector<double> x(10);

En général, il est préférable d'utiliser les types de vecteurs Rcpp, car ils donnent accès à de nombreuses méthodes pratiques semblables à celles de R, comme mean(), round() et abs(). Toutefois, les vecteurs de la STL ont l'avantage de pouvoir changer de taille dynamiquement sans payer le coût d'une copie des données à chaque fois. Cela nous permet d'écrire du code plus simple, comme la fonction « mauvaise » du précédent exercice, tout en conservant la performance du code « bon ».

Cette activité fait partie du cours

Optimiser le code R avec Rcpp

Voir le cours

Instructions de l’exercice

  • Complétez la définition de select_positive_values_std(), une fonction basée sur les vecteurs de la STL pour sélectionner les nombres positifs.
    • Définissez le type de retour de la fonction comme un vecteur standard de doubles à l'aide de std::vector<double>.
    • Déclarez un vecteur standard de doubles, positive_x, de taille 0.
    • À l'intérieur du bloc if dans la boucle for, utilisez la méthode push_back() de positive_x pour y ajouter le iᵉ élément de x.
  • good_select_positive_values_cpp() de l'exercice précédent est disponible dans votre espace de travail pour comparaison. Examinez la sortie de la console pour voir la vitesse relative des deux fonctions.

Exercice interactif pratique

Essayez cet exercice en complétant ce code d’exemple.

#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)
)
*/
Modifier et exécuter le code