Zacznij terazZacznij za darmo

Wektory STL

Standardowa biblioteka szablonów (STL) to biblioteka C++ zawierająca elastyczne algorytmy i struktury danych. Na przykład wektor typu double z STL jest odpowiednikiem NumericVector z Rcpp w „natywnym C++". Poniższy kod tworzy standardowy wektor liczb zmiennoprzecinkowych o nazwie x zawierający dziesięć elementów.

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

Na ogół lepiej trzymać się typów wektorów z Rcpp – dają dostęp do wielu wygodnych metod działających jak ich odpowiedniki w R, m.in. mean(), round() i abs(). Wektory STL mają jednak tę zaletę, że mogą dynamicznie zmieniać rozmiar bez kopiowania danych przy każdej zmianie. Dzięki temu można pisać prostszy kod – podobny do funkcji „bad" z poprzedniego ćwiczenia – zachowując przy tym wydajność funkcji „good".

To ćwiczenie jest częścią kursu

Optymalizacja kodu R za pomocą Rcpp

Zobacz kurs

Instrukcje do ćwiczenia

  • Uzupełnij definicję funkcji select_positive_values_std() – funkcji opartej na wektorze STL, która wybiera liczby dodatnie.
    • Ustaw typ zwracany funkcji na standardowy wektor liczb zmiennoprzecinkowych, używając std::vector<double>.
    • Zdefiniuj standardowy wektor liczb zmiennoprzecinkowych positive_x o rozmiarze 0.
    • Wewnątrz bloku if w pętli for użyj metody push_back() na positive_x, aby dołączyć i-ty element wektora x.
  • Funkcja good_select_positive_values_cpp() z poprzedniego ćwiczenia jest dostępna w twoim środowisku pracy – możesz jej użyć do porównania. Sprawdź wyniki w konsoli, aby zobaczyć różnicę w szybkości działania obu funkcji.

Interaktywne ćwiczenie praktyczne

Spróbuj tego ćwiczenia, uzupełniając ten przykładowy kod.

#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)
)
*/
Edytuj i uruchom kod