Simula un modello MA(q)
I modelli a media mobile (MA) dipendono anch'essi dall'iterazione precedente. A differenza dei modelli AR, però, la dipendenza riguarda la parte di rumore.
Ecco l'algoritmo in R:
ma1 <- function(n, mu, theta, sd) {
q <- length(theta)
x <- numeric(n)
eps <- rnorm(n, 0, sd)
for(i in seq(q + 1, n)) {
value <- mu + eps[i]
for(j in seq_len(q)) {
value <- value + theta[j] * eps[i - j]
}
x[i] <- value
}
x
}
n è il numero di osservazioni simulate, mu è il valore atteso, theta è un vettore numerico di coefficienti della media mobile e sd è la deviazione standard del rumore.
All'inizio del capitolo hai usato R::rnorm() per generare un singolo numero da una distribuzione normale. Esiste anche Rcpp::rnorm(), che può generare in una volta un intero vettore numerico. Accetta gli stessi argomenti della rnorm() di R.
Completa la definizione della funzione ma2(), una traduzione in C++ di ma1().
Questo esercizio fa parte del corso
Ottimizzare il codice R con Rcpp
Istruzioni dell'esercizio
- Genera il vettore del rumore come
eps. Usarnorm()dallo spazio dei nomiRcpp(non dallo spazio dei nomiR). - Nel ciclo for esterno, calcola
valuecomemupiù il valore di rumore in posizionei. - Nel ciclo for interno, aumenta
valuedelj-esimo elemento dithetamoltiplicato per l'elemento"i" menojmeno1` dieps`. - Dopo i cicli, imposta l'elemento
i-esimo dixavalue.
Esercizio pratico interattivo
Prova a risolvere questo esercizio completando il codice di esempio.
#include
using namespace Rcpp ;
// [[Rcpp::export]]
NumericVector ma2( int n, double mu, NumericVector theta, double sd ){
int q = theta.size();
NumericVector x(n);
// Generate the noise vector
NumericVector eps = ___(___, 0.0, ___);
// Loop from q to n
for(int i = q; i < n; i++) {
// Value is mean plus noise
double value = ___ + ___;
// Loop from zero to q
for(int j = 0; j < q; j++) {
// Increase by the jth element of theta times
// the "i minus j minus 1"th element of eps
value += ___ * ___;
}
// Set ith element of x to value
___ = ___;
}
return x ;
}
/*** R
d <- data.frame(
x = 1:50,
y = ma2(50, 10, c(1, -0.5), 1)
)
ggplot(d, aes(x, y)) + geom_line()
*/