Clonazione di vettori
Diversamente da R, C++ usa un sistema di copia per riferimento, il che significa che se copi una variabile e poi modifichi la copia, le modifiche avverranno anche nell'originale.
// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
// Crea una copia
NumericVector y = x;
// Modifica la copia
y[0] = 2;
// Le modifiche avvengono anche nell'originale
return x[0];
}
Per evitare questo comportamento, devi usare la funzione clone() per copiare i dati sottostanti dalla variabile originale in quella nuova. La sintassi è y = clone(x).
In questo esercizio, abbiamo definito per te due funzioni:
change_negatives_to_zero(): prende un vettore numerico, lo modifica sostituendo i numeri negativi con zero, quindi restituisce sia il vettore originale sia la copia.change_negatives_to_zero_with_cloning(): fa la stessa cosa di sopra, ma clona il vettore originale prima di modificarlo.
Questo esercizio fa parte del corso
Ottimizzare il codice R con Rcpp
Istruzioni dell'esercizio
- Completa la definizione della funzione
change_negatives_to_zero()impostandothe_copyuguale athe_original. - Completa la definizione della funzione
change_negatives_to_zero_with_cloning()impostandothe_copyuguale al clone dithe_original. - Leggi i contenuti della console per confrontare l'output di ciascuna funzione.
Esercizio pratico interattivo
Prova a risolvere questo esercizio completando il codice di esempio.
#include
using namespace Rcpp;
// [[Rcpp::export]]
List change_negatives_to_zero(NumericVector the_original) {
// Set the copy to the original
NumericVector the_copy = ___;
int n = the_original.size();
for(int i = 0; i < n; i++) {
if(the_copy[i] < 0) the_copy[i] = 0;
}
return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}
// [[Rcpp::export]]
List change_negatives_to_zero_with_cloning(NumericVector the_original) {
// Clone the original to make the copy
NumericVector the_copy = ___;
int n = the_original.size();
for(int i = 0; i < n; i++) {
if(the_copy[i] < 0) the_copy[i] = 0;
}
return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}
/*** R
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero(x)
# Need to define x again because it's changed now
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero_with_cloning(x)
*/