Aan de slagGa gratis aan de slag

STL-vectors

De standard template library (stl) is een C++-bibliotheek met flexibele algoritmen en datastructuren. Zo is de double vector uit de stl het "native C++"-equivalent van Rcpp’s NumericVector. De volgende code maakt een standaard double vector x met tien elementen.

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

Meestal is het handiger om Rcpp-vector­typen te gebruiken, omdat je dan veel handige methoden hebt die werken zoals in R, zoals mean(), round() en abs(). STL-vectors hebben echter het voordeel dat ze hun grootte dynamisch kunnen aanpassen zonder elke keer de data te kopiëren. Daardoor kun je eenvoudigere code schrijven, zoals de "slechte" functie uit de vorige oefening, terwijl je toch de prestaties van de "goede" code behoudt.

Deze oefening maakt deel uit van de cursus

R-code optimaliseren met Rcpp

Cursus bekijken

Oefeninstructies

  • Maak de definitie af van select_positive_values_std(), een op stl-vectors gebaseerde functie om positieve getallen te selecteren.
    • Stel het retourtype van de functie in op een standaard double vector met std::vector<double>.
    • Definieer een standaard double vector, positive_x, met grootte 0.
    • Gebruik binnen het if-blok in de for-lus de push_back() van positive_x om het i-de element van x toe te voegen.
  • good_select_positive_values_cpp() uit de vorige oefening staat in je workspace ter vergelijking. Bekijk de console-uitvoer om de relatieve snelheid van de twee functies te zien.

Praktische interactieve oefening

Probeer deze oefening eens door deze voorbeeldcode in te vullen.

#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)
)
*/
Code bewerken en uitvoeren