LoslegenKostenlos loslegen

STL-Vektoren

Die Standard Template Library (stl) ist eine C++-Bibliothek mit flexiblen Algorithmen und Datenstrukturen. Der Double-Vektor aus der stl ist zum Beispiel das „native C++“-Äquivalent zu Rcpps NumericVector. Der folgende Code erzeugt einen Standard-Double-Vektor namens x mit zehn Elementen.

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

In der Regel ist es sinnvoller, bei Rcpp-Vektortypen zu bleiben, weil du damit viele Komfortmethoden bekommst, die wie ihre R-Pendants funktionieren, darunter mean(), round() und abs(). Die stl-Vektoren haben jedoch den Vorteil, dass sie ihre Größe dynamisch ändern können, ohne jedes Mal die Daten kopieren zu müssen. So können wir einfacheren Code schreiben, etwa wie die „schlechte“ Funktion aus der vorherigen Übung, und trotzdem die Performance des „guten“ Codes beibehalten.

Diese Übung ist Teil des Kurses

R-Code mit Rcpp optimieren

Kurs anzeigen

Anleitung zur Übung

  • Vervollständige die Definition von select_positive_values_std(), einer auf stl-Vektoren basierenden Funktion, die positive Zahlen auswählt.
    • Setze den Rückgabetyp der Funktion auf einen Standard-Double-Vektor mit std::vector<double>.
    • Definiere einen Standard-Double-Vektor positive_x mit der Größe 0.
    • Nutze innerhalb des if-Blocks in der for-Schleife die Methode push_back() von positive_x, um das i-te Element von x anzuhängen.
  • good_select_positive_values_cpp() aus der vorherigen Übung steht dir zum Vergleich in deinem Workspace zur Verfügung. Sieh dir die Konsolenausgabe an, um die relativen Geschwindigkeiten der beiden Funktionen zu vergleichen.

Interaktive Übung

Vervollständige den Beispielcode, um diese Übung erfolgreich abzuschließen.

#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 bearbeiten und ausführen