├── README.md ├── Errata.md ├── chap6.md └── textRcode.md /README.md: -------------------------------------------------------------------------------- 1 | tsa4 2 | 3 | #### ✨ Here is [A Road Map](https://nickpoison.github.io/) if you want a broad view of what is available. 4 | 5 | ✨ Follow this link if you are looking for the [5th Edition](https://github.com/nickpoison/tsa5/) 6 | 7 |
8 | 9 | ## tsa4 10 | 11 | - All the (updated) code used in the text is in [textRcode.md](https://github.com/nickpoison/tsa4/blob/master/textRcode.md) 12 | 13 | 14 | - Edition 4 errata is here: [Errata](https://github.com/nickpoison/tsa4/blob/master/Errata.md) 15 | 16 | 17 | ## astsa 18 | 19 | - The home of [astsa - the package for the text](https://github.com/nickpoison/astsa) is here too. 20 | 21 | - See the [NEWS](https://github.com/nickpoison/astsa/blob/master/NEWS.md) for further details about the state of the package and the changelog. 22 | 23 | - A demonstration of the capabilities of `astsa` can be found here at 24 | [**FUN WITH ASTSA**](https://github.com/nickpoison/astsa/blob/master/fun_with_astsa/fun_with_astsa.md) 25 | 26 | 27 | ## python 28 | 29 | - The [code in the first 3 chapters of the text has been converted to Python here.](https://github.com/borisgarbuzov/tsa4-python/tree/master/src) 30 | 31 | - And a [Python package that contains datasets from `astsa` is here.](https://pypi.org/project/astsadata/) 32 | 33 | - _Why use Python if you can use R?_     -Mr Natural 34 | 35 |    mr natch 36 | 37 | -------------------------------------------------------------------------------- /Errata.md: -------------------------------------------------------------------------------- 1 | ## Edition 4 Errata 2 | 3 | _[aides who called tRump a moron](https://www.politico.com/story/2018/09/04/trumps-insults-idiot-woodward-806455) ... now let's go_ 4 | 5 |
6 | 7 | ### Chapter 1 8 | 9 | - it's perfect 10 | 11 | ### Chapter 2 12 | 13 | __Eq (2.38)-(2.39):__ To be more general, the time subscript should have been $t_i$ so the equations would read $$m_t = \sum_{i=1}^n w_i(t) x_{t_i} \tag{2.38}$$ where

14 | $$~~~~~~~~~~~~~~~~~~~~~~~~w_i(t)= K\bigl(\tfrac{t-{t_i}}{b}\bigr) \Bigm/ \sum_{j=1}^n K\bigl(\tfrac{t-{t_j}}{b}\bigr) \tag{2.39}$$ 15 |

16 | ... and typically $K(z)=\exp(-z^2/2)$ is used (no need for constants because the weights are normalized). 17 | 18 | 19 | So these two are the same: 20 | ```r 21 | par(mfrow=c(2,1)) 22 | tsplot(soi) # monthly data; frequency=12 and t = 1/12, 2/12, ... 23 | lines(ksmooth(time(soi), soi, kernel="normal", bandwidth=1), lwd=2, col=4) 24 | # and 25 | SOI = ts(soi, frequency=1) # change to t = 1,2,... 26 | tsplot(SOI) 27 | lines(ksmooth(time(SOI), SOI, kernel="normal", bandwidth=12), lwd=2, col=4) 28 | ``` 29 | 30 | 31 | 32 | ### Chapter 3 33 | 34 | - __Eq (3.10):__ The sum should be to $k$ (and not $k-1$): $~x_t = \phi^{-k} x_{t+k} - \sum_{j=1}^{k} \phi^{-j} w_{t+j}\,.$ 35 | 36 | 37 | ### Chapter 4 38 | 39 | - as if 40 | 41 | 42 | ### Chapter 5 43 | 44 | - __Example 5.1:__ I put this note on the R code page, but I thought I'd repeat it here. 45 | In Example 5.1, we used fracdiff, but it's not a very good package. 46 | We should have used another package such as arfima, but unfortunately it didn't make it into the revision. This is changed in Edition 5: 47 | 48 | ```r 49 | library(arfima) 50 | summary(varve.fd <- arfima(log(varve))) # d.hat = 0.3728, se(d,hat) = 0.0273 51 | # residual stuff 52 | innov = resid(varve.fd) 53 | plot.ts(innov[[1]]) 54 | acf(innov[[1]]) 55 | ``` 56 | 57 | ### Chapter 6 58 | 59 | - __Property 6.7, equation (6.137):__ Left off the conditioning arguments ... the $\pi_j(t)$ in the numerator and in the denominator should be $\pi_j(t \mid t-1)$ . 60 | 61 | - __Example 6.13:__ There is a correction in the code for this example. The correction has been made here [textRcode](https://github.com/nickpoison/tsa4/blob/master/textRcode.md). Under Example 6.13 code, the correction is for bootstrapping (lines 60-63) and the results are a little different (but the discussion is still correct): 62 | 63 | ```r 64 | for (j in k){ # this is line 60 65 | K = (phi*Pp[j-1]*z[j-1])/sig[j-1] 66 | xp.star[j] = phi*xp.star[j-1] + Ups + K*sqrt(sig[j-1])*e.star[j-1] 67 | } 68 | ``` 69 | 70 | 71 | 72 | 73 | ### Chapter 7 74 | 75 | - not enough people read this chapter to find the bloopers ... but we're fairly certain there are a few 76 | 77 | 78 | ### Elsewhere 79 | 80 | - FYI: In Edition 5, Appendix R has been removed and put online here: [dsstoffer.github.io/Rtoot](https://dsstoffer.github.io/Rtoot) 81 | 82 | 83 |


84 | -------------------------------------------------------------------------------- /chap6.md: -------------------------------------------------------------------------------- 1 | ## Chapter 6 - Old Kalman Filter and Smoother Details and Code 2 | 3 | 4 | 5 | > __Note__ The old Kalman filter and smoother scripts and the EM scripts now are marked with an `x` ... e.g., `Kfilter1` is now `xKfilter1` etc. etc. etc. BUT, older scripts can be changed to the newer ones with only slight changes. The gain in speed is worth the effort!! 6 | 7 | > __Warning__ Eventually, the old scripts with an `x` prefix will be removed. 8 |

9 | 10 | --- 11 | 12 | ### 🚭 this is the OLD stuff and will NOT work in version 2.0 or later 13 | 14 | The three levels of code `Kfilter0/Ksmooth0`, `Kfilter1/Ksmooth1`, and `Kfilter2/Ksmooth2` 15 | have been superseded by the newer `Kfilter` and `Ksmooth` scripts. The new scripts are faster, easier to work with, and they remove the need for 3 different scripts. 16 | 17 | This page contains a description of the old code and lists the older Chapter 6 code. What you see here does NOT apply anymore. 18 | 19 | ### StaRt Old Stuff: 20 | 21 | 22 | + For various models, each script provides the Kalman filter/smoother, the innovations 23 | and the corresponding variance-covariance matrices, and the value of the innovations likelihood at the location of the parameter values passed to the script. MLE is then accomplished by calling the script that runs the filter. _The model is specified by passing the model parameters._ 24 | 25 | 26 | + Level 0 is for the case of a fixed measurement matrix and no inputs; i.e., if At = A for all t, and there are no inputs, then use the code at level 0. 27 | 28 | + If the measurement matrices are time varying or there are inputs, use the code at a higher level (1 or 2). Many of the examples in the text can be done at level 0. 29 | 30 | 31 | + Level 1 allows for time varying measurement matrices and inputs, and level 2 adds 32 | the possibility of correlated noise processes. 33 | 34 | The models for each case are (x is state, y is observation, and t = 1, …, n): 35 | 36 | ♦ **Level 0:**     xt = Φ xt-1 + wt,     yt = A xt + vt,     wt ~ iid Np(0, Q) ⊥ vt ~ iid Nq(0, R) ⊥ x0 ~ Np0, Σ0) 37 | 38 | ♦ **Level 1:**     xt = Φ xt-1 + Υ ut + wt,     yt = At xt + Γ ut + vt,   ut are r-dimensional inputs, etc.
39 | 40 | ♦ **Level 2:**     xt = Φ xt-1 + Υ ut + Θ wt-1,     yt = At xt + Γ ut + vt,   cov(ws, vt) = S δst,   Θ is p × m, and wt is m-dimensional, etc. 41 | 42 | --- 43 | 44 | ### Level 0 - Fixed Measurement Matrices and No Inputs 45 | 46 | The call to Kfilter0 is, `Kfilter0(n,y,A,mu0,Sigma0,Phi,cQ,cR)` in fairly obvious notation except that `cQ` and `cR` are the Cholesky-type decompositions of 47 | `Q` and `R`. In particular `Q = t(cQ)%*%cQ` and `R = t(cR)%*%cR` is all that is required provided `Q`and `R` are valid covariance matrices (Q can be singular and there is an example in the text). The call to `Ksmooth0` is similar. 48 | 49 | __In all three cases, the smoother also returns the filter and the likelihood.__ 50 | 51 | --- 52 | 53 | ### Level 1 - Varying Measurement Matrices and Inputs 54 | 55 | The call to the filter is `Kfilter1(n,y,A,mu0,Sigma0,Phi,Ups,Gam,cQ,cR,input)` 56 | where `A` is an array with `dim=c(q,p,n)`, `Ups` is Υ [p × r], `Gam`is Γ [q × r], and `input` is the matrix of inputs 57 | that has the same row dimension as y (which is n × q), `input`is n × r; the state dimension is p). The call to `Ksmooth1`is similar. Set `Ups`, `Gam`, or `input` to 0 (zero) if you don't use them. 58 | 59 | --- 60 | 61 | ### Level 2 - Varying Measurement Matrices, Inputs and Correlated Noise 62 | 63 | The call to the filter is `Kfilter2(n,y,A,mu0,Sigma0,Phi,Ups,Gam,Theta,cQ,cR,S,input)`, which is similar to `Kfilter1` but that `S` must be included. `Kfilter2` runs the filter given in Property 6.5. The call to `Ksmooth2` is similar. Set `Ups` or `Gam` or `input` to 0 (zero) if you don't use them. 64 | 65 | --- 66 | --- 67 | 68 | ## OLD Chapter 6 Code 69 | 70 | Example 6.1 71 | ```r 72 | tsplot(blood, type='o', col=c(6,4,2), lwd=2, pch=19, cex=1) 73 | ``` 74 | 75 | Example 6.2 76 | ```r 77 | tsplot(cbind(globtemp, globtempl), spag=TRUE, lwd=2, col=astsa.col(c(6,4),.5), ylab="Temperature Deviations") 78 | 79 | # or the updated version (one is land only and the other ocean only) 80 | tsplot(cbind(gtemp_land, gtemp_ocean), spaghetti=TRUE, lwd=2, pch=20, type="o", 81 | col=astsa.col(c(4,2),.5), ylab="Temperature Deviations", main="Global Warming") 82 | legend("topleft", legend=c("Land Surface", "Sea Surface"), lty=1, pch=20, col=c(4,2), bg="white") 83 | ``` 84 | 85 | Example 6.5 86 | ```r 87 | # generate data 88 | set.seed(1) 89 | num = 50 90 | w = rnorm(num+1,0,1) 91 | v = rnorm(num,0,1) 92 | 93 | mu = cumsum(w) # states: mu[0], mu[1], . . ., mu[50] 94 | y = mu[-1] + v # obs: y[1], . . ., y[50] 95 | 96 | # filter and smooth (Ksmooth0 does both) 97 | mu0 = 0; sigma0 = 1; phi = 1; cQ = 1; cR = 1 98 | ks = Ksmooth0(num, y, 1, mu0, sigma0, phi, cQ, cR) 99 | 100 | # pictures 101 | par(mfrow=c(3,1)) 102 | Time = 1:num 103 | 104 | tsplot(Time, mu[-1], type='p', main="Prediction", ylim=c(-5,10)) 105 | lines(ks$xp) 106 | lines(ks$xp+2*sqrt(ks$Pp), lty="dashed", col="blue") 107 | lines(ks$xp-2*sqrt(ks$Pp), lty="dashed", col="blue") 108 | 109 | tsplot(Time, mu[-1], type='p', main="Filter", ylim=c(-5,10)) 110 | lines(ks$xf) 111 | lines(ks$xf+2*sqrt(ks$Pf), lty="dashed", col="blue") 112 | lines(ks$xf-2*sqrt(ks$Pf), lty="dashed", col="blue") 113 | 114 | tsplot(Time, mu[-1], type='p', main="Smoother", ylim=c(-5,10)) 115 | lines(ks$xs) 116 | lines(ks$xs+2*sqrt(ks$Ps), lty="dashed", col="blue") 117 | lines(ks$xs-2*sqrt(ks$Ps), lty="dashed", col="blue") 118 | 119 | mu[1]; ks$x0n; sqrt(ks$P0n) # initial value info 120 | 121 | # In case you can't see the differences in the figures... 122 | # ... either get new glasses or ... 123 | # ... plot them on the same graph (not shown in text) 124 | dev.new() 125 | tsplot(Time, mu[-1], type='o', pch=19, cex=1) 126 | lines(ks$xp, col=4, lwd=3) 127 | lines(ks$xf, col=3, lwd=3) 128 | lines(ks$xs, col=2, lwd=3) 129 | names = c("predictor","filter","smoother") 130 | legend("bottomright", names, col=4:2, lwd=3, lty=1, bg="white") 131 | ``` 132 | 133 | 134 | Example 6.6 135 | ```r 136 | # Generate Data 137 | set.seed(999) 138 | num = 100 139 | N = num+1 140 | x = sarima.sim(n=N, ar=.8) 141 | # below used in text 142 | # x = arima.sim(n=N, list(ar = .8)) 143 | y = ts(x[-1] + rnorm(num,0,1)) 144 | 145 | # Initial Estimates 146 | u = ts.intersect(y, lag(y,-1), lag(y,-2)) 147 | varu = var(u) 148 | coru = cor(u) 149 | phi = coru[1,3]/coru[1,2] 150 | q = (1-phi^2)*varu[1,2]/phi 151 | r = varu[1,1] - q/(1-phi^2) 152 | (init.par = c(phi, sqrt(q), sqrt(r))) 153 | 154 | # Function to evaluate the likelihood 155 | Linn=function(para){ 156 | phi = para[1]; sigw = para[2]; sigv = para[3] 157 | Sigma0 = (sigw^2)/(1-phi^2); Sigma0[Sigma0<0]=0 158 | kf = Kfilter0(num,y,1,mu0=0,Sigma0,phi,sigw,sigv) 159 | return(kf$like) 160 | } 161 | 162 | # Estimation 163 | (est = optim(init.par, Linn, gr=NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 164 | SE = sqrt(diag(solve(est$hessian))) 165 | cbind(estimate=c(phi=est$par[1],sigw=est$par[2],sigv=est$par[3]), SE) 166 | ``` 167 | 168 | 169 | 170 | Example 6.7 171 | ```r 172 | ##- slight change from text, the data scaled -## 173 | ##- you can remove the scales to get to the original analysis -## 174 | # Setup 175 | y = cbind(globtemp/sd(globtemp), globtempl/sd(globtempl)) 176 | num = nrow(y) 177 | input = rep(1,num) 178 | A = array(rep(1,2), dim=c(2,1,num)) 179 | mu0 = -.35; Sigma0 = 1; Phi = 1 180 | 181 | # Function to Calculate Likelihood 182 | Linn=function(para){ 183 | cQ = para[1] # sigma_w 184 | cR1 = para[2] # 11 element of chol(R) 185 | cR2 = para[3] # 22 element of chol(R) 186 | cR12 = para[4] # 12 element of chol(R) 187 | cR = matrix(c(cR1,0,cR12,cR2),2) # put the matrix together 188 | drift = para[5] 189 | kf = Kfilter1(num,y,A,mu0,Sigma0,Phi,drift,0,cQ,cR,input) 190 | return(kf$like) 191 | } 192 | 193 | # Estimation 194 | init.par = c(.1,.1,.1,0,.05) # initial values of parameters 195 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 196 | SE = sqrt(diag(solve(est$hessian))) 197 | 198 | # Summary of estimation 199 | estimate = est$par; u = cbind(estimate, SE) 200 | rownames(u)=c("sigw","cR11", "cR22", "cR12", "drift"); u 201 | 202 | # Smooth (first set parameters to their final estimates) 203 | cQ = est$par[1] 204 | cR1 = est$par[2] 205 | cR2 = est$par[3] 206 | cR12 = est$par[4] 207 | cR = matrix(c(cR1,0,cR12,cR2), 2) 208 | (R = t(cR)%*%cR) # to view the estimated R matrix 209 | drift = est$par[5] 210 | ks = Ksmooth1(num,y,A,mu0,Sigma0,Phi,drift,0,cQ,cR,input) 211 | 212 | # Plot 213 | tsplot(y, spag=TRUE, margins=.5, type='o', pch=2:3, col=4:3, lty=6, ylab='Temperature Deviations') 214 | xsm = ts(as.vector(ks$xs), start=1880) 215 | rmse = ts(sqrt(as.vector(ks$Ps)), start=1880) 216 | lines(xsm, lwd=2) 217 | xx = c(time(xsm), rev(time(xsm))) 218 | yy = c(xsm-2*rmse, rev(xsm+2*rmse)) 219 | polygon(xx, yy, border=NA, col=gray(.6, alpha=.25)) 220 | ``` 221 | 222 | 223 | Example 6.8 224 | ```r 225 | library(nlme) # loads package nlme (comes with R) 226 | 227 | # Generate data (same as Example 6.6) 228 | set.seed(999); num = 100; N = num+1 229 | x = sarima.sim(ar=.8, n=N) 230 | y = ts(x[-1] + rnorm(num,0,1)) 231 | 232 | # Initial Estimates 233 | u = ts.intersect(y,lag(y,-1),lag(y,-2)) 234 | varu = var(u); coru = cor(u) 235 | phi = coru[1,3]/coru[1,2] 236 | q = (1-phi^2)*varu[1,2]/phi 237 | r = varu[1,1] - q/(1-phi^2) 238 | cr = sqrt(r); cq = sqrt(q); mu0 = 0; Sigma0 = 2.8 239 | (em = EM0(num, y, 1, mu0, Sigma0, phi, cq, cr, 75, .00001)) 240 | 241 | # Standard Errors (this uses nlme) 242 | phi = em$Phi; cq = chol(em$Q); cr = chol(em$R) 243 | mu0 = em$mu0; Sigma0 = em$Sigma0 244 | para = c(phi, cq, cr) 245 | 246 | # Evaluate likelihood at estimates 247 | Linn=function(para){ 248 | kf = Kfilter0(num, y, 1, mu0, Sigma0, para[1], para[2], para[3]) 249 | return(kf$like) 250 | } 251 | emhess = fdHess(para, function(para) Linn(para)) 252 | SE = sqrt(diag(solve(emhess$Hessian))) 253 | 254 | # Display summary of estimation 255 | estimate = c(para, em$mu0, em$Sigma0); SE = c(SE,NA,NA) 256 | u = cbind(estimate, SE) 257 | rownames(u) = c("phi","sigw","sigv","mu0","Sigma0") 258 | u 259 | ``` 260 | 261 | 262 | Example 6.9 263 | ```r 264 | y = cbind(WBC, PLT, HCT) 265 | num = nrow(y) 266 | A = array(0, dim=c(3,3,num)) # creates num 3x3 zero matrices 267 | for(k in 1:num) if (y[k,1] > 0) A[,,k]= diag(1,3) 268 | 269 | # Initial values 270 | mu0 = matrix(0,3,1) 271 | Sigma0 = diag(c(.1,.1,1) ,3) 272 | Phi = diag(1,3) 273 | cQ = diag(c(.1,.1,1), 3) 274 | cR = diag(c(.1,.1,1), 3) 275 | (em = EM1(num, y, A, mu0, Sigma0, Phi, cQ, cR, 100, .001)) 276 | 277 | # Graph smoother 278 | ks = Ksmooth1(num, y, A, em$mu0, em$Sigma0, em$Phi, 0, 0, chol(em$Q), chol(em$R), 0) 279 | y1s = ks$xs[1,,] 280 | y2s = ks$xs[2,,] 281 | y3s = ks$xs[3,,] 282 | p1 = 2*sqrt(ks$Ps[1,1,]) 283 | p2 = 2*sqrt(ks$Ps[2,2,]) 284 | p3 = 2*sqrt(ks$Ps[3,3,]) 285 | 286 | par(mfrow=c(3,1)) 287 | tsplot(WBC, type='p', pch=19, ylim=c(1,5), col=6, lwd=2, cex=1) 288 | lines(y1s) 289 | xx = c(time(WBC), rev(time(WBC))) # same for all 290 | yy = c(y1s-p1, rev(y1s+p1)) 291 | polygon(xx, yy, border=8, col=astsa.col(8, alpha = .1)) 292 | 293 | tsplot(PLT, type='p', ylim=c(3,6), pch=19, col=4, lwd=2, cex=1) 294 | lines(y2s) 295 | yy = c(y2s-p2, rev(y2s+p2)) 296 | polygon(xx, yy, border=8, col=astsa.col(8, alpha = .1)) 297 | 298 | tsplot(HCT, type='p', pch=19, ylim=c(20,40), col=2, lwd=2, cex=1) 299 | lines(y3s) 300 | yy = c(y3s-p3, rev(y3s+p3)) 301 | polygon(xx, yy, border=8, col=astsa.col(8, alpha = .1)) 302 | ``` 303 | 304 | 305 | 306 | Example 6.10 307 | ```r 308 | num = length(jj) 309 | A = cbind(1,1,0,0) 310 | 311 | # Function to Calculate Likelihood 312 | Linn=function(para){ 313 | Phi = diag(0,4) 314 | Phi[1,1] = para[1] 315 | Phi[2,]=c(0,-1,-1,-1); Phi[3,]=c(0,1,0,0); Phi[4,]=c(0,0,1,0) 316 | cQ1 = para[2]; cQ2 = para[3] # sqrt q11 and sqrt q22 317 | cQ=diag(0,4); cQ[1,1]=cQ1; cQ[2,2]=cQ2 318 | cR = para[4] # sqrt r11 319 | kf = Kfilter0(num,jj,A,mu0,Sigma0,Phi,cQ,cR) 320 | return(kf$like) 321 | } 322 | 323 | # Initial Parameters 324 | mu0 = c(.7,0,0,0) 325 | Sigma0 = diag(.04,4) 326 | init.par = c(1.03, .1, .1, .5) # Phi[1,1], the 2 Qs and R 327 | 328 | # Estimation 329 | est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1)) 330 | SE = sqrt(diag(solve(est$hessian))) 331 | u = cbind(estimate=est$par,SE) 332 | rownames(u)=c("Phi11","sigw1","sigw2","sigv"); u 333 | 334 | # Smooth 335 | Phi = diag(0,4) 336 | Phi[1,1] = est$par[1] 337 | Phi[2,] = c(0,-1,-1,-1) 338 | Phi[3,] = c(0,1,0,0) 339 | Phi[4,] = c(0,0,1,0) 340 | cQ1 = est$par[2] 341 | cQ2 = est$par[3] 342 | cQ = diag(0,4) 343 | cQ[1,1] = cQ1 344 | cQ[2,2] = cQ2 345 | cR = est$par[4] 346 | ks = Ksmooth0(num, jj, A, mu0, Sigma0, Phi, cQ, cR) 347 | 348 | # Plots 349 | Tsm = ts(ks$xs[1,,], start=1960, freq=4) 350 | Ssm = ts(ks$xs[2,,], start=1960, freq=4) 351 | p1 = 3*sqrt(ks$Ps[1,1,]); p2 = 3*sqrt(ks$Ps[2,2,]) 352 | par(mfrow=c(2,1)) 353 | tsplot(Tsm, main='Trend Component', ylab='Trend') 354 | xx = c(time(jj), rev(time(jj))) 355 | yy = c(Tsm-p1, rev(Tsm+p1)) 356 | polygon(xx, yy, border=NA, col=gray(.5, alpha = .3)) 357 | tsplot(jj, main='Data & Trend+Season', ylab='J&J QE/Share', ylim=c(-.5,17)) 358 | xx = c(time(jj), rev(time(jj)) ) 359 | yy = c((Tsm+Ssm)-(p1+p2), rev((Tsm+Ssm)+(p1+p2)) ) 360 | polygon(xx, yy, border=NA, col=gray(.5, alpha = .3)) 361 | 362 | # Forecast 363 | dev.new() 364 | n.ahead = 12 365 | y = ts(append(jj, rep(0,n.ahead)), start=1960, freq=4) 366 | rmspe = rep(0,n.ahead) 367 | x00 = ks$xf[,,num] 368 | P00 = ks$Pf[,,num] 369 | Q = t(cQ)%*%cQ 370 | R = t(cR)%*%(cR) 371 | for (m in 1:n.ahead){ 372 | xp = Phi%*%x00 373 | Pp = Phi%*%P00%*%t(Phi)+Q 374 | sig = A%*%Pp%*%t(A)+R 375 | K = Pp%*%t(A)%*%(1/sig) 376 | x00 = xp 377 | P00 = Pp-K%*%A%*%Pp 378 | y[num+m] = A%*%xp 379 | rmspe[m] = sqrt(sig) 380 | } 381 | tsplot(y, type='o', main='', ylab='J&J QE/Share', ylim=c(5,30), xlim = c(1975,1984)) 382 | upp = ts(y[(num+1):(num+n.ahead)]+2*rmspe, start=1981, freq=4) 383 | low = ts(y[(num+1):(num+n.ahead)]-2*rmspe, start=1981, freq=4) 384 | xx = c(time(low), rev(time(upp))) 385 | yy = c(low, rev(upp)) 386 | polygon(xx, yy, border=8, col=gray(.5, alpha = .3)) 387 | abline(v=1981, lty=3) 388 | ``` 389 | 390 | 391 | 392 | Example 6.12 393 | ```r 394 | # Preliminary analysis 395 | fit1 = sarima(cmort, 2,0,0, xreg=time(cmort)) 396 | acf(cbind(dmort <- resid(fit1$fit), tempr, part)) 397 | lag2.plot(tempr, dmort, 8) 398 | lag2.plot(part, dmort, 8) 399 | 400 | # quick and dirty fit (detrend then fit ARMAX) 401 | trend = time(cmort) - mean(time(cmort)) 402 | dcmort = resid(fit2 <- lm(cmort~trend, na.action=NULL)) # detrended mort 403 | u = ts.intersect(dM=dcmort, dM1=lag(dcmort,-1), dM2=lag(dcmort,-2), T1=lag(tempr,-1), P=part, P4=lag(part,-4)) 404 | sarima(u[,1], 0,0,0, xreg=u[,2:6]) # ARMAX fit with residual analysis 405 | 406 | # all estimates at once 407 | trend = time(cmort) - mean(time(cmort)) # center time 408 | const = time(cmort)/time(cmort) # appropriate time series of 1s 409 | ded = ts.intersect(M=cmort, T1=lag(tempr,-1), P=part, P4=lag(part,-4), trend, const) 410 | y = ded[,1] 411 | input = ded[,2:6] 412 | num = length(y) 413 | A = array(c(1,0), dim = c(1,2,num)) 414 | 415 | # Function to Calculate Likelihood 416 | Linn=function(para){ 417 | phi1 = para[1]; phi2 = para[2]; cR = para[3]; b1 = para[4] 418 | b2 = para[5]; b3 = para[6]; b4 = para[7]; alf = para[8] 419 | mu0 = matrix(c(0,0), 2, 1) 420 | Sigma0 = diag(100, 2) 421 | Phi = matrix(c(phi1, phi2, 1, 0), 2) 422 | Theta = matrix(c(phi1, phi2), 2) 423 | Ups = matrix(c(b1, 0, b2, 0, b3, 0, 0, 0, 0, 0), 2, 5) 424 | Gam = matrix(c(0, 0, 0, b4, alf), 1, 5); cQ = cR; S = cR^2 425 | kf = Kfilter2(num, y, A, mu0, Sigma0, Phi, Ups, Gam, Theta, cQ, cR, S, input) 426 | return(kf$like) 427 | } 428 | 429 | # Estimation - prelim analysis gives good starting values 430 | init.par = c(phi1=.3, phi2=.3, cR=5, b1=-.2, b2=.1, b3=.05, b4=-1.6, alf=mean(cmort)) 431 | L = c( 0, 0, 1, -1, 0, 0, -2, 70) # lower bound on parameters 432 | U = c(.5, .5, 10, 0, .5, .5, 0, 90) # upper bound - used in optim 433 | est = optim(init.par, Linn, NULL, method='L-BFGS-B', lower=L, upper=U, 434 | hessian=TRUE, control=list(trace=1, REPORT=1, factr=10^8)) 435 | SE = sqrt(diag(solve(est$hessian))) 436 | round(cbind(estimate=est$par, SE), 3) # results 437 | 438 | # Residual Analysis (not shown) 439 | phi1 = est$par[1]; phi2 = est$par[2] 440 | cR = est$par[3]; b1 = est$par[4] 441 | b2 = est$par[5]; b3 = est$par[6] 442 | b4 = est$par[7]; alf = est$par[8] 443 | mu0 = matrix(c(0,0), 2, 1) 444 | Sigma0 = diag(100, 2) 445 | Phi = matrix(c(phi1, phi2, 1, 0), 2) 446 | Theta = matrix(c(phi1, phi2), 2) 447 | Ups = matrix(c(b1, 0, b2, 0, b3, 0, 0, 0, 0, 0), 2, 5) 448 | Gam = matrix(c(0, 0, 0, b4, alf), 1, 5) 449 | cQ = cR 450 | S = cR^2 451 | kf = Kfilter2(num, y, A, mu0, Sigma0, Phi, Ups, Gam, Theta, cQ, cR, S, input) 452 | res = ts(as.vector(kf$innov), start=start(cmort), freq=frequency(cmort)) 453 | sarima(res, 0,0,0, no.constant=TRUE) # gives a full residual analysis 454 | 455 | # Similar fit with but with trend in the X of ARMAX 456 | trend = time(cmort) - mean(time(cmort)) 457 | u = ts.intersect(M=cmort, M1=lag(cmort,-1), M2=lag(cmort,-2), T1=lag(tempr,-1), 458 | P=part, P4=lag(part -4), trend) 459 | sarima(u[,1], 0,0,0, xreg=u[,2:7]) 460 | ``` 461 | 462 | 463 | 464 | Example 6.13 465 | ```r 466 | ################################## 467 | # NOTE: If this takes a long time to run on your machine, try 468 | # tol = .0001 and if you need more speed 469 | # nboot = 250 470 | tol = sqrt(.Machine$double.eps) # determines convergence of optimizer 471 | nboot = 500 # number of bootstrap replicates 472 | ################################## 473 | 474 | pb = txtProgressBar(min = 0, max = nboot, initial = 0, style=3) # progress bar 475 | 476 | y = window(qinfl, c(1953,1), c(1965,2)) # inflation 477 | z = window(qintr, c(1953,1), c(1965,2)) # interest 478 | num = length(y) 479 | A = array(z, dim=c(1,1,num)) 480 | input = matrix(1,num,1) 481 | 482 | # Function to Calculate Likelihood 483 | Linn = function(para, y.data){ # pass data also 484 | phi = para[1]; alpha = para[2] 485 | b = para[3]; Ups = (1-phi)*b 486 | cQ = para[4]; cR = para[5] 487 | kf = Kfilter2(num,y.data,A,mu0,Sigma0,phi,Ups,alpha,1,cQ,cR,0,input) 488 | return(kf$like) 489 | } 490 | 491 | # Parameter Estimation 492 | mu0 = 1 493 | Sigma0 = .01 494 | init.par = c(phi=.84, alpha=-.77, b=.85, cQ=.12, cR=1.1) # initial values 495 | 496 | est = optim(init.par, Linn, NULL, y.data=y, method="BFGS", hessian=TRUE, 497 | control=list(trace=1, REPORT=1, reltol=tol)) 498 | SE = sqrt(diag(solve(est$hessian))) 499 | 500 | phi = est$par[1]; alpha = est$par[2] 501 | b = est$par[3]; Ups = (1-phi)*b 502 | cQ = est$par[4]; cR = est$par[5] 503 | round(cbind(estimate=est$par, SE), 3) 504 | 505 | 506 | # BEGIN BOOTSTRAP 507 | # Run the filter at the estimates 508 | kf = Kfilter2(num,y,A,mu0,Sigma0,phi,Ups,alpha,1,cQ,cR,0,input) 509 | 510 | # Pull out necessary values from the filter and initialize 511 | xp = kf$xp 512 | innov = kf$innov 513 | sig = kf$sig 514 | e = innov/sqrt(sig) 515 | e.star = e # initialize values 516 | y.star = y 517 | xp.star = xp 518 | k = 4:50 # hold first 3 observations fixed 519 | para.star = matrix(0, nboot, 5) # to store estimates 520 | init.par = c(.84, -.77, .85, .12, 1.1) 521 | 522 | for (i in 1:nboot){ 523 | setTxtProgressBar(pb,i) 524 | e.star[k] = sample(e[k], replace=TRUE) 525 | for (j in k){ 526 | K = (phi*Pp[j]*z[j])/sig[j] 527 | xp.star[j] = phi*xp.star[j-1] + Ups+K[j]*sqrt(sig[j])*e.star[j] } 528 | y.star[k] = z[k]*xp.star[k] + alpha + sqrt(sig[k])*e.star[k] 529 | est.star = optim(init.par, Linn, NULL, y.data=y.star, method="BFGS", control=list(reltol=tol)) 530 | para.star[i,] = cbind(est.star$par[1], est.star$par[2], est.star$par[3], 531 | abs(est.star$par[4]), abs(est.star$par[5])) 532 | } 533 | close(pb) 534 | 535 | # Some summary statistics 536 | rmse = rep(NA,5) # SEs from the bootstrap 537 | for(i in 1:5){rmse[i]=sqrt(sum((para.star[,i]-est$par[i])^2)/nboot) 538 | cat(i, rmse[i],"\n") 539 | } 540 | # Plot phi and sigw (scatter.hist in astsa v1.13) 541 | phi = para.star[,1] 542 | sigw = abs(para.star[,4]) 543 | phi = ifelse(phi<0, NA, phi) # any phi < 0 not plotted 544 | scatter.hist(sigw, phi, ylab=expression(phi), xlab=expression(sigma[~w]), 545 | hist.col=astsa.col(5,.4), pt.col=5, pt.size=1.5) 546 | ``` 547 | 548 | Example 6.14 549 | ```r 550 | set.seed(123) 551 | num = 50 552 | w = rnorm(num,0,.1) 553 | x = cumsum(cumsum(w)) 554 | y = x + rnorm(num,0,1) 555 | ## State Space ## 556 | Phi = matrix(c(2,1,-1,0),2) 557 | A = matrix(c(1,0),1) 558 | mu0 = matrix(0,2); Sigma0 = diag(1,2) 559 | Linn = function(para){ 560 | sigw = para[1] 561 | sigv = para[2] 562 | cQ = diag(c(sigw,0)) 563 | kf = Kfilter0(num, y, A, mu0, Sigma0, Phi, cQ, sigv) 564 | return(kf$like) 565 | } 566 | ## Estimation ## 567 | init.par = c(.1, 1) 568 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 569 | SE = sqrt(diag(solve(est$hessian))) 570 | # Summary of estimation 571 | estimate = est$par; u = cbind(estimate, SE) 572 | rownames(u) = c("sigw","sigv"); u 573 | # Smooth 574 | sigw = est$par[1] 575 | cQ = diag(c(sigw,0)) 576 | sigv = est$par[2] 577 | ks = Ksmooth0(num, y, A, mu0, Sigma0, Phi, cQ, sigv) 578 | xsmoo = ts(ks$xs[1,1,]); psmoo = ts(ks$Ps[1,1,]) 579 | upp = xsmoo+2*sqrt(psmoo) 580 | low = xsmoo-2*sqrt(psmoo) 581 | # 582 | tsplot(x, ylab="", ylim=c(-1,8), col=1) 583 | lines(y, type='o', col=8) 584 | lines(xsmoo, col=4, lty=2, lwd=3) 585 | lines(upp, col=4, lty=2); lines(low, col=4, lty=2) 586 | lines(smooth.spline(y), lty=1, col=2) 587 | legend("topleft", c("Observations","State"), pch=c(1,-1), lty=1, lwd=c(1,2), col=c(8,1)) 588 | legend("bottomright", c("Smoother", "GCV Spline"), lty=c(2,1), lwd=c(3,1), col=c(4,2)) 589 | ``` 590 | 591 | Example 6.16 592 | ```r 593 | library(depmixS4) 594 | model <- depmix(EQcount ~1, nstates=2, data=data.frame(EQcount), family=poisson('identity'), respstart=c(15,25)) 595 | set.seed(90210) 596 | summary(fm <- fit(model)) # estimation results 597 | standardError(fm) # with standard errors 598 | 599 | ##-- A little nicer display of the parameters --## 600 | para.mle = as.vector(getpars(fm))[3:8] 601 | ( mtrans = matrix(para.mle[1:4], byrow=TRUE, nrow=2) ) 602 | ( lams = para.mle[5:6] ) 603 | ( pi1 = mtrans[2,1]/(2 - mtrans[1,1] - mtrans[2,2]) ) 604 | ( pi2 = 1 - pi1 ) 605 | 606 | #-- Graphics --## 607 | par(mfrow=c(3,1)) 608 | # data and states 609 | tsplot(EQcount, main="", ylab='EQcount', type='h', col=gray(.7), ylim=c(0,50)) 610 | text(EQcount, col=6*posterior(fm)[,1]-2, labels=posterior(fm)[,1]) 611 | # prob of state 2 612 | tsplot(ts(posterior(fm)[,3], start=1900), ylab = expression(hat(pi)[~2]*'(t|n)')); abline(h=.5, lty=2) 613 | # histogram 614 | hist(EQcount, breaks=30, prob=TRUE, main="") 615 | xvals = seq(1,45) 616 | u1 = pi1*dpois(xvals, lams[1]) 617 | u2 = pi2*dpois(xvals, lams[2]) 618 | lines(xvals, u1, col=4) 619 | lines(xvals, u2, col=2) 620 | ``` 621 | 622 | Example 6.17 623 | ```r 624 | library(depmixS4) 625 | y = ts(sp500w, start=2003, freq=52) # make data depmix friendly 626 | mod3 <- depmix(y~1, nstates=3, data=data.frame(y)) 627 | set.seed(2) 628 | summary(fm3 <- fit(mod3)) # estimation results 629 | 630 | ##-- a little nicer display --## 631 | para.mle = as.vector(getpars(fm3)[-(1:3)]) 632 | permu = matrix(c(0,0,1,0,1,0,1,0,0), 3,3) # for the label switch 633 | (mtrans.mle = permu%*%round(t(matrix(para.mle[1:9],3,3)),3)%*%permu) 634 | (norms.mle = round(matrix(para.mle[10:15],2,3),3)%*%permu) 635 | 636 | ##-- Graphics --## 637 | layout(matrix(c(1,2, 1,3), 2), heights=c(1,.75)) 638 | 639 | tsplot(y, main="", ylab='S&P500 Weekly Returns', col=gray(.7), ylim=c(-.11,.11)) 640 | culer = 4-posterior(fm3)[,1]; culer[culer==3]=4 # switch labels 1 and 3 641 | text(y, col=culer, labels=4-posterior(fm3)[,1]) 642 | 643 | acf1(y^2, 25) 644 | 645 | hist(y, 25, prob=TRUE, main='', col=astsa.col(8,.2)) 646 | pi.hat = colSums(posterior(fm3)[-1,2:4])/length(y) 647 | culer = c(1,2,4) 648 | for (i in 1:3) { 649 | mu = norms.mle[1,i]; sig = norms.mle[2,i] 650 | x = seq(-.2,.15, by=.001) 651 | lines(x, pi.hat[4-i]*dnorm(x, mean=mu, sd=sig), col=culer[i], lwd=2) 652 | } 653 | ``` 654 | 655 | Example 6.18 656 | ```r 657 | library(MSwM) 658 | set.seed(90210) 659 | dflu = diff(flu) 660 | model = lm(dflu~ 1) 661 | mod = msmFit(model, k=2, p=2, sw=rep(TRUE,4)) # 2 regimes, AR(2)s 662 | summary(mod) 663 | plotProb(mod, which=3) 664 | ``` 665 | 666 | 667 | 668 | Example 6.22 669 | ```r 670 | y = flu 671 | num = length(y) 672 | nstate = 4 # state dimenstion 673 | M1 = as.matrix(cbind(1,0,0,1)) # obs matrix normal 674 | M2 = as.matrix(cbind(1,0,1,1)) # obs matrix flu epi 675 | prob = matrix(0,num,1); yp = y # to store pi2(t|t-1) & y(t|t-1) 676 | xfilter = array(0, dim=c(nstate,1,num)) # to store x(t|t) 677 | # Function to Calculate Likelihood 678 | Linn = function(para){ 679 | alpha1 = para[1]; alpha2 = para[2]; beta0 = para[3] 680 | sQ1 = para[4]; sQ2 = para[5]; like=0 681 | xf = matrix(0, nstate, 1) # x filter 682 | xp = matrix(0, nstate, 1) # x pred 683 | Pf = diag(.1, nstate) # filter cov 684 | Pp = diag(.1, nstate) # pred cov 685 | pi11 <- .75 -> pi22; pi12 <- .25 -> pi21; pif1 <- .5 -> pif2 686 | phi = matrix(0,nstate,nstate) 687 | phi[1,1] = alpha1; phi[1,2] = alpha2; phi[2,1]=1; phi[4,4]=1 688 | Ups = as.matrix(rbind(0,0,beta0,0)) 689 | Q = matrix(0,nstate,nstate) 690 | Q[1,1] = sQ1^2; Q[3,3] = sQ2^2; R=0 # R=0 in final model 691 | # begin filtering # 692 | for(i in 1:num){ 693 | xp = phi%*%xf + Ups; Pp = phi%*%Pf%*%t(phi) + Q 694 | sig1 = as.numeric(M1%*%Pp%*%t(M1) + R) 695 | sig2 = as.numeric(M2%*%Pp%*%t(M2) + R) 696 | k1 = Pp%*%t(M1)/sig1; k2 = Pp%*%t(M2)/sig2 697 | e1 = y[i]-M1%*%xp; e2 = y[i]-M2%*%xp 698 | pip1 = pif1*pi11 + pif2*pi21; pip2 = pif1*pi12 + pif2*pi22 699 | den1 = (1/sqrt(sig1))*exp(-.5*e1^2/sig1) 700 | den2 = (1/sqrt(sig2))*exp(-.5*e2^2/sig2) 701 | denm = pip1*den1 + pip2*den2 702 | pif1 = pip1*den1/denm; pif2 = pip2*den2/denm 703 | pif1 = as.numeric(pif1); pif2 = as.numeric(pif2) 704 | e1 = as.numeric(e1); e2=as.numeric(e2) 705 | xf = xp + pif1*k1*e1 + pif2*k2*e2 706 | eye = diag(1, nstate) 707 | Pf = pif1*(eye-k1%*%M1)%*%Pp + pif2*(eye-k2%*%M2)%*%Pp 708 | like = like - log(pip1*den1 + pip2*den2) 709 | prob[i]<<-pip2; xfilter[,,i]<<-xf; innov.sig<<-c(sig1,sig2) 710 | yp[i]<<-ifelse(pip1 > pip2, M1%*%xp, M2%*%xp) 711 | } 712 | return(like) 713 | } 714 | # Estimation 715 | alpha1 = 1.4; alpha2 = -.5; beta0 = .3; sQ1 = .1; sQ2 = .1 716 | init.par = c(alpha1, alpha2, beta0, sQ1, sQ2) 717 | (est = optim(init.par, Linn, NULL, method='BFGS', hessian=TRUE, control=list(trace=1,REPORT=1))) 718 | SE = sqrt(diag(solve(est$hessian))) 719 | u = cbind(estimate=est$par, SE) 720 | rownames(u)=c('alpha1','alpha2','beta0','sQ1','sQ2'); u 721 | 722 | # Graphics 723 | predepi = ifelse(prob<.5,0,1) 724 | FLU = window(flu, start=1968.4) 725 | Time = window(time(flu), start=1968.4) 726 | k = 6:num 727 | par(mfrow=c(3,1)) 728 | tsplot(FLU, col=8, ylab='flu') 729 | text(FLU, col= predepi[k]+1, labels=predepi[k]+1, cex=1.1) 730 | legend('topright', '(a)', bty='n') 731 | 732 | filters = ts(t(xfilter[c(1,3,4),,]), start=tsp(flu)[1], frequency=tsp(flu)[3]) 733 | tsplot(window(filters, start=1968.4), spag=TRUE, col=2:4, ylab='filter') 734 | legend('topright', '(b)', bty='n') 735 | 736 | tsplot(FLU, type='p', pch=19, ylab='flu', cex=1.2) 737 | prde1 = 2*sqrt(innov.sig[1]); prde2 = 2*sqrt(innov.sig[2]) 738 | prde = ifelse(predepi[k]<.5, prde1, prde2) 739 | xx = c(Time, rev(Time)) 740 | yy = c(yp[k]-prde, rev(yp[k]+prde)) 741 | polygon(xx, yy, border=8, col=gray(.6, alpha=.3)) 742 | legend('topright', '(c)', bty='n') 743 | ``` 744 | 745 | 746 | 747 | 748 | Example 6.23 749 | ```r 750 | y = log(nyse^2) 751 | num = length(y) 752 | 753 | # Initial Parameters 754 | phi0=0; phi1=.95; sQ=.2; alpha=mean(y); sR0=1; mu1=-3; sR1=2 755 | init.par = c(phi0,phi1,sQ,alpha,sR0,mu1,sR1) 756 | 757 | # Innovations Likelihood 758 | Linn = function(para){ 759 | phi0=para[1]; phi1=para[2]; sQ=para[3]; alpha=para[4] 760 | sR0=para[5]; mu1=para[6]; sR1=para[7] 761 | sv = SVfilter(num,y,phi0,phi1,sQ,alpha,sR0,mu1,sR1) 762 | return(sv$like) 763 | } 764 | 765 | # Estimation 766 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 767 | SE = sqrt(diag(solve(est$hessian))) 768 | u = cbind(estimates=est$par, SE) 769 | rownames(u)=c("phi0","phi1","sQ","alpha","sigv0","mu1","sigv1"); u 770 | 771 | # Graphics (need filters at the estimated parameters) 772 | phi0=est$par[1]; phi1=est$par[2]; sQ=est$par[3]; alpha=est$par[4] 773 | sR0=est$par[5]; mu1=est$par[6]; sR1=est$par[7] 774 | sv = SVfilter(num,y,phi0,phi1,sQ,alpha,sR0,mu1,sR1) 775 | 776 | # densities plot (f is chi-sq, fm is fitted mixture) 777 | x = seq(-15,6,by=.01) 778 | f = exp(-.5*(exp(x)-x))/(sqrt(2*pi)) 779 | f0 = exp(-.5*(x^2)/sR0^2)/(sR0*sqrt(2*pi)) 780 | f1 = exp(-.5*(x-mu1)^2/sR1^2)/(sR1*sqrt(2*pi)) 781 | fm = (f0+f1)/2 782 | tsplot(x, f, xlab='x') 783 | lines(x, fm, lty=2, lwd=2) 784 | legend('topleft', legend=c('log chi-square', 'normal mixture'), lty=1:2) 785 | 786 | dev.new() 787 | Time = 701:1100 788 | tsplot(Time, nyse[Time], type='l', col=4, lwd=2, ylab='', xlab='', ylim=c(-.18,.12)) 789 | lines(Time, sv$xp[Time]/10, lwd=2, col=6) 790 | ``` 791 | 792 | 793 | 794 | Example 6.24 795 | ```r 796 | n.boot = 500 # number of bootstrap replicates 797 | tol = sqrt(.Machine$double.eps) # convergence limit 798 | 799 | gnpgr = diff(log(gnp)) 800 | fit = arima(gnpgr, order=c(1,0,0)) 801 | y = as.matrix(log(resid(fit)^2)) 802 | num = length(y) 803 | tsplot(y, ylab="") 804 | 805 | # Initial Parameters 806 | phi1 = .9; sQ = .5; alpha = mean(y); sR0 = 1; mu1 = -3; sR1 = 2.5 807 | init.par = c(phi1, sQ, alpha, sR0, mu1, sR1) 808 | 809 | # Innovations Likelihood 810 | Linn=function(para){ 811 | phi1 = para[1]; sQ = para[2]; alpha = para[3] 812 | sR0 = para[4]; mu1 = para[5]; sR1 = para[6] 813 | sv = SVfilter(num, y, 0, phi1, sQ, alpha, sR0, mu1, sR1) 814 | return(sv$like) 815 | } 816 | 817 | # Estimation 818 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 819 | SE = sqrt(diag(solve(est$hessian))) 820 | u = cbind(estimates=est$par, SE) 821 | rownames(u)=c("phi1","sQ","alpha","sig0","mu1","sig1"); u 822 | 823 | # Bootstrap 824 | para.star = matrix(0, n.boot, 6) # to store parameter estimates 825 | Linn2 = function(para){ 826 | phi1 = para[1]; sQ = para[2]; alpha = para[3] 827 | sR0 = para[4]; mu1 = para[5]; sR1 = para[6] 828 | sv = SVfilter(num, y.star, 0, phi1, sQ, alpha, sR0, mu1, sR1) 829 | return(sv$like) 830 | } 831 | 832 | for (jb in 1:n.boot){ cat("iteration:", jb, "\n") 833 | phi1 = est$par[1]; sQ = est$par[2]; alpha = est$par[3] 834 | sR0 = est$par[4]; mu1 = est$par[5]; sR1 = est$par[6] 835 | Q = sQ^2; R0 = sR0^2; R1 = sR1^2 836 | sv = SVfilter(num, y, 0, phi1, sQ, alpha, sR0, mu1, sR1) 837 | 838 | sig0 = sv$Pp+R0 839 | sig1 = sv$Pp+R1 840 | K0 = sv$Pp/sig0 841 | K1 = sv$Pp/sig1 842 | inn0 = y-sv$xp-alpha; inn1 = y-sv$xp-mu1-alpha 843 | den1 = (1/sqrt(sig1))*exp(-.5*inn1^2/sig1) 844 | den0 = (1/sqrt(sig0))*exp(-.5*inn0^2/sig0) 845 | fpi1 = den1/(den0+den1) 846 | 847 | # (start resampling at t=4) 848 | e0 = inn0/sqrt(sig0) 849 | e1 = inn1/sqrt(sig1) 850 | indx = sample(4:num, replace=TRUE) 851 | sinn = cbind(c(e0[1:3], e0[indx]), c(e1[1:3], e1[indx])) 852 | eF = matrix(c(phi1, 1, 0, 0), 2, 2) 853 | xi = cbind(sv$xp,y) # initialize 854 | 855 | for (i in 4:num){ # generate boot sample 856 | G = matrix(c(0, alpha+fpi1[i]*mu1), 2, 1) 857 | h21 = (1-fpi1[i])*sqrt(sig0[i]); h11 = h21*K0[i] 858 | h22 = fpi1[i]*sqrt(sig1[i]); h12 = h22*K1[i] 859 | H = matrix(c(h11,h21,h12,h22),2,2) 860 | xi[i,] = t(eF%*%as.matrix(xi[i-1,],2) + G + H%*%as.matrix(sinn[i,],2)) 861 | } 862 | 863 | # Estimates from boot data 864 | y.star = xi[,2] 865 | phi1 = .9; sQ = .5; alpha = mean(y.star); sR0 = 1; mu1 = -3; sR1 = 2.5 866 | init.par = c(phi1, sQ, alpha, sR0, mu1, sR1) # same as for data 867 | est.star = optim(init.par, Linn2, NULL, method="BFGS", control=list(reltol=tol)) 868 | para.star[jb,] = cbind(est.star$par[1], abs(est.star$par[2]), est.star$par[3], abs(est.star$par[4]), 869 | est.star$par[5], abs(est.star$par[6])) 870 | } 871 | 872 | # Some summary statistics and graphics 873 | rmse = rep(NA, 6) # SEs from the bootstrap 874 | for(i in 1:6){rmse[i] = sqrt(sum((para.star[,i]-est$par[i])^2)/n.boot) 875 | cat(i, rmse[i],"\n") 876 | } 877 | dev.new() 878 | phi = para.star[,1] 879 | hist(phi, 15, prob=TRUE, main="", xlim=c(0,2), xlab="", col=astsa.col(4,.3)) 880 | abline(v=mean(phi), col=4) 881 | curve(dnorm(x, mean=u[1,1], sd=u[2,1]), 0, 2, add=TRUE) 882 | abline(v=u[1,1]) 883 | ``` 884 | 885 | 886 | Example 6.26 887 | 888 |   Adapted from code by: [Hedibert Freitas Lopes](http://hedibert.org/) 889 | 890 | ```r 891 | ##-- Notation --## 892 | # y(t) = x(t) + v(t); v(t) ~ iid N(0,V) 893 | # x(t) = x(t-1) + w(t); w(t) ~ iid N(0,W) 894 | # priors: x(0) ~ N(m0,C0); V ~ IG(a,b); W ~ IG(c,d) 895 | # FFBS: x(t|t) ~ N(m,C); x(t|n) ~ N(mm,CC); x(t|t+1) ~ N(a,R) 896 | ##-- 897 | ffbs = function(y,V,W,m0,C0){ 898 | n = length(y); a = rep(0,n); R = rep(0,n) 899 | m = rep(0,n); C = rep(0,n); B = rep(0,n-1) 900 | H = rep(0,n-1); mm = rep(0,n); CC = rep(0,n) 901 | x = rep(0,n); llike = 0.0 902 | for (t in 1:n){ 903 | if(t==1){a[1] = m0; R[1] = C0 + W 904 | }else{ a[t] = m[t-1]; R[t] = C[t-1] + W } 905 | f = a[t] 906 | Q = R[t] + V 907 | A = R[t]/Q 908 | m[t] = a[t]+A*(y[t]-f) 909 | C[t] = R[t]-Q*A**2 910 | B[t-1] = C[t-1]/R[t] 911 | H[t-1] = C[t-1]-R[t]*B[t-1]**2 912 | llike = llike + dnorm(y[t],f,sqrt(Q),log=TRUE) } 913 | mm[n] = m[n]; CC[n] = C[n] 914 | x[n] = rnorm(1,m[n],sqrt(C[n])) 915 | for (t in (n-1):1){ 916 | mm[t] = m[t] + C[t]/R[t+1]*(mm[t+1]-a[t+1]) 917 | CC[t] = C[t] - (C[t]^2)/(R[t+1]^2)*(R[t+1]-CC[t+1]) 918 | x[t] = rnorm(1,m[t]+B[t]*(x[t+1]-a[t+1]),sqrt(H[t])) } 919 | return(list(x=x,m=m,C=C,mm=mm,CC=CC,llike=llike)) } 920 | 921 | # Simulate states and data 922 | set.seed(1); W = 0.5; V = 1.0 923 | n = 100; m0 = 0.0; C0 = 10.0; x0 = 0 924 | w = rnorm(n,0,sqrt(W)) 925 | v = rnorm(n,0,sqrt(V)) 926 | x = y = rep(0,n) 927 | x[1] = x0 + w[1] 928 | y[1] = x[1] + v[1] 929 | for (t in 2:n){ 930 | x[t] = x[t-1] + w[t] 931 | y[t] = x[t] + v[t] } 932 | 933 | # actual smoother (for plotting) 934 | ks = Ksmooth0(num=n, y, A=1, m0, C0, Phi=1, cQ=sqrt(W), cR=sqrt(V)) 935 | xsmooth = as.vector(ks$xs) 936 | 937 | # run it 938 | run = ffbs(y,V,W,m0,C0) 939 | m = run$m; C = run$C; mm = run$mm 940 | CC = run$CC; L1 = m-2*C; U1 = m+2*C 941 | L2 = mm-2*CC; U2 = mm+2*CC 942 | N = 50 943 | Vs = seq(0.1,2,length=N) 944 | Ws = seq(0.1,2,length=N) 945 | likes = matrix(0,N,N) 946 | for (i in 1:N){ 947 | for (j in 1:N){ 948 | V = Vs[i] 949 | W = Ws[j] 950 | run = ffbs(y,V,W,m0,C0) 951 | likes[i,j] = run$llike } } 952 | # Hyperparameters 953 | a = 0.01; b = 0.01; c = 0.01; d = 0.01 954 | # MCMC step 955 | set.seed(90210) 956 | burn = 10; M = 1000 957 | niter = burn + M 958 | V1 = V; W1 = W 959 | draws = NULL 960 | all_draws = NULL 961 | for (iter in 1:niter){ 962 | run = ffbs(y,V1,W1,m0,C0) 963 | x = run$x 964 | V1 = 1/rgamma(1,a+n/2,b+sum((y-x)^2)/2) 965 | W1 = 1/rgamma(1,c+(n-1)/2,d+sum(diff(x)^2)/2) 966 | draws = rbind(draws,c(V1,W1,x)) } 967 | all_draws = draws[,1:2] 968 | q025 = function(x){quantile(x,0.025)} 969 | q975 = function(x){quantile(x,0.975)} 970 | draws = draws[(burn+1):(niter),] 971 | xs = draws[,3:(n+2)] 972 | lx = apply(xs,2,q025) 973 | mx = apply(xs,2,mean) 974 | ux = apply(xs,2,q975) 975 | 976 | ## plot data 977 | par(mfrow=c(2,2)) 978 | tsplot(cbind(x,y), spag=TRUE, ylab='', col=c(1,8), lwd=2) 979 | points(y) 980 | legend(0, 11, legend=c("x(t)","y(t)"), lty=1, col=c(1,8), lwd=2, bty="n", pch=c(-1,1)) 981 | contour(Vs, Ws, exp(likes), xlab=expression(sigma[v]^2), ylab=expression(sigma[w]^2), 982 | drawlabels=FALSE, ylim=c(0,1.2)) 983 | points(draws[,1:2], pch=16, col=rgb(.9,0,0,0.3), cex=.7) 984 | hist(draws[,1], ylab="Density",main="", xlab=expression(sigma[v]^2)) 985 | abline(v=mean(draws[,1]), col=3, lwd=3) 986 | hist(draws[,2],main="", ylab="Density", xlab=expression(sigma[w]^2)) 987 | abline(v=mean(draws[,2]), col=3, lwd=3) 988 | 989 | ## plot states 990 | dev.new() 991 | tsplot(y, ylab='', type='o', col=8) 992 | lines(xsmooth, lwd=4, col=rgb(1,0,1,alpha=.4)) 993 | lines(mx, col= 4) 994 | xx=c(1:100, 100:1) 995 | yy=c(lx, rev(ux)) 996 | polygon(xx, yy, border=NA, col= gray(.6,alpha=.2)) 997 | legend('topleft', c('true smoother', 'data', 'posterior mean', '95% of draws'), lty=1, 998 | lwd=c(3,1,1,10), pch=c(-1,1,-1,-1), col=c(6, gray(.4), 4, gray(.6, alpha=.5)), 999 | bg='white' ) 1000 | ``` 1001 | 1002 | Example 6.27 1003 | 1004 | ```r 1005 | y = jj 1006 | ### setup - model and initial parameters 1007 | set.seed(90210) 1008 | n = length(y) 1009 | F = c(1,1,0,0) # this is A 1010 | G = diag(0,4) # G is Phi 1011 | G[1,1] = 1.03 1012 | G[2,] = c(0,-1,-1,-1); G[3,]=c(0,1,0,0); G[4,]=c(0,0,1,0) 1013 | a1 = rbind(.7,0,0,0) # this is mu0 1014 | R1 = diag(.04,4) # this is Sigma0 1015 | V = .1 1016 | W11 = .1 1017 | W22 = .1 1018 | 1019 | ##-- FFBS --## 1020 | ffbs = function(y,F,G,V,W11,W22,a1,R1){ 1021 | n = length(y) 1022 | Ws = diag(c(W11,W22,1,1)) # this is Q with 1s as a device only 1023 | iW = diag(1/diag(Ws),4) 1024 | a = matrix(0,n,4) # this is m_t 1025 | R = array(0,c(n,4,4)) # this is V_t 1026 | m = matrix(0,n,4) 1027 | C = array(0,c(n,4,4)) 1028 | a[1,] = a1[,1] 1029 | R[1,,] = R1 1030 | f = t(F)%*%a[1,] 1031 | Q = t(F)%*%R[1,,]%*%F + V 1032 | A = R[1,,]%*%F/Q[1,1] 1033 | m[1,] = a[1,]+A%*%(y[1]-f) 1034 | C[1,,] = R[1,,]-A%*%t(A)*Q[1,1] 1035 | for (t in 2:n){ 1036 | a[t,] = G%*%m[t-1,] 1037 | R[t,,] = G%*%C[t-1,,]%*%t(G) + Ws 1038 | f = t(F)%*%a[t,] 1039 | Q = t(F)%*%R[t,,]%*%F + V 1040 | A = R[t,,]%*%F/Q[1,1] 1041 | m[t,] = a[t,] + A%*%(y[t]-f) 1042 | C[t,,] = R[t,,] - A%*%t(A)*Q[1,1] } 1043 | xb = matrix(0,n,4) 1044 | xb[n,] = m[n,] + t(chol(C[n,,]))%*%rnorm(4) 1045 | for (t in (n-1):1){ 1046 | iC = solve(C[t,,]) 1047 | CCC = solve(t(G)%*%iW%*%G + iC) 1048 | mmm = CCC%*%(t(G)%*%iW%*%xb[t+1,] + iC%*%m[t,]) 1049 | xb[t,] = mmm + t(chol(CCC))%*%rnorm(4) } 1050 | return(xb) 1051 | } 1052 | 1053 | ##-- Prior hyperparameters --## 1054 | # b0 = 0 # mean for beta = phi -1 1055 | # B0 = Inf # var for beta (non-informative => use OLS for sampling beta) 1056 | n0 = 10 # use same for all- the prior is 1/Gamma(n0/2, n0*s20_/2) 1057 | s20v = .001 # for V 1058 | s20w =.05 # for Ws 1059 | 1060 | ##-- MCMC scheme --## 1061 | set.seed(90210) 1062 | burnin = 100 1063 | step = 10 1064 | M = 1000 1065 | niter = burnin+step*M 1066 | pars = matrix(0,niter,4) 1067 | xbs = array(0,c(niter,n,4)) 1068 | pb = txtProgressBar(min=0, max=niter, initial=0, style=3) # progress bar 1069 | 1070 | for (iter in 1:niter){ 1071 | setTxtProgressBar(pb,iter) 1072 | xb = ffbs(y,F,G,V,W11,W22,a1,R1) 1073 | u = xb[,1] 1074 | yu = diff(u); xu = u[-n] # for phihat and se(phihat) 1075 | regu = lm(yu~0+xu) # est of beta = phi-1 1076 | phies = as.vector(coef(summary(regu)))[1:2] + c(1,0) # phi estimate and SE 1077 | dft = df.residual(regu) 1078 | G[1,1] = phies[1] + rt(1,dft)*phies[2] # use a t 1079 | V = 1/rgamma(1, (n0+n)/2, (n0*s20v/2) + sum((y-xb[,1]-xb[,2])^2)/2) 1080 | W11 = 1/rgamma(1, (n0+n-1)/2, (n0*s20w/2) + sum((xb[-1,1]-phies[1]*xb[-n,1])^2)/2) 1081 | W22 = 1/rgamma(1, (n0+ n-3)/2, (n0*s20w/2) + sum((xb[4:n,2] + xb[3:(n-1),2] + 1082 | xb[2:(n-2),2] +xb[1:(n-3),2])^2)/2) 1083 | xbs[iter,,] = xb 1084 | pars[iter,] = c(G[1,1], sqrt(V), sqrt(W11), sqrt(W22)) 1085 | } 1086 | close(pb) 1087 | 1088 | # Plot results 1089 | ind = seq(burnin+1, niter, by=step) 1090 | names= c(expression(phi), expression(sigma[v]), expression(sigma[w~11]), expression(sigma[w~22])) 1091 | par(mfcol=c(3,4)) 1092 | for (i in 1:4){ 1093 | tsplot(pars[ind,i],xlab="iterations", ylab="trace", main="") 1094 | mtext(names[i], side=3, line=.5, cex=1) 1095 | acf(pars[ind,i],main="", lag.max=25, xlim=c(1,25), ylim=c(-.4,.4)) 1096 | hist(pars[ind,i],main="",xlab="") 1097 | abline(v=mean(pars[ind,i]), lwd=2, col=3) 1098 | } 1099 | 1100 | dev.new() 1101 | par(mfrow=c(2,1)) 1102 | mxb = cbind(apply(xbs[ind,,1],2,mean), apply(xbs[,,2],2,mean)) 1103 | lxb = cbind(apply(xbs[ind,,1],2,quantile,0.005), apply(xbs[ind,,2],2,quantile,0.005)) 1104 | uxb = cbind(apply(xbs[ind,,1],2,quantile,0.995), apply(xbs[ind,,2],2,quantile,0.995)) 1105 | mxb = ts(cbind(mxb,rowSums(mxb)), start = tsp(jj)[1], freq=4) 1106 | lxb = ts(cbind(lxb,rowSums(lxb)), start = tsp(jj)[1], freq=4) 1107 | uxb = ts(cbind(uxb,rowSums(uxb)), start = tsp(jj)[1], freq=4) 1108 | names=c('Trend', 'Season', 'Trend + Season') 1109 | L = min(lxb[,1])-.01; U = max(uxb[,1]) +.01 1110 | tsplot(mxb[,1], ylab=names[1], ylim=c(L,U)) 1111 | xx=c(time(jj), rev(time(jj))) 1112 | yy=c(lxb[,1], rev(uxb[,1])) 1113 | polygon(xx, yy, border=NA, col=gray(.4, alpha = .2)) 1114 | L = min(lxb[,3])-.01; U = max(uxb[,3]) +.01 1115 | tsplot(mxb[,3], ylab=names[3], ylim=c(L,U)) 1116 | xx=c(time(jj), rev(time(jj))) 1117 | yy=c(lxb[,3], rev(uxb[,3])) 1118 | polygon(xx, yy, border=NA, col=gray(.4, alpha = .2)) 1119 | ``` 1120 | 1121 | -------------------------------------------------------------------------------- /textRcode.md: -------------------------------------------------------------------------------- 1 | 2 | ## R Code Used in the Examples - tsa4 3 | 4 |   tsa4   This is the site for the 4th edition. The site for the 5th edition is here: [Time Series Analysis and Its Applications, 5th Edition](https://github.com/nickpoison/tsa5/blob/master/textRcode.md) 5 | 6 | 7 | #### ✨ See the [NEWS](https://github.com/nickpoison/astsa/blob/master/NEWS.md) for further details about the state of the package and the changelog. 8 | 9 | 10 | #### ✨ An intro to `astsa` capabilities can be found at [FUN WITH ASTSA](https://github.com/nickpoison/astsa/blob/master/fun_with_astsa/fun_with_astsa.md) 11 | 12 | #### ✨ Here is [A Road Map](https://nickpoison.github.io/) if you want a broad view of what is available. 13 | 14 |

15 | 16 |
17 | 18 | ⛔ ⛔ __WARNING:__ If loaded, the package `dplyr` may (and most likely will) corrupt the base scripts `filter` 19 | and `lag` that we use often. In this case, to avoid problems when analyzing time series, you have a few options: 20 | 21 | ```r 22 | # (1) either detach the problem package 23 | detach(package:dplyr) 24 | 25 | # (2) or fix it yourself if you want dplyr 26 | # this is a great idea from https://stackoverflow.com/a/65186251 27 | library(dplyr, exclude = c("filter", "lag")) # remove the culprits on load 28 | Lag <- dplyr::lag # and do what the dplyr ... 29 | Filter <- dplyr::filter # ... maintainers refuse to do 30 | # then use `Lag` and `Filter` for dplyr's scripts 31 | # `lag` and `filter` will remain uncorrupted as originally intended 32 | 33 | # (3) or just take back the commands 34 | filter = stats::filter 35 | lag = stats::lag 36 | 37 | # in this case, you can still use these for dplyr 38 | Lag <- dplyr::lag 39 | Filter <- dplyr::filter 40 | ``` 41 | 42 | 😖 If you are wondering how it is possible to corrupt a base package, you are not alone. 43 | 44 |
45 | 46 | --- 47 | --- 48 | 49 | > __Note__ when you are in a code block below, you can copy the contents of the block by moving your mouse to the upper right corner and clicking on the copy icon ( 📋 ). 50 | 51 | --- 52 | --- 53 | 54 | ### Table of Contents 55 | 56 | * [Chapter 1 - Characteristics of Time Series](#chapter-1) 57 | * [Chapter 2 - Time Series Regression and Exploratory Data Analysis](#chapter-2) 58 | * [Chapter 3 - ARIMA Models](#chapter-3) 59 | * [Chapter 4 - Spectral Analysis and Filtering](#chapter-4) 60 | * [Chapter 5 - Additional Time Domain Topics](#chapter-5) 61 | * [Chapter 6 - State Space Models](#chapter-6) 62 | * [Chapter 7 - Statistical Methods in the Frequency Domain](#chapter-7) 63 | 64 | --- 65 | 66 | ## Chapter 1 67 | 68 | 69 | Example 1.1 70 | 71 | ```r 72 | tsplot(jj, col=4, type="o", ylab="Quarterly Earnings per Share") 73 | ``` 74 | 75 | Example 1.2 76 | 77 | ```r 78 | tsplot(globtemp, col=4, type="o", ylab="Global Temperature Deviations") 79 | 80 | # or with the updated values 81 | tsplot(gtemp_land, col=4, type="o", ylab="Global Temperature Deviations") 82 | ``` 83 | 84 | Example 1.3 85 | 86 | ```r 87 | tsplot(speech) 88 | ``` 89 | 90 | Example 1.4 91 | 92 | ```r 93 | library(xts) # install it if you don't have it 94 | djiar = diff(log(djia$Close))[-1] 95 | plot(djiar, col=4, main="DJIA Returns") 96 | ``` 97 | 98 | Example 1.5 99 | 100 | ```r 101 | par(mfrow = c(2,1)) # set up the graphics 102 | tsplot(soi, col=4, ylab="", main="Southern Oscillation Index") 103 | tsplot(rec, col=4, ylab="", main="Recruitment") 104 | ``` 105 | 106 | Example 1.6 107 | 108 | ```r 109 | par(mfrow=c(2,1)) 110 | tsplot(fmri1[,2:5], col=1:4, ylab="BOLD", main="Cortex", spaghetti=TRUE) 111 | tsplot(fmri1[,6:9], col=1:4, ylab="BOLD", main="Thalamus & Cerebellum", spaghetti=TRUE) 112 | 113 | # each separately (not in text) 114 | tsplot(fmri1[,2:9], col=1:8, lwd=2, ncol=2, ylim=c(-.6,.6)) 115 | 116 | # and another view (not in text) 117 | x = ts(fmri1[,4:9], start=0, freq=32) 118 | names = c("Cortex","Thalamus","Cerebellum") 119 | u = ts(rep(c(rep(.6,16), rep(-.6,16)), 4), start=0, freq=32) # stimulus signal 120 | par(mfrow=c(3,1)) 121 | for (i in 1:3){ 122 | j = 2*i - 1 123 | tsplot(x[,j:(j+1)], ylab="BOLD", xlab="", main=names[i], col=5:6, ylim=c(-.6,.6), 124 | lwd=2, xaxt="n", spaghetti=TRUE) 125 | axis(seq(0,256,64), side=1, at=0:4) 126 | lines(u, type="s", col=gray(.3)) 127 | } 128 | mtext("seconds", side=1, line=1.75, cex=.9) 129 | ``` 130 | 131 | Example 1.7 132 | 133 | ```r 134 | par(mfrow=2:1) 135 | tsplot(EQ5, col=4, main="Earthquake") 136 | tsplot(EXP6, col=4, main="Explosion") 137 | 138 | # or try (not in text) 139 | tsplot(cbind(EQ5,EXP6), col=4) 140 | ``` 141 | 142 | Example 1.9 143 | 144 | ```r 145 | w = rnorm(500,0,1) # 500 N(0,1) variates 146 | v = filter(w, sides=2, rep(1/3,3)) # moving average 147 | par(mfrow=c(2,1)) 148 | tsplot(w, col=4, main="white noise") 149 | tsplot(v, col=4, ylim=c(-3,3), main="moving average") 150 | ``` 151 | 152 | Example 1.10 153 | 154 | ```r 155 | w = rnorm(550,0,1) # 50 extra to avoid startup problems 156 | x = filter(w, filter=c(1,-.9), method="recursive")[-(1:50)] 157 | tsplot(x, col=4, main="autoregression") 158 | ``` 159 | 160 | Example 1.11 161 | 162 | ```r 163 | set.seed(154) # so you can reproduce the results 164 | w = rnorm(200); x = cumsum(w) # two commands in one line 165 | wd = w +.2; xd = cumsum(wd) 166 | tsplot(xd, ylim=c(-5,55), main="random walk", ylab='') 167 | lines(x, col=4) 168 | clip(0,200,0,50) 169 | abline(h=0, col=4, lty=2) 170 | abline(a=0, b=.2, lty=2) 171 | ``` 172 | 173 | Example 1.12 174 | 175 | ```r 176 | cs = 2*cos(2*pi*(1:500)/50 + .6*pi) 177 | w = rnorm(500,0,1) 178 | par(mfrow=c(3,1)) 179 | tsplot(cs, ylab="", main = expression(x[t]==2*cos(2*pi*t/50+.6*pi))) 180 | tsplot(cs + w, ylab="", main = expression(x[t]==2*cos(2*pi*t/50+.6*pi)+N(0,1))) 181 | tsplot(cs + 5*w, ylab="", main = expression(x[t]==2*cos(2*pi*t/50+.6*pi)+N(0,25))) 182 | ``` 183 | 184 | Example 1.24 185 | 186 | ```r 187 | set.seed(2) 188 | x = rnorm(100) 189 | y = lag(x, -5) + rnorm(100) 190 | ccf2(y, x, ylab='CCovF', type='covariance') 191 | text( 9, 1.1, 'x leads') 192 | text(-8, 1.1, 'y leads') 193 | ``` 194 | 195 | Example 1.25 196 | 197 | ```r 198 | (r = round( acf1(soi, 6, plot=FALSE), 2)) # sample acf values 199 | par(mfrow=c(1,2)) 200 | tsplot(lag(soi,-1), soi, col=4, type='p', xlab='lag(soi,-1)') 201 | legend("topleft", legend=r[1], bg="white", adj=.45, cex = 0.85) 202 | tsplot(lag(soi,-6), soi, col=4, type='p', xlab='lag(soi,-6)') 203 | legend("topleft", legend=r[6], bg="white", adj=.25, cex = 0.8) 204 | ``` 205 | 206 | Example 1.26 207 | 208 | ```r 209 | set.seed(666) 210 | x1 = sample(c(-1,1), 11, replace=TRUE) # simulated sequence of coin tosses 211 | x2 = sample(c(-1,1), 101, replace=TRUE) 212 | y1 = 5 + filter(x1, sides=1, filter=c(1,-.7))[-1] 213 | y2 = 5 + filter(x2, sides=1, filter=c(1,-.7))[-1] 214 | tsplot(y1, type='s') # plot 1st series 215 | points(y1, pch=19) 216 | c(mean(y1), mean(y2)) # the sample means 217 | acf(y1, lag.max=4, plot=FALSE) 218 | acf(y2, lag.max=4, plot=FALSE) 219 | 220 | ######################################### 221 | # here's the version from the other text - 222 | # same idea but the y values are 2-4-6-8 223 | # like the children's cheer 224 | 225 | set.seed(101011) 226 | x1 = sample(c(-2,2), 11, replace=TRUE) # simulated coin tosses 227 | x2 = sample(c(-2,2), 101, replace=TRUE) 228 | y1 = 5 + filter(x1, sides=1, filter=c(1,-.5))[-1] 229 | y2 = 5 + filter(x2, sides=1, filter=c(1,-.5))[-1] 230 | tsplot(y1, type="s", col=4, xaxt="n", yaxt="n") # y2 not shown 231 | axis(1, 1:10); axis(2, seq(2,8,2), las=1) 232 | points(y1, pch=21, cex=1.1, bg=6) 233 | acf(y1, lag.max=4, plot=FALSE) 234 | acf(y2, lag.max=4, plot=FALSE) 235 | ``` 236 | 237 | Example 1.27 238 | 239 | ```r 240 | acf1(speech, 250) 241 | ``` 242 | 243 | Example 1.28 244 | 245 | ```r 246 | par(mfrow=c(3,1)) 247 | acf1(soi, main="Southern Oscillation Index") 248 | acf1(rec, main="Recruitment") 249 | ccf2(soi, rec, main="SOI vs Recruitment") 250 | ``` 251 | 252 | Example 1.29 253 | 254 | ```r 255 | set.seed(1492) 256 | num = 120 257 | t = 1:num 258 | X = ts(2*cos(2*pi*t/12) + rnorm(num), freq=12) 259 | Y = ts(2*cos(2*pi*(t+5)/12) + rnorm(num), freq=12) 260 | Yw = resid( lm(Y~ cos(2*pi*t/12) + sin(2*pi*t/12), na.action=NULL) ) 261 | par(mfrow=c(3,2) ) 262 | tsplot(X) 263 | tsplot(Y) 264 | acf1(X, 48, ylab='ACF(X)') 265 | acf1(Y, 48, ylab='ACF(Y)') 266 | ccf2(X, Y, 24) 267 | ccf2(X, Yw, 24, ylim=c(-.6,.6)) 268 | ################################################ 269 | 270 | # here's another example that's simpler 271 | # the series are trend stationary with 272 | # just a hint of trend - but same result 273 | 274 | set.seed(90210) 275 | num = 250 276 | t = 1:num 277 | X = .01*t + rnorm(num,0,2) 278 | Y = .01*t + rnorm(num) 279 | par(mfrow=c(3,1)) 280 | tsplot(cbind(X,Y), spag=TRUE, col=astsa.col(c(4,2),.7), lwd=2, ylab='data') 281 | ccf2(X, Y, ylim=c(-.3,.3), col=4, lwd=2) 282 | Yw = detrend(Y) # whiten Y by removing trend 283 | ccf2(X, Yw, ylim=c(-.3,.3), col=4, lwd=2) 284 | ``` 285 | 286 | Example 1.30 287 | 288 | ```r 289 | par(mar=rep(1,4)) 290 | persp(1:64, 1:36, soiltemp, phi=30, theta=30, scale=FALSE, expand=4, 291 | ticktype="detailed", xlab="rows", ylab="cols", zlab="temperature") 292 | dev.new() 293 | tsplot(rowMeans(soiltemp), xlab="row", ylab="Average Temperature") 294 | ``` 295 | 296 | Example 1.31 297 | 298 | ```r 299 | fs = abs(fft(soiltemp-mean(soiltemp)))^2/(64*36) # see Ch 4 for info on FFT 300 | cs = Re(fft(fs, inverse=TRUE)/sqrt(64*36)) # ACovF 301 | rs = cs/cs[1,1] # ACF 302 | 303 | rs2 = cbind(rs[1:41,21:2], rs[1:41,1:21]) # these lines are just to center 304 | rs3 = rbind(rs2[41:2,], rs2) # the 0 lag 305 | 306 | par(mar = c(1,2.5,0,0)+.1) 307 | persp(-40:40, -20:20, rs3, phi=30, theta=30, expand=30, scale="FALSE", 308 | ticktype="detailed", xlab="row lags", ylab="column lags", zlab="ACF") 309 | ``` 310 | 311 | [top](#table-of-contents) 312 | 313 | --- 314 | 315 | 316 | 317 | ## Chapter 2 318 | 319 | 320 | Example 2.1 321 | 322 | ```r 323 | # astsa now has a trend script, so Figure 2.1 can be done in one line 324 | trend(chicken, lwd=2) # includes a 95% CI 325 | 326 | # in the text 327 | summary(fit <- lm(chicken~time(chicken))) # regress price on time 328 | tsplot(chicken, ylab="cents per pound", col=4, lwd=2) 329 | abline(fit) # add the fitted regression line to the plot 330 | ``` 331 | 332 | Example 2.2 333 | 334 | ```r 335 | ##-- separate 336 | par(mfrow=c(3,1)) 337 | tsplot(cmort, main="Cardiovascular Mortality", col=6, type="o", pch=19, ylab="") 338 | tsplot(tempr, main="Temperature", col=4, type="o", pch=19, ylab="") 339 | tsplot(part, main="Particulates", col=2, type="o", pch=19, ylab="") 340 | 341 | ##-- together 342 | dev.new() 343 | tsplot(cbind(cmort, tempr, part), spag=TRUE, ylab="", col=c(6,4,2)) 344 | legend("topright", legend=c("Mortality", "Temperature", "Pollution"), lty=1, lwd=2, col=c(6,4,2), bg="white") 345 | 346 | ##-- scatterplot matrix 347 | dev.new() 348 | panel.cor <- function(x, y, ...){ 349 | usr <- par("usr") 350 | par(usr = c(0, 1, 0, 1)) 351 | r <- round(cor(x, y), 2) 352 | text(0.5, 0.5, r, cex = 1.75) 353 | } 354 | pairs(cbind(Mortality=cmort, Temperature=tempr, Particulates=part), col=4, lower.panel=panel.cor) 355 | 356 | # Regression 357 | temp = tempr-mean(tempr) # center temperature 358 | temp2 = temp^2 # square it 359 | trend = time(cmort) # time 360 | 361 | fit = lm(cmort~ trend + temp + temp2 + part, na.action=NULL) 362 | 363 | summary(fit) # regression results 364 | summary(aov(fit)) # ANOVA table (compare to next line) 365 | summary(aov(lm(cmort~cbind(trend, temp, temp2, part)))) # Table 2.1 366 | 367 | num = length(cmort) # sample size 368 | AIC(fit)/num - log(2*pi) # AIC 369 | BIC(fit)/num - log(2*pi) # BIC 370 | (AICc = log(sum(resid(fit)^2)/num) + (num+5)/(num-5-2)) # AICc 371 | ``` 372 | 373 | Examples 2.3 374 | 375 | ```r 376 | fish = ts.intersect(rec, soiL6=lag(soi,-6), dframe=TRUE) 377 | summary(fit <- lm(rec~soiL6, data=fish, na.action=NULL)) 378 | ## not shown in text but resids are not white 379 | par(mfrow=2:1) 380 | tsplot(resid(fit)) 381 | acf1(resid(fit)) 382 | ``` 383 | 384 | 385 | 386 | Examples 2.4 and 2.5 387 | 388 | ```r 389 | # astsa now has a detrend script, so Figure 2.4 can be done as 390 | par(mfrow=2:1) 391 | tsplot( detrend(chicken), main="detrended" ) 392 | tsplot( diff(chicken), main="first difference" ) 393 | 394 | # and Figure 2.5 as 395 | dev.new() 396 | par(mfrow=c(3,1)) # plot ACFs 397 | acf1(chicken, 48, main="chicken") 398 | acf1(detrend(chicken), 48, main="detrended") 399 | acf1(diff(chicken), 48, main="first difference") 400 | ``` 401 | 402 | 403 | Example 2.6 404 | 405 | ```r 406 | par(mfrow=c(2,1)) 407 | tsplot(diff(globtemp), type="o") 408 | mean(diff(globtemp)) # drift estimate = .008 409 | acf1(diff(gtemp), 48, main="") 410 | ``` 411 | 412 | Example 2.7 413 | 414 | ```r 415 | layout(matrix(1:4,2), widths=c(2.5,1)) 416 | tsplot(varve, main="", ylab="", col=4) 417 | mtext("varve", side=3, line=.5, cex=1.2, font=2, adj=0) 418 | tsplot(log(varve), main="", ylab="", col=4) 419 | mtext("log(varve)", side=3, line=.5, cex=1.2, font=2, adj=0) 420 | qqnorm(varve, main="", col=4) 421 | qqline(varve, col=2, lwd=2) 422 | qqnorm(log(varve), main="", col=4) 423 | qqline(log(varve), col=2, lwd=2) 424 | ``` 425 | 426 | Example 2.8 427 | 428 | ```r 429 | lag1.plot(soi, 12, col=astsa.col(4, .3), cex=1.5, pch=20) 430 | dev.new() 431 | lag2.plot(soi, rec, 8, col=astsa.col(4, .3), cex=1.5, pch=20) 432 | ``` 433 | 434 | Example 2.9 435 | 436 | ```r 437 | dummy = ifelse(soi<0, 0, 1) 438 | fish = ts.intersect(rec, soiL6=lag(soi,-6), dL6=lag(dummy,-6), dframe=TRUE) 439 | summary(fit <- lm(rec~ soiL6*dL6, data=fish, na.action=NULL)) 440 | tsplot(fish$soiL6, fish$rec, type='p', col=4, ylab='rec', xlab='soiL6') 441 | lines(lowess(fish$soiL6, fish$rec), col=4, lwd=2) 442 | points(fish$soiL6, fitted(fit), pch='+', col=6) 443 | 444 | dev.new() 445 | par(mfrow=2:1) 446 | tsplot(resid(fit)) # not shown ... 447 | acf1(resid(fit)) # ... but obviously not noise 448 | ``` 449 | 450 | 451 | Example 2.10 452 | 453 | ```r 454 | set.seed(1000) # so you can reproduce these results 455 | x = 2*cos(2*pi*1:500/50 + .6*pi) + rnorm(500,0,5) 456 | z1 = cos(2*pi*1:500/50) 457 | z2 = sin(2*pi*1:500/50) 458 | summary(fit <- lm(x~0+z1+z2)) # zero to exclude the intercept 459 | par(mfrow=c(2,1)) 460 | tsplot(x, col=4) 461 | tsplot(x, col=astsa.col(4,.7), ylab=expression(hat(x))) 462 | lines(fitted(fit), col=2, lwd=2) 463 | ``` 464 | 465 | 466 | Example 2.11 467 | 468 | ```r 469 | wgts = c(.5, rep(1,11), .5)/12 470 | soif = filter(soi, sides=2, filter=wgts) 471 | tsplot(soi, col=4) 472 | lines(soif, lwd=2, col=6) 473 | par(fig = c(.75, 1, .75, 1), new = TRUE) # the insert 474 | nwgts = c(rep(0,20), wgts, rep(0,20)) 475 | plot(nwgts, type="l", ylim = c(-.02,.1), xaxt='n', yaxt='n', ann=FALSE) 476 | ``` 477 | 478 | 479 | Example 2.12 480 | 481 | ```r 482 | tsplot(soi, col=4) 483 | lines(ksmooth(time(soi), soi, "normal", bandwidth=1), lwd=2, col=6) 484 | par(fig = c(.75, 1, .75, 1), new = TRUE) # the insert 485 | curve(dnorm, -3, 3, xaxt='n', yaxt='n', ann=FALSE) 486 | ``` 487 | 488 | 489 | Example 2.13 490 | 491 | ```r 492 | # Figure 2.14 using the trend script 493 | trend(soi, lowess=TRUE) 494 | lines(lowess(soi, f=.05), lwd=2, col=6) # El Niño cycle 495 | ``` 496 | 497 | 498 | 499 | Example 2.14 500 | 501 | ```r 502 | tsplot(soi) 503 | lines(smooth.spline(time(soi), soi, spar=.5), lwd=2, col=4) 504 | lines(smooth.spline(time(soi), soi, spar= 1), lty=2, lwd=2, col=2) 505 | ``` 506 | 507 | Example 2.15 508 | 509 | ```r 510 | tsplot(tempr, cmort, type="p", xlab="Temperature", ylab="Mortality", pch=20, col=4) 511 | lines(lowess(tempr, cmort), col=6, lwd=2) 512 | ``` 513 | 514 | [top](#table-of-contents) 515 | 516 | --- 517 | 518 | 519 | 520 | ## Chapter 3 521 | 522 | > The way AIC, AICc, and BIC are calculated in `sarima` changed a few versions ago. The values in the text will be different than the current values, but the results of any data analysis in the text are the same. 523 | 524 |
525 | 526 | 527 | 528 | 529 | Example 3.2 530 | 531 | ```r 532 | par(mfrow=c(2,1)) 533 | # in the expressions below, ~ is a space and == is equal 534 | tsplot(sarima.sim(ar= .9, n=100), col=4, ylab="", main=(expression(AR(1)~~~phi==+.9))) 535 | tsplot(sarima.sim(ar=-.9, n=100), col=4, ylab="", main=(expression(AR(1)~~~phi==-.9))) 536 | ``` 537 | 538 | Example 3.5 539 | 540 | ```r 541 | par(mfrow=c(2,1)) 542 | tsplot(sarima.sim(ma= .9, n=100), col=4, ylab="", main=(expression(MA(1)~~~theta==+.9))) 543 | tsplot(sarima.sim(ma=-.9, n=100), col=4, ylab="", main=(expression(MA(1)~~~theta==-.9))) 544 | ``` 545 | 546 | Example 3.7 547 | 548 | ```r 549 | set.seed(8675309) # Jenny, I got your number 550 | x = rnorm(150, mean=5) # Jenerate iid N(5,1)s 551 | arima(x, order=c(1,0,1)) # Jenstimation 552 | ``` 553 | 554 | Example 3.8 555 | 556 | ```r 557 | ARMAtoMA(ar = .9, ma = .5, 10) # first 10 psi-weights 558 | ARMAtoAR(ar = .9, ma = .5, 10) # first 10 pi-weights 559 | ``` 560 | 561 | Example 3.9 562 | ```r 563 | # this is how Figure 3.3 was generated 564 | seg1 = seq( 0, 2, by=0.1) 565 | seg2 = seq(-2, 2, by=0.1) 566 | name1 = expression(phi[1]) 567 | name2 = expression(phi[2]) 568 | tsplot(seg1, (1-seg1), ylim=c(-1,1), xlim=c(-2,2), ylab=name2, xlab=name1, 569 | main='Causal Region of an AR(2)') 570 | lines(-seg1, (1-seg1), ylim=c(-1,1), xlim=c(-2,2)) 571 | abline(h=0, v=0, lty=2, col=8) 572 | lines(seg2, -(seg2^2 /4), ylim=c(-1,1)) 573 | lines( x=c(-2,2), y=c(-1,-1), ylim=c(-1,1)) 574 | text(0, .35, 'real roots') 575 | text(0, -.5, 'complex roots') 576 | ``` 577 | 578 | 579 | Example 3.11 580 | 581 | ```r 582 | z = c(1,-1.5,.75) # coefficients of the polynomial 583 | (a = polyroot(z)[1]) # = 1+0.57735i, print one root which is 1 + i 1/sqrt(3) 584 | arg = Arg(a)/(2*pi) # arg in cycles/pt 585 | 1/arg # = 12, the period 586 | 587 | par(mfrow=c(3,1)) 588 | set.seed(8675309) # Jenny, it's me again 589 | ar2 = sarima.sim(ar=c(1.5,-.75), n=144, S=12) 590 | tsplot(ar2, xlab="Year") 591 | 592 | ACF = ARMAacf(ar=c(1.5,-.75), ma=0, 50)[-1] 593 | tsplot(ACF, type="h", xlab="lag") 594 | abline(h=0, col=8) 595 | 596 | # alternately - not in text 597 | ACF = ARMAacf(ar=c(1.5,-.75), ma=0, 50) 598 | tsplot(0:50, ACF, type="h", xlab="lag") 599 | abline(h=0, col=8) 600 | 601 | 602 | # psi-weights - not in text 603 | psi = ts(ARMAtoMA(ar=c(1.5,-.75), ma=0, 50), start=0, freq=12) 604 | tsplot(psi, type='o', cex=1.1, ylab=expression(psi-weights), xaxt='n', xlab='Index') 605 | axis(1, at=0:4, labels=c('0','12','24','36','48')) 606 | 607 | # you can play the same game with the ACF - not in text 608 | ACF = ts(ARMAacf(ar=c(1.5,-.75), ma=0, 50), start=0, frequency=12) 609 | tsplot(ACF, type='h', xaxt='n', xlab='LAG') 610 | abline(h=0, col=8) 611 | axis(1, at=0:4, labels=c('0','12','24','36','48')) 612 | 613 | ``` 614 | 615 | Example 3.12 616 | 617 | ```r 618 | psi = ARMAtoMA(ar=.9, ma=.5, 50) # for a list 619 | tsplot(psi, type='h', ylab=expression(psi-weights), xlab='Index') # for a graph 620 | ``` 621 | 622 | 623 | Example 3.16 624 | 625 | ```r 626 | ar2.acf = ARMAacf(ar=c(1.5,-.75), ma=0, 24)[-1] 627 | ar2.pacf = ARMAacf(ar=c(1.5,-.75), ma=0, 24, pacf=TRUE) 628 | par(mfrow=1:2) 629 | tsplot(ar2.acf, type="h", xlab="lag", lwd=3, nxm=5, col=c(rep(4,11), 6)) 630 | tsplot(ar2.pacf, type="h", xlab="lag", lwd=3, nxm=5, col=4) 631 | ``` 632 | 633 | Example 3.18 634 | 635 | ```r 636 | acf2(rec, 48) # will produce values and a graphic 637 | (regr = ar.ols(rec, order=2, demean=FALSE, intercept=TRUE)) # regression 638 | regr$asy.se.coef # standard errors 639 | ``` 640 | 641 | 642 | Example 3.25 643 | 644 | ```r 645 | regr = ar.ols(rec, order=2, demean=FALSE, intercept=TRUE) 646 | fore = predict(regr, n.ahead=24) 647 | tsplot(cbind(rec, fore$pred), spag=TRUE, col=1:2, xlim=c(1980,1990), ylab="Recruitment") 648 | lines(fore$pred, type="p", col=2) 649 | lines(fore$pred+fore$se, lty="dashed", col=4) 650 | lines(fore$pred-fore$se, lty="dashed", col=4) 651 | ``` 652 | 653 | Example 3.26 654 | 655 | ```r 656 | set.seed(666) 657 | x = sarima.sim(ar=.9, ma=.5, n=100) 658 | xr = rev(x) # xr is the reversed data 659 | pxr = predict(arima(xr, order=c(1,0,1)), 10) # predict the reversed data 660 | pxrp = rev(pxr$pred) # reorder the predictors (for plotting) 661 | pxrse = rev(pxr$se) # reorder the SEs 662 | nx = ts(c(pxrp, x), start=-9) # attach the backcasts to the data 663 | tsplot(nx, ylab=expression(X[~t]), main='Backcasting', ylim=c(-7,4)) 664 | U = nx[1:10] + pxrse 665 | L = nx[1:10] - pxrse 666 | xx = c(-9:0, 0:-9) 667 | yy = c(L, rev(U)) 668 | polygon(xx, yy, border = 8, col = gray(0.6, alpha = 0.2)) 669 | lines(-9:0, nx[1:10], col=2, type='o') 670 | ``` 671 | 672 | 673 | Example 3.28 674 | 675 | ```r 676 | rec.yw = ar.yw(rec, order=2) 677 | rec.yw$x.mean # = 62.26278 (mean estimate) 678 | rec.yw$ar # = 1.3315874, -.4445447 (parameter estimates) 679 | sqrt(diag(rec.yw$asy.var.coef)) # = .04222637, .04222637 (standard errors) 680 | rec.yw$var.pred # = 94.79912 (error variance estimate) 681 | 682 | rec.pr = predict(rec.yw, n.ahead=24) 683 | U = rec.pr$pred + rec.pr$se 684 | L = rec.pr$pred - rec.pr$se 685 | tsplot(cbind(rec, rec.pr$pred), spag=TRUE, xlim=c(1980,1990), ylab="Recruitment") 686 | lines(rec.pr$pred, col=2, type="o") 687 | lines(U, col=4, lty=2) 688 | lines(L, col=4, lty=2) 689 | ``` 690 | 691 | Example 3.29 692 | 693 | ```r 694 | set.seed(1) 695 | ma1 = sarima.sim(ma=.9, n=50) 696 | acf1(ma1, 1, plot=FALSE) # [1] .536 (lag 1 sample ACF) 697 | ``` 698 | 699 | Example 3.31 700 | 701 | ```r 702 | rec.mle = ar.mle(rec, order=2) 703 | rec.mle$x.mean 704 | rec.mle$ar 705 | sqrt(diag(rec.mle$asy.var.coef)) 706 | rec.mle$var.pred 707 | ``` 708 | 709 | 710 | 711 | Example 3.33 712 | 713 | ```r 714 | x = diff(log(varve)) # data 715 | r = acf1(x, 1, plot=FALSE) # acf(1) 716 | c(0) -> z -> Sc -> Sz -> Szw -> para # initialize .. 717 | c(x[1]) -> w # .. all variables 718 | num = length(x) # 633 719 | 720 | ## Gauss-Newton Estimation 721 | para[1] = (1-sqrt(1-4*(r^2)))/(2*r) # MME to start (not very good) 722 | niter = 12 723 | for (j in 1:niter){ 724 | for (t in 2:num){ w[t] = x[t] - para[j]*w[t-1] 725 | z[t] = w[t-1] - para[j]*z[t-1] 726 | } 727 | Sc[j] = sum(w^2) 728 | Sz[j] = sum(z^2) 729 | Szw[j] = sum(z*w) 730 | para[j+1] = para[j] + Szw[j]/Sz[j] 731 | } 732 | ## Results 733 | cbind(iteration=1:niter-1, thetahat=para[1:niter], Sc, Sz) 734 | 735 | ## Plot conditional SS and results 736 | c(0) -> cSS 737 | th = -seq(.3, .94, .01) 738 | for (p in 1:length(th)){ 739 | for (t in 2:num){ w[t] = x[t] - th[p]*w[t-1] 740 | } 741 | cSS[p] = sum(w^2) 742 | } 743 | tsplot(th, cSS, ylab=expression(S[c](theta)), xlab=expression(theta)) 744 | abline(v=para[1:12], lty=2, col=4) # add previous results to plot 745 | points(para[1:12], Sc[1:12], pch=16, col=4) 746 | ``` 747 | 748 | 749 | 750 | Example 3.36 751 | 752 | ```r 753 | # generate data 754 | set.seed(101010) 755 | e = rexp(150, rate=.5) 756 | u = runif(150,-1,1) 757 | de = e*sign(u) 758 | dex = 50 + sarima.sim(n=100, ar=.95, innov=de, burnin=50) 759 | tsplot(dex, ylab=expression(X[~t])) 760 | 761 | # Bootstrap 762 | set.seed(666) # not that 666 763 | fit = ar.yw(dex, order=1) # assumes the data were retained 764 | m = fit$x.mean # estimate of mean 765 | phi = fit$ar # estimate of phi 766 | nboot = 250 # number of bootstrap replicates 767 | resids = fit$resid[-1] # the 99 innovations 768 | x.star = dex # initialize x* 769 | phi.star.yw = c() # initialize phi* 770 | 771 | for (i in 1:nboot) { 772 | resid.star = sample(resids, replace=TRUE) 773 | x.star = sarima.sim(n=99, ar=phi, innov=resid.star, burnin=0) + m 774 | phi.star.yw[i] = ar.yw(x.star, order=1)$ar 775 | } 776 | 777 | # small sample distn 778 | set.seed(111) 779 | phi.yw = rep(NA, 1000) 780 | for (i in 1:1000){ 781 | e = rexp(150, rate=.5); u = runif(150,-1,1); de = e*sign(u) 782 | x = 50 + arima.sim(n=100,list(ar=.95), innov=de, n.start=50) 783 | phi.yw[i] = ar.yw(x, order=1)$ar 784 | } 785 | 786 | # Picture 787 | hist(phi.star.yw, 15, main="", prob=TRUE, xlim=c(.65,1.05), ylim=c(0,14), 788 | col=astsa.col(4,.3), xlab=expression(hat(phi))) 789 | lines(density(phi.yw, bw=.02), lwd=2) 790 | curve(dnorm(x, mean=.96, sd=.03), .75,1.1, lty=2, lwd=2, add=TRUE) 791 | legend(.65, 14, bty='n', lty=c(1,0,2), lwd=c(2,0,2), col=1, pch=c(NA,22,NA), 792 | pt.bg=c(NA,astsa.col(4,.3),NA), pt.cex=2.5, 793 | legend=c('true distribution', 'bootstrap distribution', 'normal approximation')) 794 | ``` 795 | 796 | 797 | Example 3.38 798 | 799 | ```r 800 | set.seed(666) 801 | x = sarima.sim(ma = -0.8, d=1, n = 100) 802 | (x.ima = HoltWinters(x, beta=FALSE, gamma=FALSE)) # α is 1-λ here 803 | plot(x.ima) 804 | ``` 805 | 806 | Example 3.39, 3.40, and 3.43 807 | 808 | ```r 809 | tsplot(gnp, col=4) 810 | 811 | dev.new() 812 | acf2(gnp, 50) # compare to acf2(1:250, 50) 813 | gnpgr = diff(log(gnp)) # growth rate 814 | 815 | dev.new() 816 | tsplot(gnpgr, col=4) 817 | 818 | dev.new() 819 | acf2(gnpgr, 24) 820 | sarima(gnpgr, 1, 0, 0) # AR(1) 821 | sarima(gnpgr, 0, 0, 2) # MA(2) 822 | ARMAtoMA(ar=.35, ma=0, 10) # prints psi-weights 823 | ``` 824 | 825 | Example 3.41 826 | 827 | ```r 828 | sarima(log(varve), 0,1,1, no.constant=TRUE, gg=TRUE, col=4) # ARIMA(0,1,1) 829 | 830 | dev.new() 831 | sarima(log(varve), 1,1,1, no.constant=TRUE, gg=TRUE, col=4) # ARIMA(1,1,1) 832 | ``` 833 | 834 | Example 3.44 835 | 836 | ```r 837 | trend = time(cmort) 838 | temp = tempr - mean(tempr) 839 | temp2 = temp^2 840 | summary(fit <- lm(cmort~trend + temp + temp2 + part, na.action=NULL)) 841 | acf2(resid(fit), 52) # implies AR2 842 | sarima(cmort, 2,0,0, xreg=cbind(trend,temp,temp2,part) ) 843 | ``` 844 | 845 | Example 3.45 846 | 847 | ```r 848 | # Note: this could benefit from a seasonal model fit, but it hasn't 849 | # been talked about yet - you could come back to this after the next section 850 | dummy = ifelse(soi<0, 0, 1) 851 | fish = ts.intersect(rec, soiL6=lag(soi,-6), dL6=lag(dummy,-6), dframe=TRUE) 852 | summary(fit <- lm(rec ~soiL6*dL6, data=fish, na.action=NULL)) 853 | plot(resid(fit)) 854 | acf2(resid(fit)) # indicates AR(2) 855 | intract = fish$soiL6*fish$dL6 # interaction term 856 | sarima(fish$rec, 2,0,0, xreg = cbind(fish$soiL6, fish$dL6, intract)) 857 | ``` 858 | 859 | 860 | 861 | Example 3.46 862 | 863 | ```r 864 | set.seed(666) 865 | SAR = sarima.sim(sar=.9, S=12, n=37) + 50 866 | layout(matrix(c(1,2, 1,3), nc=2), heights=c(1.5,1)) 867 | tsplot(SAR, type="c", xlab="Year") 868 | abline(v=1:3, col=4, lty=2) 869 | points(SAR, pch=Months, cex=1.35, font=4, col=1:6) 870 | 871 | phi = c(rep(0,11),.9) 872 | ACF = ARMAacf(ar=phi, ma=0, 100)[-1] # [-1] removes 0 lag 873 | PACF = ARMAacf(ar=phi, ma=0, 100, pacf=TRUE) 874 | LAG = 1:100/12 875 | tsplot(LAG, ACF, type="h", xlab="LAG", ylim=c(-.04,1)) 876 | abline(h=0, col=8) 877 | tsplot(LAG, PACF, type="h", xlab="LAG", ylim=c(-.04,1)) 878 | abline(h=0, col=8) 879 | ``` 880 | 881 | 882 | Example 3.47 883 | 884 | ```r 885 | par(mfrow=1:2) 886 | phi = c(rep(0,11),.8) 887 | ACF = ARMAacf(ar=phi, ma=-.5, 50)[-1] 888 | PACF = ARMAacf(ar=phi, ma=-.5, 50, pacf=TRUE) 889 | LAG = 1:50/12 890 | tsplot(LAG, ACF, type="h", xlab="LAG", ylim=c(-.4,.8), col=4, lwd=2) 891 | abline(h=0, col=8) 892 | tsplot(LAG, PACF, type="h", xlab="LAG", ylim=c(-.4,.8), col=4, lwd=2) 893 | abline(h=0, col=8) 894 | ``` 895 | 896 | 897 | Example 3.49 898 | 899 | ```r 900 | x = AirPassengers 901 | lx = log(x) 902 | dlx = diff(lx) 903 | ddlx = diff(dlx, 12) 904 | tsplot(cbind(x, lx, dlx, ddlx), main="") 905 | 906 | # below of interest for showing seasonal persistence (not shown here): 907 | par(mfrow=c(2,1)) 908 | monthplot(dlx) 909 | monthplot(ddlx) 910 | 911 | sarima(lx, 1,1,1, 0,1,1, 12) # model 1 912 | sarima(lx, 0,1,1, 0,1,1, 12) # model 2 (the winner) 913 | sarima(lx, 1,1,0, 0,1,1, 12) # model 3 914 | 915 | dev.new() 916 | sarima.for(lx, 12, 0,1,1, 0,1,1,12) # forecasts 917 | ``` 918 | 919 | [top](#table-of-contents) 920 | 921 | --- 922 | 923 | ## Chapter 4 924 | 925 | 926 | Example 4.1 927 | ```r 928 | x1 = 2*cos(2*pi*1:100*6/100) + 3*sin(2*pi*1:100*6/100) 929 | x2 = 4*cos(2*pi*1:100*10/100) + 5*sin(2*pi*1:100*10/100) 930 | x3 = 6*cos(2*pi*1:100*40/100) + 7*sin(2*pi*1:100*40/100) 931 | x = x1 + x2 + x3 932 | 933 | par(mfrow=c(2,2)) 934 | tsplot(x1, ylim=c(-10,10), main = expression(omega==6/100~~~A^2==13)) 935 | tsplot(x2, ylim=c(-10,10), main = expression(omega==10/100~~~A^2==41)) 936 | tsplot(x3, ylim=c(-10,10), main = expression(omega==40/100~~~A^2==85)) 937 | tsplot(x, ylim=c(-16,16), main="sum") 938 | ``` 939 | 940 | Example 4.2 941 | ```r 942 | # x from Example 4.1 is used here 943 | dev.new() 944 | P = abs(2*fft(x)/100)^2 945 | Fr = 0:99/100 946 | tsplot(Fr, P, type="o", xlab="frequency", ylab="periodogram") 947 | abline(v=.5, lty=2) 948 | ``` 949 | 950 | Example 4.3 951 | ```r 952 | # modulation 953 | t = 1:200 954 | tsplot(x <- 2*cos(2*pi*.2*t)*cos(2*pi*.01*t)) 955 | lines(cos(2*pi*.19*t)+cos(2*pi*.21*t), col=2) # the same 956 | Px = Mod(fft(x))^2 957 | tsplot(0:199/200, Px, type='o') # the periodogram 958 | 959 | # star mag analysis 960 | n = length(star) 961 | par(mfrow=c(2,1)) 962 | tsplot(star, ylab="star magnitude", xlab="day") 963 | Per = Mod(fft(star-mean(star)))^2/n 964 | Freq = (1:n -1)/n 965 | tsplot(Freq[1:50], Per[1:50], type='h', lwd=3, ylab="Periodogram", xlab="Frequency") 966 | text(.05, 7000, "24 day cycle") 967 | text(.027, 9000, "29 day cycle") 968 | #- a list to help find the peaks 969 | round( cbind(1/Freq[1:30], Per[1:30]), 3) 970 | ``` 971 | 972 | 973 | 974 | 975 | Examples 4.5, 4.6, 4.7 976 | ```r 977 | # default is to not plot on log scale 978 | # add log='y' otherwise 979 | par(mfrow=c(3,1)) 980 | arma.spec(main="White Noise", col=4) 981 | arma.spec(ma=.5, main="Moving Average", col=4) 982 | arma.spec(ar=c(1,-.9), main="Autoregression", col=4) 983 | ``` 984 | 985 | 986 | Example 4.10 987 | ```r 988 | x = c(1,2,3,2,1) 989 | c1 = cos(2*pi*1:5*1/5) 990 | s1 = sin(2*pi*1:5*1/5) 991 | c2 = cos(2*pi*1:5*2/5) 992 | s2 = sin(2*pi*1:5*2/5) 993 | omega1 = cbind(c1, s1) 994 | omega2 = cbind(c2, s2) 995 | anova(lm(x~ omega1+omega2) ) # ANOVA Table 996 | Mod(fft(x))^2/5 # the periodogram (as a check) 997 | ``` 998 | 999 | Example 4.13 1000 | ```r 1001 | par(mfrow=c(2,1)) 1002 | soi.per = mvspec(soi) 1003 | abline(v=1/4, lty="dotted") 1004 | rec.per = mvspec(rec) 1005 | abline(v=1/4, lty="dotted") 1006 | 1007 | soi.per$details[1:50,] 1008 | # frequency period spectrum 1009 | # [9,] 0.225 4.4444 0.0309 1010 | # [10,] 0.250 4.0000 0.0537 1011 | # [11,] 0.275 3.6364 0.0754 1012 | # [12,] 0.300 3.3333 0.0567 1013 | # 1014 | # [39,] 0.975 1.0256 0.0167 1015 | # [40,] 1.000 1.0000 0.9722 1016 | # [41,] 1.025 0.9756 0.0054 1017 | 1018 | # conf intervals - returned value: 1019 | U = qchisq(.025,2) # 0.05063 1020 | L = qchisq(.975,2) # 7.37775 1021 | 2*soi.per$spec[10]/L # 0.01456 1022 | 2*soi.per$spec[10]/U # 2.12220 1023 | 2*soi.per$spec[40]/L # 0.26355 1024 | 2*soi.per$spec[40]/U # 38.40108 1025 | 1026 | # Repeat lines above using rec in place of soi 1027 | ``` 1028 | 1029 | Example 4.14 1030 | ```r 1031 | soi.ave = mvspec(soi, kernel('daniell',4)) 1032 | abline(v = c(.25,1,2,3), lty=2) 1033 | soi.ave$bandwidth # = 0.225 1034 | df = soi.ave$df # df = 16.9875 1035 | U = qchisq(.025, df) # U = 7.555916 1036 | L = qchisq(.975, df) # L = 30.17425 1037 | soi.ave$spec[10] # 0.0495202 1038 | soi.ave$spec[40] # 0.1190800 1039 | # intervals 1040 | df*soi.ave$spec[10]/L # 0.0278789 1041 | df*soi.ave$spec[10]/U # 0.1113333 1042 | df*soi.ave$spec[40]/L # 0.0670396 1043 | df*soi.ave$spec[40]/U # 0.2677201 1044 | 1045 | # Repeat above commands with soi replaced by rec, for example: 1046 | rec.ave = mvspec(rec, k) 1047 | abline(v=c(.25,1,2,3), lty=2) 1048 | # and so on. 1049 | ``` 1050 | 1051 | Example 4.15 1052 | ```r 1053 | t = seq(0, 1, by=1/200) 1054 | amps = c(1, .5, .4, .3, .2, .1) 1055 | x = matrix(0, 201, 6) 1056 | for (j in 1:6) x[,j] = amps[j]*sin(2*pi*t*2*j) 1057 | x = ts(cbind(x, rowSums(x)), start=0, deltat=1/200) 1058 | tsplot(x, lty=c(1:6, 1), lwd=c(rep(1,6), 2), ylab="Sinusoids", col=1:6, spaghetti=TRUE) 1059 | names = c("Fundamental","2nd Harmonic","3rd Harmonic","4th Harmonic","5th Harmonic", 1060 | "6th Harmonic","Formed Signal") 1061 | legend("topright", names, lty=c(1:6, 1), lwd=c(rep(1,6), 2), col=1:6) 1062 | rm(t) #Redemption 1063 | 1064 | ########################################################################## 1065 | # another view of the idea, sawtooth signal periodic but not sinusoidal # 1066 | ########################################################################## 1067 | y = ts(rev(1:100 %% 20), freq=20) # sawtooth signal 1068 | par(mfrow=2:1) 1069 | tsplot(1:100, y, ylab="sawtooth signal", col=4) 1070 | mvspec(y, main="", ylab="periodogram", col=5, xlim=c(0,7)) 1071 | ``` 1072 | 1073 | 1074 | 1075 | Example 4.16 1076 | ```r 1077 | kernel("modified.daniell", c(3,3)) # for a list 1078 | plot(kernel("modified.daniell", c(3,3))) # for a graph 1079 | 1080 | k = kernel("modified.daniell", c(3,3)) 1081 | soi.smo = mvspec(soi, kernel=k, taper=.1) 1082 | abline(v = c(.25,1), lty=2) 1083 | ## Repeat above lines with rec replacing soi 1084 | soi.smo$df # df = 17.42618 1085 | soi.smo$bandwidth # B = 0.2308103 1086 | 1087 | # An easier way to obtain soi.smo: 1088 | soi.smo = mvspec(soi, spans=c(7,7), taper=.1, nxm=4) 1089 | 1090 | # hightlight El Nino cycle 1091 | rect(1/7, -1e5, 1/3, 1e5, density=NA, col=gray(.5,.2)) 1092 | mtext("1/4", side=1, line=0, at=.25, cex=.75) 1093 | ``` 1094 | 1095 | 1096 | 1097 | Example 4.17 1098 | ```r 1099 | s0 = mvspec(soi, spans=c(7,7), plot=FALSE) # no taper 1100 | s50 = mvspec(soi, spans=c(7,7), taper=.5, plot=FALSE) # full taper 1101 | tsplot(s50$freq, s50$spec, log="y", type="l", ylab="spectrum", xlab="frequency") 1102 | lines(s0$freq, s0$spec, lty=2) 1103 | abline(v=.25, lty=2, col=8) 1104 | mtext('1/4',side=1, line=0, at=.25, cex=.9) 1105 | legend(5,.04, legend=c('full taper', 'no taper'), lty=1:2) 1106 | 1107 | text(1.42, 0.04, 'leakage', cex=.8) 1108 | arrows(1.4, .035, .75, .009, length=0.05,angle=30) 1109 | arrows(1.4, .035, 1.21, .0075, length=0.05,angle=30) 1110 | par(fig = c(.65, 1, .65, 1), new = TRUE, cex=.5, mgp=c(0,-.1,0), tcl=-.2) 1111 | taper <- function(x) { .5*(1+cos(2*pi*x)) } 1112 | x <- seq(from = -.5, to = .5, by = 0.001) 1113 | plot(x, taper(x), type = "l", lty = 1, yaxt='n', ann=FALSE) 1114 | ``` 1115 | 1116 | 1117 | Example 4.18 1118 | ```r 1119 | # AR spectrum - AIC picks order=15 1120 | u <- spec.ic(soi, detrend=TRUE, col=4, lwd=2, nxm=4) 1121 | # plot AIC and BIC 1122 | dev.new() 1123 | tsplot(0:30, u[[1]][,2:3], type='o', col=2:3, xlab='ORDER', nxm=5, lwd=2, gg=TRUE) 1124 | ``` 1125 | 1126 | 1127 | Example 4.21 1128 | ```r 1129 | sr = mvspec(cbind(soi,rec), kernel("daniell",9), plot.type="coh") 1130 | sr$df # df = 35.8625 1131 | f = qf(.999, 2, sr$df-2) # f = 8.529792 1132 | C = f/(18+f) # C = 0.3188779 1133 | abline(h = C) 1134 | ``` 1135 | 1136 | 1137 | Example 4.22 1138 | ```r 1139 | par(mfrow=c(3,1)) 1140 | tsplot(soi, col=4) # plot data 1141 | tsplot(diff(soi), col=4) # plot first difference 1142 | k = kernel("modified.daniell", 6) # filter weights 1143 | tsplot(soif <- kernapply(soi, k), col=4) # plot 12 month filter 1144 | dev.new() 1145 | mvspec(soif, spans=9, lwd=2, col=5, nxm=4, taper=.1) # spectral analysis (not shown) 1146 | rect(1/7, -1e5, 1/3, 1e5, density=NA, col=gray(.5,.2)) 1147 | mtext("1/4", side=1, line=0, at=.25, cex=.75) 1148 | dev.new() 1149 | ##-- frequency responses --## 1150 | par(mfrow=c(2,1)) 1151 | w = seq(0, .5, by=.01) 1152 | FRdiff = abs(1-exp(2i*pi*w))^2 1153 | tsplot(w, FRdiff, xlab='frequency') 1154 | u = cos(2*pi*w)+cos(4*pi*w)+cos(6*pi*w)+cos(8*pi*w)+cos(10*pi*w) 1155 | FRma = ((1 + cos(12*pi*w) + 2*u)/12)^2 1156 | tsplot(w, FRma, xlab='frequency') 1157 | ``` 1158 | 1159 | 1160 | Example 4.24 1161 | ```r 1162 | LagReg(soi, rec, L=15, M=32, threshold=6) 1163 | dev.new() 1164 | LagReg(rec, soi, L=15, M=32, inverse=TRUE, threshold=.01) 1165 | dev.new() 1166 | fish = ts.intersect(R=rec, RL1=lag(rec,-1), SL5=lag(soi,-5)) 1167 | (u = lm(fish[,1]~fish[,2:3], na.action=NULL)) 1168 | acf2(resid(u)) # suggests ar1 1169 | sarima(fish[,1], 1, 0, 0, xreg=fish[,2:3], details=FALSE) 1170 | ``` 1171 | 1172 | Example 4.25 1173 | ```r 1174 | SigExtract(soi, L=9, M=64, max.freq=.05) 1175 | ``` 1176 | 1177 | Example 4.26 1178 | ```r 1179 | per = abs(fft(soiltemp-mean(soiltemp))/sqrt(64*36))^2 1180 | per2 = cbind(per[1:32,18:2], per[1:32,1:18]) # this and line below is just rearranging 1181 | per3 = rbind(per2[32:2,], per2) # results to get 0 frequency in the middle 1182 | 1183 | par(mar=c(1,2.5,0,0)+.1) 1184 | persp(-31:31/64, -17:17/36, per3, phi=30, theta=30, expand=.6, ticktype="detailed", xlab="cycles/row", 1185 | ylab="cycles/column", zlab="Periodogram Ordinate") 1186 | ``` 1187 | 1188 | [top](#table-of-contents) 1189 | 1190 | --- 1191 | 1192 | ## Chapter 5 1193 | 1194 | 1195 | Example 5.1 1196 | 1197 | ```r 1198 | # NOTE: The example in the text uses the package 'fracdiff', 1199 | # which is a dinosaur and gave questionable results - 1200 | # this uses 'arfima' but it didn't make it into the text. 1201 | library(arfima) 1202 | summary(varve.fd <- arfima(log(varve))) # d.hat = 0.3728, se(d,hat) = 0.0273 1203 | # residual stuff 1204 | innov = resid(varve.fd) 1205 | par(mfrow=2:1) 1206 | tsplot(innov[[1]]) 1207 | acf1(innov[[1]]) 1208 | 1209 | # plot pi wgts 1210 | dev.new() 1211 | p = rep(1,31) 1212 | for (k in 1:30){ p[k+1] = (k-coef(varve.fd)[1])*p[k]/(k+1) } 1213 | tsplot(p[-1], ylab=expression(pi[j](d)), xlab="Index (j)", type="h", lwd=4, col=2:7, nxm=5) 1214 | ``` 1215 | 1216 | 1217 | Example 5.2 1218 | ```r 1219 | series = log(varve) # specify series to be analyzed 1220 | d0 = .1 # initial value of d 1221 | n.per = nextn(length(series)) 1222 | m = (n.per)/2 - 1 1223 | per = abs(fft(series-mean(series))[-1])^2 # remove 0 freq 1224 | per = per/n.per # R doesn't scale fft by sqrt(n) 1225 | g = 4*(sin(pi*((1:m)/n.per))^2) 1226 | 1227 | # Function to calculate -log.likelihood 1228 | whit.like = function(d){ 1229 | g.d=g^d 1230 | sig2 = (sum(g.d*per[1:m])/m) 1231 | log.like = m*log(sig2) - d*sum(log(g)) + m 1232 | return(log.like) 1233 | } 1234 | 1235 | # Estimation (?optim for details - output not shown) 1236 | (est = optim(d0, whit.like, gr=NULL, method="L-BFGS-B", 1237 | hessian=TRUE, lower=-.5, upper=.5, control=list(trace=1,REPORT=1))) 1238 | 1239 | # Results [d.hat = .380, se(dhat) = .028] 1240 | cat("d.hat =", est$par, "se(dhat) = ",1/sqrt(est$hessian),"\n") 1241 | g.dhat = g^est$par 1242 | sig2 = sum(g.dhat*per[1:m])/m 1243 | cat("sig2hat =",sig2,"\n") # sig2hat = .229 1244 | 1245 | # compart AR spectrum to long memory spectrum 1246 | u = spec.ic(log(varve), log='y', lty=2, xlim=c(0,.25), ylim=c(.2,20), col=4) 1247 | g = 4*(sin(pi*((1:500)/2000))^2) 1248 | fhat = sig2*g^{-est$par} # long memory spectral estimate 1249 | lines(1:500/2000, fhat, col=6) 1250 | ar.mle(log(varve)) # to get AR(8) estimates 1251 | 1252 | # 'fracdiff' has a GPH method, but I don't trust the pacakge 1253 | # library(fracdiff) 1254 | # fdGPH(log(varve), bandw=.9) # m = n^bandw- it's supposed to be small- this is way too big 1255 | ``` 1256 | 1257 | 1258 | Example 5.3 1259 | ```r 1260 | library(tseries) 1261 | adf.test(log(varve), k=0) # DF test 1262 | adf.test(log(varve)) # ADF test 1263 | pp.test(log(varve)) # PP test 1264 | ``` 1265 | 1266 | Example 5.4 1267 | ```r 1268 | gnpgr = diff(log(gnp)) # get the returns 1269 | u = sarima(gnpgr, 1, 0, 0) # fit an AR(1) 1270 | acf2(resid(u$fit), 20) # get (p)acf of the squared residuals 1271 | 1272 | library(fGarch) 1273 | summary(garchFit(~arma(1,0)+garch(1,0), gnpgr)) 1274 | ``` 1275 | 1276 | 1277 | 1278 | Example 5.5 and 5.6 1279 | ```r 1280 | library(xts) # needed to handle djia 1281 | djiar = diff(log(djia$Close))[-1] 1282 | acf2(djiar) # exhibits some autocorrelation (not shown) 1283 | acf2(djiar^2) # oozes autocorrelation (not shown) 1284 | library(fGarch) 1285 | # GARCH fit 1286 | summary(djia.g <- garchFit(~arma(1,0)+garch(1,1), data=djiar, cond.dist='std')) 1287 | plot(djia.g) # to see all plot options 1288 | # APARCH fit 1289 | summary(djia.ap <- garchFit(~arma(1,0)+aparch(1,1), data=djiar, cond.dist='std')) 1290 | plot(djia.ap) 1291 | ``` 1292 | 1293 | Example 5.7 1294 | ```r 1295 | tsplot(flu, type="c") 1296 | Months = c("J","F","M","A","M","J","J","A","S","O","N","D") 1297 | points(flu, pch=Months, cex=.8, font=2) 1298 | # Start analysis 1299 | dflu = diff(flu) 1300 | dev.new() 1301 | lag1.plot(dflu, corr=FALSE) # scatterplot with lowess fit 1302 | thrsh = .05 # threshold 1303 | Z = ts.intersect(dflu, lag(dflu,-1), lag(dflu,-2), lag(dflu,-3), 1304 | lag(dflu,-4) ) 1305 | ind1 = ifelse(Z[,2] < thrsh, 1, NA) # indicator < thrsh 1306 | ind2 = ifelse(Z[,2] < thrsh, NA, 1) # indicator >= thrsh 1307 | X1 = Z[,1]*ind1 1308 | X2 = Z[,1]*ind2 1309 | summary(fit1 <- lm(X1~ Z[,2:5]) ) # case 1 1310 | summary(fit2 <- lm(X2~ Z[,2:5]) ) # case 2 1311 | D = cbind(rep(1, nrow(Z)), Z[,2:5]) # design matrix 1312 | p1 = D %*% coef(fit1) # get predictions 1313 | p2 = D %*% coef(fit2) 1314 | prd = ifelse(Z[,2] < thrsh, p1, p2) 1315 | dev.new() 1316 | tsplot(dflu, ylim=c(-.5,.5), type='p', pch=3) 1317 | lines(prd) 1318 | prde1 = sqrt(sum(resid(fit1)^2)/df.residual(fit1) ) 1319 | prde2 = sqrt(sum(resid(fit2)^2)/df.residual(fit2) ) 1320 | prde = ifelse(Z[,2] < thrsh, prde1, prde2) 1321 | tx = time(dflu)[-(1:4)] 1322 | xx = c(tx, rev(tx)) 1323 | yy = c(prd-2*prde, rev(prd+2*prde)) 1324 | polygon(xx, yy, border=8, col=gray(.6, alpha=.25) ) 1325 | abline(h=.05, col=4, lty=6) 1326 | 1327 | # Using tsDyn (not in text) 1328 | library(tsDyn) 1329 | # vignette("tsDyn") # for package details (it's quirky, so you'll need this) 1330 | dflu = diff(flu) 1331 | (u = setar(dflu, m=4, thDelay=0)) # fit model and view results (thDelay=0 is lag 1 delay) 1332 | BIC(u); AIC(u) # if you want to try other models ... m=3 works well too 1333 | plot(u) # graphics - ?plot.setar for information 1334 | ``` 1335 | 1336 | Example 5.8 and 5.9 1337 | ```r 1338 | soi.d = resid(lm(soi~time(soi), na.action=NULL)) # detrended SOI 1339 | acf2(soi.d) 1340 | fit = arima(soi.d, order=c(1,0,0)) 1341 | ar1 = as.numeric(coef(fit)[1]) # = 0.5875 1342 | soi.pw = resid(fit) 1343 | rec.fil = filter(rec, filter=c(1, -ar1), sides=1) 1344 | dev.new() 1345 | ccf2(soi.pw, rec.fil) 1346 | 1347 | fish = ts.intersect(rec, RL1=lag(rec,-1), SL5=lag(soi.d,-5)) 1348 | (u = lm(fish[,1]~fish[,2:3], na.action=NULL)) 1349 | dev.new() 1350 | acf2(resid(u)) # suggests ar1 1351 | (arx = sarima(fish[,1], 1, 0, 0, xreg=fish[,2:3])) # final model 1352 | pred = rec + resid(arx$fit) # 1-step-ahead predictions 1353 | dev.new() 1354 | tsplot(pred, col=astsa.col(8,.3), lwd=7, ylab='rec & prediction') 1355 | lines(rec) 1356 | ``` 1357 | 1358 | Example 5.10 and 5.11 1359 | ```r 1360 | library(vars) 1361 | x = cbind(cmort, tempr, part) 1362 | summary(VAR(x, p=1, type="both")) # "both" fits constant + trend 1363 | 1364 | VARselect(x, lag.max=10, type="both") 1365 | summary(fit <- VAR(x, p=2, type="both")) 1366 | acf(resid(fit), 52) 1367 | serial.test(fit, lags.pt=12, type="PT.adjusted") 1368 | 1369 | (fit.pr = predict(fit, n.ahead = 24, ci = 0.95)) # 4 weeks ahead 1370 | dev.new() 1371 | fanchart(fit.pr) # plot prediction + error 1372 | ``` 1373 | 1374 | Example 5.12 1375 | ```r 1376 | library(marima) 1377 | model = define.model(kvar=3, ar=c(1,2), ma=c(1)) 1378 | arp = model$ar.pattern 1379 | map = model$ma.pattern 1380 | cmort.d = resid(detr <- lm(cmort~ time(cmort), na.action=NULL)) 1381 | xdata = matrix(cbind(cmort.d, tempr, part), ncol=3) # strip ts attributes 1382 | fit = marima(xdata, ar.pattern=arp, ma.pattern=map, means=c(0,1,1), penalty=1) 1383 | # resid analysis (not displayed) 1384 | innov = t(resid(fit)) 1385 | tsplot(innov) 1386 | acfm(innov) # since astsa v1.13.2 1387 | # acf(innov, na.action = na.pass) # or use this 1388 | 1389 | # fitted values for cmort 1390 | pred = ts(t(fitted(fit))[,1], start=start(cmort), freq=frequency(cmort)) + 1391 | detr$coef[1] + detr$coef[2]*time(cmort) 1392 | plot(pred, ylab="Cardiovascular Mortality", lwd=2, col=4) 1393 | points(cmort) 1394 | # print estimates and corresponding t^2-statistic 1395 | short.form(fit$ar.estimates, leading=FALSE) 1396 | short.form(fit$ar.fvalues, leading=FALSE) 1397 | short.form(fit$ma.estimates, leading=FALSE) 1398 | short.form(fit$ma.fvalues, leading=FALSE) 1399 | fit$resid.cov # estimate of noise cov matrix 1400 | ``` 1401 | 1402 | [top](#table-of-contents) 1403 | 1404 | --- 1405 | 1406 | ## Chapter 6 1407 | 1408 | > __Warning__ The code here uses the updated scripts in `astsa` _version 2.0._ Details of the updates are in the help files of `Kfilter`, `Ksmooth`, and `EM`. Original code (prior to version 2.0) may be found here: [Original Chapter 6 Info and Code](https://github.com/nickpoison/tsa4/blob/master/chap6.md) 1409 | 1410 | 1411 | 1412 | 1413 | Example 6.1 1414 | ```r 1415 | tsplot(blood, type='o', col=c(6,4,2), lwd=2, pch=19, cex=1) 1416 | ``` 1417 | 1418 | Example 6.2 1419 | ```r 1420 | tsplot(cbind(gtemp_land, gtemp_ocean), spaghetti=TRUE, lwd=2, pch=20, type="o", 1421 | col=astsa.col(c(4,2),.5), ylab="Temperature Deviations", main="Global Warming") 1422 | legend("topleft", legend=c("Land Surface", "Sea Surface"), lty=1, pch=20, col=c(4,2), bg="white") 1423 | ``` 1424 | 1425 | Example 6.5 1426 | ```r 1427 | # generate data 1428 | set.seed(1) 1429 | num = 50 1430 | w = rnorm(num+1,0,1) 1431 | v = rnorm(num,0,1) 1432 | mu = cumsum(w) # states: mu[0], mu[1], . . ., mu[50] 1433 | y = mu[-1] + v # obs: y[1], . . ., y[50] 1434 | 1435 | # filter and smooth (Ksmooth does both) 1436 | mu0 = 0; sigma0 = 1; phi = 1; sQ = 1; sR = 1 1437 | ks = Ksmooth(y, A=1, mu0, sigma0, phi, sQ, sR) 1438 | 1439 | # pictures 1440 | par(mfrow=c(3,1)) 1441 | 1442 | tsplot(mu[-1], type='p', col=4, pch=19, ylab=expression(mu[~t]), main="Prediction", ylim=c(-5,10)) 1443 | lines(ks$Xp, col=6) 1444 | lines(ks$Xp+2*sqrt(ks$Pp), lty=6, col=6) 1445 | lines(ks$Xp-2*sqrt(ks$Pp), lty=6, col=6) 1446 | 1447 | tsplot(mu[-1], type='p', col=4, pch=19, ylab=expression(mu[~t]), main="Filter", ylim=c(-5,10)) 1448 | lines(ks$Xf, col=6) 1449 | lines(ks$Xf+2*sqrt(ks$Pf), lty=6, col=6) 1450 | lines(ks$Xf-2*sqrt(ks$Pf), lty=6, col=6) 1451 | 1452 | tsplot(mu[-1], type='p', col=4, pch=19, ylab=expression(mu[~t]), main="Smoother", ylim=c(-5,10)) 1453 | lines(ks$Xs, col=6) 1454 | lines(ks$Xs+2*sqrt(ks$Ps), lty=6, col=6) 1455 | lines(ks$Xs-2*sqrt(ks$Ps), lty=6, col=6) 1456 | 1457 | mu[1]; ks$X0n; sqrt(ks$P0n) # initial value info 1458 | ``` 1459 | 1460 | 1461 | Example 6.6 1462 | ```r 1463 | # Generate Data 1464 | set.seed(999) 1465 | num = 100 1466 | N = num+1 1467 | x = sarima.sim(n=N, ar=.8) 1468 | y = ts(x[-1] + rnorm(num,0,1)) 1469 | 1470 | # Initial Estimates 1471 | u = ts.intersect(y, lag(y,-1), lag(y,-2)) 1472 | varu = var(u) 1473 | coru = cor(u) 1474 | phi = coru[1,3]/coru[1,2] 1475 | q = (1-phi^2)*varu[1,2]/phi 1476 | r = varu[1,1] - q/(1-phi^2) 1477 | (init.par = c(phi, sqrt(q), sqrt(r))) 1478 | 1479 | # Function to evaluate the likelihood 1480 | Linn=function(para){ 1481 | phi = para[1]; sigw = para[2]; sigv = para[3] 1482 | Sigma0 = (sigw^2)/(1-phi^2); Sigma0[Sigma0<0]=0 1483 | kf = Kfilter(y,A=1,mu0=0,Sigma0,phi,sigw,sigv) 1484 | return(kf$like) 1485 | } 1486 | 1487 | # Estimation 1488 | (est = optim(init.par, Linn, gr=NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 1489 | SE = sqrt(diag(solve(est$hessian))) 1490 | cbind(estimate=c(phi=est$par[1],sigw=est$par[2],sigv=est$par[3]), SE) 1491 | ``` 1492 | 1493 | 1494 | 1495 | Example 6.7 1496 | ```r 1497 | ##- slight change from text, the data scaled -## 1498 | ##- you can remove the scales to get to the original analysis -## 1499 | 1500 | ##- ALSO note that regression parameters not used are set to NULL (the default) instead of 0 now. 1501 | 1502 | # Setup 1503 | y = cbind(globtemp/sd(globtemp), globtempl/sd(globtempl)) 1504 | num = nrow(y) 1505 | input = rep(1,num) 1506 | A = matrix(c(1,1), nrow=2) 1507 | mu0 = -.35; Sigma0 = 1; Phi = 1 1508 | 1509 | # Function to Calculate Likelihood 1510 | Linn=function(para){ 1511 | sQ = para[1] # sigma_w 1512 | sR1 = para[2] # 11 element of sR 1513 | sR2 = para[3] # 22 element of sR 1514 | sR21 = para[4] # 21 element of sR 1515 | sR = matrix(c(sR1,sR21,0,sR2), 2) # put the matrix together 1516 | drift = para[5] 1517 | kf = Kfilter(y,A,mu0,Sigma0,Phi,sQ,sR,Ups=drift,Gam=NULL,input) # NOTE Gamma is set to NULL now (instead of 0) 1518 | return(kf$like) 1519 | } 1520 | 1521 | # Estimation 1522 | init.par = c(.1,.1,.1,0,.05) # initial values of parameters 1523 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 1524 | SE = sqrt(diag(solve(est$hessian))) 1525 | 1526 | # Summary of estimation 1527 | estimate = est$par; u = cbind(estimate, SE) 1528 | rownames(u)=c("sigw","sR11", "sR22", "sR21", "drift"); u 1529 | 1530 | # Smooth (first set parameters to their final estimates) 1531 | sQ = est$par[1] 1532 | sR1 = est$par[2] 1533 | sR2 = est$par[3] 1534 | sR21 = est$par[4] 1535 | sR = matrix(c(sR1,sR21,0,sR2), 2) 1536 | (R = sR%*%t(sR)) # to view the estimated R matrix 1537 | drift = est$par[5] 1538 | ks = Ksmooth(y,A,mu0,Sigma0,Phi,sQ,sR,Ups=drift,Gam=NULL,input) # NOTE Gamma is set to NULL now (instead of 0) 1539 | 1540 | # Plot 1541 | tsplot(y, spag=TRUE, margins=.5, type='o', pch=2:3, col=4:3, lty=6, ylab='Temperature Deviations') 1542 | xsm = ts(as.vector(ks$Xs), start=1880) 1543 | rmse = ts(sqrt(as.vector(ks$Ps)), start=1880) 1544 | lines(xsm, lwd=2, col=6) 1545 | xx = c(time(xsm), rev(time(xsm))) 1546 | yy = c(xsm-2*rmse, rev(xsm+2*rmse)) 1547 | polygon(xx, yy, border=NA, col=gray(.6, alpha=.25)) 1548 | ``` 1549 | 1550 | 1551 | Example 6.8 1552 | 1553 | 1554 | ```r 1555 | library(nlme) # loads package nlme (comes with R) 1556 | 1557 | # Generate data (same as Example 6.6) 1558 | set.seed(999); num = 100; N = num+1 1559 | x = sarima.sim(ar=.8, n=N) 1560 | y = ts(x[-1] + rnorm(num,0,1)) 1561 | 1562 | # Initial Estimates 1563 | u = ts.intersect(y,lag(y,-1),lag(y,-2)) 1564 | varu = var(u); coru = cor(u) 1565 | phi = coru[1,3]/coru[1,2] 1566 | q = (1-phi^2)*varu[1,2]/phi 1567 | r = varu[1,1] - q/(1-phi^2) 1568 | mu0 = 0; Sigma0 = 2.8 1569 | ( em = EM(y, 1, mu0, Sigma0, phi, q, r) ) 1570 | 1571 | # Standard Errors (this uses nlme) 1572 | phi = em$Phi; sq = sqrt(em$Q); sr = sqrt(em$R) 1573 | mu0 = em$mu0; Sigma0 = em$Sigma0 1574 | para = c(phi, sq, sr) 1575 | # evaluate likelihood at estimates 1576 | Linn=function(para){ 1577 | kf = Kfilter(y, A=1, mu0, Sigma0, para[1], para[2], para[3]) 1578 | return(kf$like) 1579 | } 1580 | emhess = fdHess(para, function(para) Linn(para)) 1581 | SE = sqrt(diag(solve(emhess$Hessian))) 1582 | 1583 | # Display summary of estimation 1584 | estimate = c(para, em$mu0, em$Sigma0); SE = c(SE,NA,NA) 1585 | u = cbind(estimate, SE) 1586 | rownames(u) = c("phi","sigw","sigv","mu0","Sigma0") 1587 | u 1588 | ``` 1589 | 1590 | 1591 | Example 6.9 1592 | 1593 | 1594 | ```r 1595 | y = blood 1596 | num = nrow(y) 1597 | A = array(0, dim=c(3,3,num)) 1598 | for(k in 1:num) if (!is.na(y[k,1])) A[,,k]= diag(1,3) 1599 | 1600 | # Initial values 1601 | mu0 = matrix(0,3,1) 1602 | Sigma0 = diag(c(.1,.1,1) ,3) 1603 | Phi = diag(1,3) 1604 | Q = diag(c(.1,.1,1), 3) 1605 | R = diag(c(.1,.1,1), 3) 1606 | ( em = EM(y, A, mu0, Sigma0, Phi, Q, R) ) 1607 | 1608 | # Graph smoother 1609 | sQ = em$Q %^% .5 1610 | sR = sqrt(em$R) 1611 | ks = Ksmooth(y, A, em$mu0, em$Sigma0, em$Phi, sQ , sR) 1612 | y1s = ks$Xs[1,,] 1613 | y2s = ks$Xs[2,,] 1614 | y3s = ks$Xs[3,,] 1615 | p1 = 2*sqrt(ks$Ps[1,1,]) 1616 | p2 = 2*sqrt(ks$Ps[2,2,]) 1617 | p3 = 2*sqrt(ks$Ps[3,3,]) 1618 | 1619 | par(mfrow=c(3,1)) 1620 | tsplot(WBC, type='p', pch=19, ylim=c(1,5), col=6, lwd=2, cex=1) 1621 | lines(y1s) 1622 | xx = c(time(WBC), rev(time(WBC))) # same for all 1623 | yy = c(y1s-p1, rev(y1s+p1)) 1624 | polygon(xx, yy, border=8, col=astsa.col(8, alpha = .1)) 1625 | 1626 | tsplot(PLT, type='p', ylim=c(3,6), pch=19, col=4, lwd=2, cex=1) 1627 | lines(y2s) 1628 | yy = c(y2s-p2, rev(y2s+p2)) 1629 | polygon(xx, yy, border=8, col=astsa.col(8, alpha = .1)) 1630 | 1631 | tsplot(HCT, type='p', pch=19, ylim=c(20,40), col=2, lwd=2, cex=1) 1632 | lines(y3s) 1633 | yy = c(y3s-p3, rev(y3s+p3)) 1634 | polygon(xx, yy, border=8, col=astsa.col(8, alpha = .1)) 1635 | ``` 1636 | 1637 | 1638 | 1639 | Example 6.10 1640 | ```r 1641 | num = length(jj) 1642 | A = cbind(1,1,0,0) 1643 | 1644 | # Function to Calculate Likelihood 1645 | Linn = function(para){ 1646 | Phi = diag(0,4) 1647 | Phi[1,1] = para[1] 1648 | Phi[2,]=c(0,-1,-1,-1); Phi[3,]=c(0,1,0,0); Phi[4,]=c(0,0,1,0) 1649 | sQ1 = para[2]; sQ2 = para[3] # sqrt q11 and sqrt q22 1650 | sQ = diag(0,4); sQ[1,1]=sQ1; sQ[2,2]=sQ2 1651 | sR = para[4] # sqrt r11 1652 | kf = Kfilter(jj, A, mu0, Sigma0, Phi, sQ, sR) 1653 | return(kf$like) 1654 | } 1655 | 1656 | # Initial Parameters 1657 | mu0 = c(.7,0,0,0) 1658 | Sigma0 = diag(.04, 4) 1659 | init.par = c(1.03, .1, .1, .5) # Phi[1,1], the 2 Qs and R 1660 | 1661 | # Estimation 1662 | est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1)) 1663 | SE = sqrt(diag(solve(est$hessian))) 1664 | u = cbind(estimate=est$par,SE) 1665 | rownames(u)=c("Phi11","sigw1","sigw2","sigv"); u 1666 | 1667 | # Smooth 1668 | Phi = diag(0,4) 1669 | Phi[1,1] = est$par[1]; Phi[2,] = c(0,-1,-1,-1) 1670 | Phi[3,] = c(0,1,0,0); Phi[4,] = c(0,0,1,0) 1671 | sQ = diag(0,4) 1672 | sQ[1,1] = est$par[2] 1673 | sQ[2,2] = est$par[3] 1674 | sR = est$par[4] 1675 | ks = Ksmooth(jj, A, mu0, Sigma0, Phi, sQ, sR) 1676 | 1677 | # Plots 1678 | Tsm = ts(ks$Xs[1,,], start=1960, freq=4) 1679 | Ssm = ts(ks$Xs[2,,], start=1960, freq=4) 1680 | p1 = 3*sqrt(ks$Ps[1,1,]); p2 = 3*sqrt(ks$Ps[2,2,]) 1681 | par(mfrow=c(2,1)) 1682 | tsplot(Tsm, main='Trend Component', ylab='Trend') 1683 | xx = c(time(jj), rev(time(jj))) 1684 | yy = c(Tsm-p1, rev(Tsm+p1)) 1685 | polygon(xx, yy, border=NA, col=gray(.5, alpha = .3)) 1686 | tsplot(jj, main='Data & Trend+Season', ylab='J&J QE/Share', ylim=c(-.5,17)) 1687 | xx = c(time(jj), rev(time(jj)) ) 1688 | yy = c((Tsm+Ssm)-(p1+p2), rev((Tsm+Ssm)+(p1+p2)) ) 1689 | polygon(xx, yy, border=NA, col=gray(.5, alpha = .3)) 1690 | 1691 | # Forecast 1692 | dev.new() 1693 | n.ahead = 12 1694 | y = ts(append(jj, rep(0,n.ahead)), start=1960, freq=4) 1695 | rmspe = rep(0,n.ahead) 1696 | x00 = ks$Xf[,,num] 1697 | P00 = ks$Pf[,,num] 1698 | Q = sQ%*%t(sQ) 1699 | R = sR%*%t(sR) 1700 | for (m in 1:n.ahead){ 1701 | xp = Phi%*%x00 1702 | Pp = Phi%*%P00%*%t(Phi)+Q 1703 | sig = A%*%Pp%*%t(A)+R 1704 | K = Pp%*%t(A)%*%(1/sig) 1705 | x00 = xp 1706 | P00 = Pp-K%*%A%*%Pp 1707 | y[num+m] = A%*%xp 1708 | rmspe[m] = sqrt(sig) 1709 | } 1710 | tsplot(y, type='o', main='', ylab='J&J QE/Share', ylim=c(5,30), xlim = c(1975,1984)) 1711 | upp = ts(y[(num+1):(num+n.ahead)]+2*rmspe, start=1981, freq=4) 1712 | low = ts(y[(num+1):(num+n.ahead)]-2*rmspe, start=1981, freq=4) 1713 | xx = c(time(low), rev(time(upp))) 1714 | yy = c(low, rev(upp)) 1715 | polygon(xx, yy, border=8, col=gray(.5, alpha = .3)) 1716 | abline(v=1981, lty=3) 1717 | ``` 1718 | 1719 | 1720 | Example 6.12 1721 | ```r 1722 | # Preliminary analysis 1723 | fit1 = sarima(cmort, 2,0,0, xreg=time(cmort)) 1724 | acf(cbind(dmort <- resid(fit1$fit), tempr, part)) 1725 | lag2.plot(tempr, dmort, 8) 1726 | lag2.plot(part, dmort, 8) 1727 | 1728 | # quick and dirty fit (detrend then fit ARMAX) 1729 | trend = time(cmort) - mean(time(cmort)) 1730 | dcmort = resid(fit2 <- lm(cmort~trend, na.action=NULL)) # detrended mort 1731 | u = ts.intersect(dM=dcmort, dM1=lag(dcmort,-1), dM2=lag(dcmort,-2), T1=lag(tempr,-1), P=part, P4=lag(part,-4)) 1732 | sarima(u[,1], 0,0,0, xreg=u[,2:6]) # ARMAX fit with residual analysis 1733 | 1734 | ################################################# 1735 | ## All estimates at once ## 1736 | ################################################# 1737 | trend = time(cmort) - mean(time(cmort)) # center time 1738 | const = time(cmort)/time(cmort) # appropriate time series of 1s 1739 | ded = ts.intersect(M=cmort, T1=lag(tempr,-1), P=part, P4=lag(part,-4), trend, const) 1740 | y = ded[,1] 1741 | input = ded[,2:6] 1742 | num = length(y) 1743 | A = matrix(c(1,0), 1, 2) 1744 | 1745 | # Function to Calculate Likelihood 1746 | Linn=function(para){ 1747 | phi1 = para[1]; phi2 = para[2]; sR = para[3]; b1 = para[4] 1748 | b2 = para[5]; b3 = para[6]; b4 = para[7]; alf = para[8] 1749 | mu0 = matrix(c(0,0), 2, 1) 1750 | Sigma0 = diag(100, 2) 1751 | Phi = matrix(c(phi1, phi2, 1, 0), 2) 1752 | S = 1 1753 | Ups = matrix(c(b1, 0, b2, 0, b3, 0, 0, 0, 0, 0), 2, 5) 1754 | Gam = matrix(c(0, 0, 0, b4, alf), 1, 5) 1755 | sQ = matrix(c(phi1, phi2), 2)*sR 1756 | # S = sR^2 1757 | kf = Kfilter(y, A, mu0, Sigma0, Phi, sQ, sR, Ups=Ups, Gam=Gam, input=input, S=S, version=2) 1758 | return(kf$like) 1759 | } 1760 | 1761 | # Estimation - prelim analysis gives good starting values 1762 | init.par = c(phi1=.3, phi2=.3, sR=4, b1=-.1, b2=.1, b3=.04, b4=-1.3, alf=mean(cmort)) 1763 | L = c( 0, 0, 1, -1, 0, 0, -2, 70) # lower bound on parameters 1764 | U = c(.5, .5, 10, 0, .5, .5, 0, 90) # upper bound - used in optim 1765 | est = optim(init.par, Linn, NULL, method='L-BFGS-B', lower=L, upper=U, 1766 | hessian=TRUE, control=list(trace=1, REPORT=1, factr=10^8)) 1767 | SE = sqrt(diag(solve(est$hessian))) 1768 | round(cbind(estimate=est$par, SE), 3) # results 1769 | ################################################# 1770 | 1771 | # Residual Analysis (not shown) 1772 | phi1 = est$par[1]; phi2 = est$par[2] 1773 | sR = est$par[3]; b1 = est$par[4] 1774 | b2 = est$par[5]; b3 = est$par[6] 1775 | b4 = est$par[7]; alf = est$par[8] 1776 | mu0 = matrix(c(0,0), 2, 1) 1777 | Sigma0 = diag(100, 2) 1778 | Phi = matrix(c(phi1, phi2, 1, 0), 2) 1779 | S = 1 1780 | Ups = matrix(c(b1, 0, b2, 0, b3, 0, 0, 0, 0, 0), 2, 5) 1781 | Gam = matrix(c(0, 0, 0, b4, alf), 1, 5) 1782 | sQ = matrix(c(phi1, phi2), 2)*sR 1783 | kf = Kfilter(y, A, mu0, Sigma0, Phi, sQ, sR, Ups=Ups, Gam=Gam, input=input, S=S, version=2) 1784 | res = ts(drop(kf$innov), start=start(cmort), freq=frequency(cmort)) 1785 | sarima(res, 0,0,0, no.constant=TRUE) # gives a full residual analysis 1786 | 1787 | # Similar fit with but with trend in the X of ARMAX 1788 | trend = time(cmort) - mean(time(cmort)) 1789 | u = ts.intersect(M=cmort, M1=lag(cmort,-1), M2=lag(cmort,-2), T1=lag(tempr,-1), 1790 | P=part, P4=lag(part -4), trend) 1791 | sarima(u[,1], 0,0,0, xreg=u[,2:7]) 1792 | ``` 1793 | 1794 | 1795 | 1796 | Example 6.13 1797 | ```r 1798 | ################################## 1799 | # NOTE: If this takes a long time on your machine, 1800 | # increase `tol` and/or decrease `nboot` 1801 | tol = .0001 # determines convergence of optimizer 1802 | nboot = 500 # number of bootstrap replicates 1803 | ################################## 1804 | 1805 | y = window(qinfl, c(1953,1), c(1965,2)) # inflation 1806 | z = window(qintr, c(1953,1), c(1965,2)) # interest 1807 | num = length(y) 1808 | A = array(z, dim=c(1,1,num)) 1809 | input = matrix(1,num,1) 1810 | 1811 | # Function to Calculate Likelihood 1812 | Linn = function(para, y.data){ # pass data also 1813 | phi = para[1]; alpha = para[2] 1814 | b = para[3]; Ups = (1-phi)*b 1815 | sQ = para[4]; sR = para[5] 1816 | kf = Kfilter(y.data,A,mu0,Sigma0,phi,sQ ,sR ,Ups ,Gam=alpha,input) 1817 | return(kf$like) 1818 | } 1819 | 1820 | # Parameter Estimation 1821 | mu0 = 1 1822 | Sigma0 = .01 1823 | init.par = c(phi=.84, alpha=-.77, b=.85, sQ=.12, sR=1.1) # initial values 1824 | 1825 | est = optim(init.par, Linn, NULL, y.data=y, method="BFGS", hessian=TRUE, 1826 | control=list(trace=1, REPORT=1, reltol=tol)) 1827 | SE = sqrt(diag(solve(est$hessian))) 1828 | 1829 | phi = est$par[1]; alpha = est$par[2] 1830 | b = est$par[3]; Ups = (1-phi)*b 1831 | sQ = est$par[4]; sR = est$par[5] 1832 | round(cbind(estimate=est$par, SE), 3) 1833 | 1834 | 1835 | # BEGIN BOOTSTRAP 1836 | # Run the filter at the estimates 1837 | kf = Kfilter(y, A, mu0, Sigma0, phi, sQ, sR, Ups, Gam=alpha, input) 1838 | 1839 | # Pull out necessary values from the filter and initialize 1840 | xp = kf$Xp 1841 | Pp = kf$Pp 1842 | innov = kf$innov 1843 | sig = kf$sig 1844 | e = innov/sqrt(sig) 1845 | e.star = e # initialize values 1846 | y.star = y 1847 | xp.star = xp 1848 | k = 4:50 # hold first 3 observations fixed 1849 | para.star = matrix(0, nboot, 5) # to store estimates 1850 | init.par = c(.84, -.77, .85, .12, 1.1) 1851 | 1852 | pb = txtProgressBar(min = 0, max = nboot, initial = 0, style=3) # progress bar 1853 | 1854 | for (i in 1:nboot){ 1855 | setTxtProgressBar(pb,i) 1856 | e.star[k] = sample(e[k], replace=TRUE) 1857 | for (j in k){ 1858 | K = (phi*Pp[j-1]*z[j-1])/sig[j-1] 1859 | xp.star[j] = phi*xp.star[j-1] + Ups + K*sqrt(sig[j-1])*e.star[j-1] 1860 | } 1861 | y.star[k] = z[k]*xp.star[k] + alpha + sqrt(sig[k])*e.star[k] 1862 | est.star = optim(init.par, Linn, NULL, y.data=y.star, method='BFGS', control=list(reltol=tol)) 1863 | para.star[i,] = cbind(est.star$par[1], est.star$par[2], est.star$par[3], 1864 | abs(est.star$par[4]), abs(est.star$par[5])) 1865 | } 1866 | close(pb) 1867 | 1868 | # Some summary statistics 1869 | rmse = rep(NA,5) # SEs from the bootstrap 1870 | for(i in 1:5){rmse[i]=sqrt(sum((para.star[,i]-est$par[i])^2)/nboot) 1871 | cat(i, rmse[i],"\n") 1872 | } 1873 | # Plot phi and sigw (scatter.hist in astsa v1.13) 1874 | phi = para.star[,1] 1875 | sigw = abs(para.star[,4]) 1876 | scatter.hist(sigw, phi, ylab=expression(phi), xlab=expression(sigma[~w]), 1877 | hist.col=astsa.col(5,.4), pt.col=5, pt.size=1.5) 1878 | ``` 1879 | 1880 | 1881 | Example 6.14 1882 | 1883 | ```r 1884 | set.seed(123) 1885 | num = 50 1886 | w = rnorm(num,0,.1) 1887 | x = cumsum(cumsum(w)) 1888 | y = x + rnorm(num,0,1) 1889 | ## State Space ## 1890 | Phi = matrix(c(2,1,-1,0),2) 1891 | A = matrix(c(1,0),1) 1892 | mu0 = matrix(0,2); Sigma0 = diag(1,2) 1893 | Linn = function(para){ 1894 | sigw = para[1] 1895 | sigv = para[2] 1896 | sQ = diag(c(sigw,0)) 1897 | kf = Kfilter(y, A, mu0, Sigma0, Phi, sQ, sigv) 1898 | return(kf$like) 1899 | } 1900 | 1901 | ## Estimation ## 1902 | init.par = c(.1, 1) 1903 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 1904 | SE = sqrt(diag(solve(est$hessian))) 1905 | # Summary of estimation 1906 | estimate = est$par; u = cbind(estimate, SE) 1907 | rownames(u) = c("sigw","sigv"); u 1908 | 1909 | # Smooth 1910 | sigw = est$par[1] 1911 | sQ = diag(c(sigw,0)) 1912 | sigv = est$par[2] 1913 | ks = Ksmooth(y, A, mu0, Sigma0, Phi, sQ, sigv) 1914 | xsmoo = ts(ks$Xs[1,1,]) 1915 | psmoo = ts(ks$Ps[1,1,]) 1916 | upp = xsmoo + 2*sqrt(psmoo) 1917 | low = xsmoo - 2*sqrt(psmoo) 1918 | 1919 | 1920 | tsplot(x, ylab="", ylim=c(-1,8), col=1) 1921 | lines(y, type='o', col=8) 1922 | lines(xsmoo, col=4, lty=2, lwd=3) 1923 | lines(upp, col=4, lty=2); lines(low, col=4, lty=2) 1924 | lines(smooth.spline(y), lty=1, col=2) 1925 | legend("topleft", c("Observations","State"), pch=c(1,-1), lty=1, lwd=c(1,2), col=c(8,1)) 1926 | legend("bottomright", c("Smoother", "GCV Spline"), lty=c(2,1), lwd=c(3,1), col=c(4,2)) 1927 | ``` 1928 | 1929 | Example 6.16 1930 | 1931 | ```r 1932 | library(depmixS4) 1933 | model <- depmix(EQcount ~1, nstates=2, data=data.frame(EQcount), family=poisson('identity'), respstart=c(15,25)) 1934 | set.seed(90210) 1935 | summary(fm <- fit(model)) # estimation results 1936 | standardError(fm) # with standard errors 1937 | 1938 | ##-- A little nicer display of the parameters --## 1939 | para.mle = as.vector(getpars(fm))[3:8] 1940 | ( mtrans = matrix(para.mle[1:4], byrow=TRUE, nrow=2) ) 1941 | ( lams = para.mle[5:6] ) 1942 | ( pi1 = mtrans[2,1]/(2 - mtrans[1,1] - mtrans[2,2]) ) 1943 | ( pi2 = 1 - pi1 ) 1944 | 1945 | #-- Graphics --## 1946 | par(mfrow=c(3,1)) 1947 | # data and states 1948 | tsplot(EQcount, main="", ylab='EQcount', type='h', col=gray(.7), ylim=c(0,50)) 1949 | text(EQcount, col=6*posterior(fm)[,1]-2, labels=posterior(fm)[,1]) 1950 | # prob of state 2 1951 | tsplot(ts(posterior(fm)[,3], start=1900), ylab = expression(hat(pi)[~2]*'(t|n)')); abline(h=.5, lty=2) 1952 | # histogram 1953 | hist(EQcount, breaks=30, prob=TRUE, main="") 1954 | xvals = seq(1,45) 1955 | u1 = pi1*dpois(xvals, lams[1]) 1956 | u2 = pi2*dpois(xvals, lams[2]) 1957 | lines(xvals, u1, col=4) 1958 | lines(xvals, u2, col=2) 1959 | ``` 1960 | 1961 | Example 6.17 1962 | ```r 1963 | library(depmixS4) 1964 | y = ts(sp500w, start=2003, freq=52) # make data depmix friendly 1965 | mod3 <- depmix(y~1, nstates=3, data=data.frame(y)) 1966 | set.seed(2) 1967 | summary(fm3 <- fit(mod3)) # estimation results 1968 | 1969 | ##-- a little nicer display --## 1970 | para.mle = as.vector(getpars(fm3)[-(1:3)]) 1971 | permu = matrix(c(0,0,1,0,1,0,1,0,0), 3,3) # for the label switch 1972 | (mtrans.mle = permu%*%round(t(matrix(para.mle[1:9],3,3)),3)%*%permu) 1973 | (norms.mle = round(matrix(para.mle[10:15],2,3),3)%*%permu) 1974 | 1975 | ##-- Graphics --## 1976 | layout(matrix(c(1,2, 1,3), 2), heights=c(1,.75)) 1977 | 1978 | tsplot(y, main="", ylab='S&P500 Weekly Returns', col=gray(.7), ylim=c(-.11,.11)) 1979 | culer = 4-posterior(fm3)[,1]; culer[culer==3]=4 # switch labels 1 and 3 1980 | text(y, col=culer, labels=4-posterior(fm3)[,1]) 1981 | 1982 | acf1(y^2, 25) 1983 | 1984 | hist(y, 25, prob=TRUE, main='', col=astsa.col(8,.2)) 1985 | pi.hat = colSums(posterior(fm3)[-1,2:4])/length(y) 1986 | culer = c(1,2,4) 1987 | for (i in 1:3) { 1988 | mu = norms.mle[1,i]; sig = norms.mle[2,i] 1989 | x = seq(-.2,.15, by=.001) 1990 | lines(x, pi.hat[4-i]*dnorm(x, mean=mu, sd=sig), col=culer[i], lwd=2) 1991 | } 1992 | ``` 1993 | 1994 | Example 6.18 1995 | ```r 1996 | library(MSwM) 1997 | set.seed(90210) 1998 | dflu = diff(flu) 1999 | model = lm(dflu~ 1) 2000 | mod = msmFit(model, k=2, p=2, sw=rep(TRUE,4)) # 2 regimes, AR(2)s 2001 | summary(mod) 2002 | plotProb(mod, which=3) 2003 | ``` 2004 | 2005 | 2006 | 2007 | Example 6.22 2008 | ```r 2009 | y = flu 2010 | num = length(y) 2011 | nstate = 4 # state dimenstion 2012 | M1 = as.matrix(cbind(1,0,0,1)) # obs matrix normal 2013 | M2 = as.matrix(cbind(1,0,1,1)) # obs matrix flu epi 2014 | prob = matrix(0,num,1); yp = y # to store pi2(t|t-1) & y(t|t-1) 2015 | xfilter = array(0, dim=c(nstate,1,num)) # to store x(t|t) 2016 | # Function to Calculate Likelihood 2017 | Linn = function(para){ 2018 | alpha1 = para[1]; alpha2 = para[2]; beta0 = para[3] 2019 | sQ1 = para[4]; sQ2 = para[5]; like=0 2020 | xf = matrix(0, nstate, 1) # x filter 2021 | xp = matrix(0, nstate, 1) # x pred 2022 | Pf = diag(.1, nstate) # filter cov 2023 | Pp = diag(.1, nstate) # pred cov 2024 | pi11 <- .75 -> pi22; pi12 <- .25 -> pi21; pif1 <- .5 -> pif2 2025 | phi = matrix(0,nstate,nstate) 2026 | phi[1,1] = alpha1; phi[1,2] = alpha2; phi[2,1]=1; phi[4,4]=1 2027 | Ups = as.matrix(rbind(0,0,beta0,0)) 2028 | Q = matrix(0,nstate,nstate) 2029 | Q[1,1] = sQ1^2; Q[3,3] = sQ2^2; R=0 # R=0 in final model 2030 | # begin filtering # 2031 | for(i in 1:num){ 2032 | xp = phi%*%xf + Ups; Pp = phi%*%Pf%*%t(phi) + Q 2033 | sig1 = as.numeric(M1%*%Pp%*%t(M1) + R) 2034 | sig2 = as.numeric(M2%*%Pp%*%t(M2) + R) 2035 | k1 = Pp%*%t(M1)/sig1; k2 = Pp%*%t(M2)/sig2 2036 | e1 = y[i]-M1%*%xp; e2 = y[i]-M2%*%xp 2037 | pip1 = pif1*pi11 + pif2*pi21; pip2 = pif1*pi12 + pif2*pi22 2038 | den1 = (1/sqrt(sig1))*exp(-.5*e1^2/sig1) 2039 | den2 = (1/sqrt(sig2))*exp(-.5*e2^2/sig2) 2040 | denm = pip1*den1 + pip2*den2 2041 | pif1 = pip1*den1/denm; pif2 = pip2*den2/denm 2042 | pif1 = as.numeric(pif1); pif2 = as.numeric(pif2) 2043 | e1 = as.numeric(e1); e2=as.numeric(e2) 2044 | xf = xp + pif1*k1*e1 + pif2*k2*e2 2045 | eye = diag(1, nstate) 2046 | Pf = pif1*(eye-k1%*%M1)%*%Pp + pif2*(eye-k2%*%M2)%*%Pp 2047 | like = like - log(pip1*den1 + pip2*den2) 2048 | prob[i]<<-pip2; xfilter[,,i]<<-xf; innov.sig<<-c(sig1,sig2) 2049 | yp[i]<<-ifelse(pip1 > pip2, M1%*%xp, M2%*%xp) 2050 | } 2051 | return(like) 2052 | } 2053 | # Estimation 2054 | alpha1 = 1.4; alpha2 = -.5; beta0 = .3; sQ1 = .1; sQ2 = .1 2055 | init.par = c(alpha1, alpha2, beta0, sQ1, sQ2) 2056 | (est = optim(init.par, Linn, NULL, method='BFGS', hessian=TRUE, control=list(trace=1,REPORT=1))) 2057 | SE = sqrt(diag(solve(est$hessian))) 2058 | u = cbind(estimate=est$par, SE) 2059 | rownames(u)=c('alpha1','alpha2','beta0','sQ1','sQ2'); u 2060 | 2061 | # Graphics 2062 | predepi = ifelse(prob<.5,0,1) 2063 | FLU = window(flu, start=1968.4) 2064 | Time = window(time(flu), start=1968.4) 2065 | k = 6:num 2066 | par(mfrow=c(3,1)) 2067 | tsplot(FLU, col=8, ylab='flu') 2068 | text(FLU, col= predepi[k]+1, labels=predepi[k]+1, cex=1.1) 2069 | legend('topright', '(a)', bty='n') 2070 | 2071 | filters = ts(t(xfilter[c(1,3,4),,]), start=tsp(flu)[1], frequency=tsp(flu)[3]) 2072 | tsplot(window(filters, start=1968.4), spag=TRUE, col=2:4, ylab='filter') 2073 | legend('topright', '(b)', bty='n') 2074 | 2075 | tsplot(FLU, type='p', pch=19, ylab='flu', cex=1.2) 2076 | prde1 = 2*sqrt(innov.sig[1]); prde2 = 2*sqrt(innov.sig[2]) 2077 | prde = ifelse(predepi[k]<.5, prde1, prde2) 2078 | xx = c(Time, rev(Time)) 2079 | yy = c(yp[k]-prde, rev(yp[k]+prde)) 2080 | polygon(xx, yy, border=8, col=gray(.6, alpha=.3)) 2081 | legend('topright', '(c)', bty='n') 2082 | ``` 2083 | 2084 | 2085 | 2086 | 2087 | Example 6.23 2088 | ```r 2089 | y = log(nyse^2) 2090 | num = length(y) 2091 | 2092 | # Initial Parameters 2093 | phi0=0; phi1=.95; sQ=.2; alpha=mean(y); sR0=1; mu1=-3; sR1=2 2094 | init.par = c(phi0,phi1,sQ,alpha,sR0,mu1,sR1) 2095 | 2096 | # Innovations Likelihood 2097 | Linn = function(para){ 2098 | phi0=para[1]; phi1=para[2]; sQ=para[3]; alpha=para[4] 2099 | sR0=para[5]; mu1=para[6]; sR1=para[7] 2100 | sv = SVfilter(num,y,phi0,phi1,sQ,alpha,sR0,mu1,sR1) 2101 | return(sv$like) 2102 | } 2103 | 2104 | # Estimation 2105 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 2106 | SE = sqrt(diag(solve(est$hessian))) 2107 | u = cbind(estimates=est$par, SE) 2108 | rownames(u)=c("phi0","phi1","sQ","alpha","sigv0","mu1","sigv1"); u 2109 | 2110 | # Graphics (need filters at the estimated parameters) 2111 | phi0=est$par[1]; phi1=est$par[2]; sQ=est$par[3]; alpha=est$par[4] 2112 | sR0=est$par[5]; mu1=est$par[6]; sR1=est$par[7] 2113 | sv = SVfilter(num,y,phi0,phi1,sQ,alpha,sR0,mu1,sR1) 2114 | 2115 | # densities plot (f is chi-sq, fm is fitted mixture) 2116 | x = seq(-15,6,by=.01) 2117 | f = exp(-.5*(exp(x)-x))/(sqrt(2*pi)) 2118 | f0 = exp(-.5*(x^2)/sR0^2)/(sR0*sqrt(2*pi)) 2119 | f1 = exp(-.5*(x-mu1)^2/sR1^2)/(sR1*sqrt(2*pi)) 2120 | fm = (f0+f1)/2 2121 | tsplot(x, f, xlab='x') 2122 | lines(x, fm, lty=2, lwd=2) 2123 | legend('topleft', legend=c('log chi-square', 'normal mixture'), lty=1:2) 2124 | 2125 | dev.new() 2126 | Time = 701:1100 2127 | tsplot(Time, nyse[Time], type='l', col=4, lwd=2, ylab='', xlab='', ylim=c(-.18,.12)) 2128 | lines(Time, sv$xp[Time]/10, lwd=2, col=6) 2129 | ``` 2130 | 2131 | 2132 | 2133 | Example 6.24 2134 | ```r 2135 | n.boot = 500 # number of bootstrap replicates 2136 | tol = sqrt(.Machine$double.eps) # convergence limit 2137 | 2138 | gnpgr = diff(log(gnp)) 2139 | fit = arima(gnpgr, order=c(1,0,0)) 2140 | y = as.matrix(log(resid(fit)^2)) 2141 | num = length(y) 2142 | tsplot(y, ylab="") 2143 | 2144 | # Initial Parameters 2145 | phi1 = .9; sQ = .5; alpha = mean(y); sR0 = 1; mu1 = -3; sR1 = 2.5 2146 | init.par = c(phi1, sQ, alpha, sR0, mu1, sR1) 2147 | 2148 | # Innovations Likelihood 2149 | Linn=function(para){ 2150 | phi1 = para[1]; sQ = para[2]; alpha = para[3] 2151 | sR0 = para[4]; mu1 = para[5]; sR1 = para[6] 2152 | sv = SVfilter(num, y, 0, phi1, sQ, alpha, sR0, mu1, sR1) 2153 | return(sv$like) 2154 | } 2155 | 2156 | # Estimation 2157 | (est = optim(init.par, Linn, NULL, method="BFGS", hessian=TRUE, control=list(trace=1,REPORT=1))) 2158 | SE = sqrt(diag(solve(est$hessian))) 2159 | u = cbind(estimates=est$par, SE) 2160 | rownames(u)=c("phi1","sQ","alpha","sig0","mu1","sig1"); u 2161 | 2162 | # Bootstrap 2163 | para.star = matrix(0, n.boot, 6) # to store parameter estimates 2164 | Linn2 = function(para){ 2165 | phi1 = para[1]; sQ = para[2]; alpha = para[3] 2166 | sR0 = para[4]; mu1 = para[5]; sR1 = para[6] 2167 | sv = SVfilter(num, y.star, 0, phi1, sQ, alpha, sR0, mu1, sR1) 2168 | return(sv$like) 2169 | } 2170 | 2171 | for (jb in 1:n.boot){ cat("iteration:", jb, "\n") 2172 | phi1 = est$par[1]; sQ = est$par[2]; alpha = est$par[3] 2173 | sR0 = est$par[4]; mu1 = est$par[5]; sR1 = est$par[6] 2174 | Q = sQ^2; R0 = sR0^2; R1 = sR1^2 2175 | sv = SVfilter(num, y, 0, phi1, sQ, alpha, sR0, mu1, sR1) 2176 | 2177 | sig0 = sv$Pp+R0 2178 | sig1 = sv$Pp+R1 2179 | K0 = sv$Pp/sig0 2180 | K1 = sv$Pp/sig1 2181 | inn0 = y-sv$xp-alpha; inn1 = y-sv$xp-mu1-alpha 2182 | den1 = (1/sqrt(sig1))*exp(-.5*inn1^2/sig1) 2183 | den0 = (1/sqrt(sig0))*exp(-.5*inn0^2/sig0) 2184 | fpi1 = den1/(den0+den1) 2185 | 2186 | # (start resampling at t=4) 2187 | e0 = inn0/sqrt(sig0) 2188 | e1 = inn1/sqrt(sig1) 2189 | indx = sample(4:num, replace=TRUE) 2190 | sinn = cbind(c(e0[1:3], e0[indx]), c(e1[1:3], e1[indx])) 2191 | eF = matrix(c(phi1, 1, 0, 0), 2, 2) 2192 | xi = cbind(sv$xp,y) # initialize 2193 | 2194 | for (i in 4:num){ # generate boot sample 2195 | G = matrix(c(0, alpha+fpi1[i]*mu1), 2, 1) 2196 | h21 = (1-fpi1[i])*sqrt(sig0[i]); h11 = h21*K0[i] 2197 | h22 = fpi1[i]*sqrt(sig1[i]); h12 = h22*K1[i] 2198 | H = matrix(c(h11,h21,h12,h22),2,2) 2199 | xi[i,] = t(eF%*%as.matrix(xi[i-1,],2) + G + H%*%as.matrix(sinn[i,],2)) 2200 | } 2201 | 2202 | # Estimates from boot data 2203 | y.star = xi[,2] 2204 | phi1 = .9; sQ = .5; alpha = mean(y.star); sR0 = 1; mu1 = -3; sR1 = 2.5 2205 | init.par = c(phi1, sQ, alpha, sR0, mu1, sR1) # same as for data 2206 | est.star = optim(init.par, Linn2, NULL, method="BFGS", control=list(reltol=tol)) 2207 | para.star[jb,] = cbind(est.star$par[1], abs(est.star$par[2]), est.star$par[3], abs(est.star$par[4]), 2208 | est.star$par[5], abs(est.star$par[6])) 2209 | } 2210 | 2211 | # Some summary statistics and graphics 2212 | rmse = rep(NA, 6) # SEs from the bootstrap 2213 | for(i in 1:6){rmse[i] = sqrt(sum((para.star[,i]-est$par[i])^2)/n.boot) 2214 | cat(i, rmse[i],"\n") 2215 | } 2216 | dev.new() 2217 | phi = para.star[,1] 2218 | hist(phi, 15, prob=TRUE, main="", xlim=c(0,2), xlab="", col=astsa.col(4,.3)) 2219 | abline(v=mean(phi), col=4) 2220 | curve(dnorm(x, mean=u[1,1], sd=u[2,1]), 0, 2, add=TRUE) 2221 | abline(v=u[1,1]) 2222 | ``` 2223 | 2224 | 2225 | Example 6.26 2226 | 2227 | ```r 2228 | # generate some data from the model - 2 parameters 2229 | set.seed(1) 2230 | sQ = 1; sR = 3; n = 100 2231 | mu0 = 0; Sigma0=10; x0=rnorm(1,mu0,Sigma0) 2232 | w = rnorm(n); v = rnorm(n) 2233 | x = c(x0 + sQ*w[1]) # initialize states 2234 | y = c(x[1] + sR*v[1]) # initialize obs 2235 | for (t in 2:n){ 2236 | x[t] = x[t-1] + sQ*w[t] 2237 | y[t] = x[t] + sR*v[t] 2238 | } 2239 | 2240 | # set up the Gibbs sampler 2241 | burn = 50; n.iter = 1000 2242 | niter = burn + n.iter 2243 | draws = c() 2244 | # priors for R (a,b) and Q (c,d) IG distributions 2245 | a = 2; b = 2; c = 2; d = 1 2246 | # (1) initialize - sample sQ and sR 2247 | sR = sqrt(1/rgamma(1,a,b)); sQ = sqrt(1/rgamma(1,c,d)) 2248 | 2249 | # progress bar 2250 | pb = txtProgressBar(min = 0, max = niter, initial = 0, style=3) 2251 | 2252 | # run it 2253 | for (iter in 1:niter){ 2254 | ## (2) sample the states 2255 | run = ffbs(y,1,0,10,1,sQ,sR) # ffbs(y,A,mu0,Sigma0,Phi,Ups,Gam,sQ,sR,input) 2256 | ## (1) sample the parameters 2257 | Xs = as.matrix(run$Xs) 2258 | R = 1/rgamma(1,a+n/2,b+sum((y-Xs)^2)/2) 2259 | sR = sqrt(R) 2260 | Q = 1/rgamma(1,c+(n-1)/2,d+sum(diff(Xs)^2)/2) 2261 | sQ = sqrt(Q) 2262 | ## store everything 2263 | draws = rbind(draws,c(sQ,sR,Xs)) 2264 | setTxtProgressBar(pb,iter) 2265 | } 2266 | close(pb) 2267 | 2268 | # pull out the results for easy plotting 2269 | draws = draws[(burn+1):(niter),] 2270 | q025 = function(x){quantile(x,0.025)} 2271 | q975 = function(x){quantile(x,0.975)} 2272 | xs = draws[,3:(n+2)] 2273 | lx = apply(xs,2,q025) 2274 | mx = apply(xs,2,mean) 2275 | ux = apply(xs,2,q975) 2276 | 2277 | # some graphics 2278 | tsplot(cbind(x,y,mx), spag=TRUE, ylab='', col=c(6,8,4), lwd=c(1,1,1.5), type='o', pch=c(NA,1,NA)) 2279 | legend('topleft', legend=c("x(t)","y(t)","xs(t)"), lty=1, col=c(6,8,4), lwd=1.5, bty="n", pch=c(NA,1,NA)) 2280 | points(y) 2281 | xx=c(1:100, 100:1) 2282 | yy=c(lx, rev(ux)) 2283 | polygon(xx, yy, border=NA, col=astsa.col(4,.1)) 2284 | ``` 2285 | 2286 | 2287 | 2288 | Example 6.27 2289 | 2290 | ```r 2291 | y = jj # the data 2292 | 2293 | ### setup - model and initial parameters 2294 | set.seed(90210) 2295 | n = length(y) 2296 | A = matrix(c(1,1,0,0), 1, 4) 2297 | Phi = diag(0,4) 2298 | Phi[1,1] = 1.03 2299 | Phi[2,] = c(0,-1,-1,-1); Phi[3,]=c(0,1,0,0); Phi[4,]=c(0,0,1,0) 2300 | mu0 = rbind(.7,0,0,0) 2301 | Sigma0 = diag(.04, 4) 2302 | sR = 1 # observation noise standard deviation 2303 | sQ = diag(c(.1,.1,0,0)) # state noise standard deviations on the diagonal 2304 | 2305 | ### initializing and hyperparameters 2306 | burn = 50 2307 | n.iter = 1000 2308 | niter = burn + n.iter 2309 | draws = NULL 2310 | a = 2; b = 2; c = 2; d = 1 # hypers (c and d for both Qs) 2311 | 2312 | pb = txtProgressBar(min = 0, max = niter, initial = 0, style=3) # progress bar 2313 | 2314 | ### start Gibbs 2315 | for (iter in 1:niter){ 2316 | # draw states 2317 | run = ffbs(y,A,mu0,Sigma0,Phi,sQ,sR) # initial values are given above 2318 | xs = run$Xs 2319 | # obs variance 2320 | R = 1/rgamma(1,a+n/2,b+sum((as.vector(y)-as.vector(A%*%xs[,,]))^2)) 2321 | sR = sqrt(R) 2322 | # beta where phi = 1+beta 2323 | Y = diff(xs[1,,]) 2324 | D = as.vector(lag(xs[1,,],-1))[-1] 2325 | regu = lm(Y~0+D) # est beta = phi-1 2326 | phies = as.vector(coef(summary(regu)))[1:2] + c(1,0) # phi estimate and SE 2327 | dft = df.residual(regu) 2328 | Phi[1,1] = phies[1] + rt(1,dft)*phies[2] # use a t to sample phi 2329 | # state variances 2330 | u = xs[,,2:n] - Phi%*%xs[,,1:(n-1)] 2331 | uu = u%*%t(u)/(n-2) 2332 | Q1 = 1/rgamma(1,c+(n-1)/2,d+uu[1,1]/2) 2333 | sQ1 = sqrt(Q1) 2334 | Q2 = 1/rgamma(1,c+(n-1)/2,d+uu[2,2]/2) 2335 | sQ2 = sqrt(Q2) 2336 | sQ = diag(c(sQ1, sQ2, 0,0)) 2337 | # store results 2338 | trend = xs[1,,] 2339 | season= xs[2,,] 2340 | draws = rbind(draws,c(Phi[1,1],sQ1,sQ2,sR,trend,season)) 2341 | setTxtProgressBar(pb,iter) 2342 | } 2343 | close(pb) 2344 | 2345 | ##- display results -## 2346 | 2347 | # set up 2348 | u = draws[(burn+1):(niter),] 2349 | parms = u[,1:4] 2350 | q025 = function(x){quantile(x,0.025)} 2351 | q975 = function(x){quantile(x,0.975)} 2352 | 2353 | ## plot parameters (display at end) 2354 | names= c(expression(phi), expression(sigma[w1]), expression(sigma[w2]), expression(sigma[v])) 2355 | par(mfrow=c(4,1), mar=c(2,1,2,1)+1) 2356 | for (i in 1:4){ 2357 | hist(parms[,i], col=astsa.col(5,.4), main=names[i], xlab='', cex.main=2) 2358 | u1 = apply(parms,2,q025); u2 = apply(parms,2,mean); u3 = apply(parms,2,q975); 2359 | abline(v=c(u1[i],u2[i],u3[i]), lwd=2, col=c(3,6,3)) 2360 | } 2361 | 2362 | ### plot states (display at end) 2363 | # trend 2364 | dev.new() 2365 | par(mfrow=2:1) 2366 | tr = ts(u[,5:(n+4)], start=1960, frequency=4) 2367 | ltr = ts(apply(tr,2,q025), start=1960, frequency=4) 2368 | mtr = ts(apply(tr,2,mean), start=1960, frequency=4) 2369 | utr = ts(apply(tr,2,q975), start=1960, frequency=4) 2370 | 2371 | tsplot(mtr, ylab='', col=4, main='trend') 2372 | xx=c(time(mtr), rev(time(mtr))) 2373 | yy=c(ltr, rev(utr)) 2374 | polygon(xx, yy, border=NA, col=astsa.col(4,.1)) 2375 | 2376 | # trend + season 2377 | sea = ts(u[,(n+5):(2*n)], start=1960, frequency=4) 2378 | lsea = ts(apply(sea,2,q025), start=1960, frequency=4) 2379 | msea = ts(apply(sea,2,mean), start=1960, frequency=4) 2380 | usea = ts(apply(sea,2,q975), start=1960, frequency=4) 2381 | tsplot(msea+mtr, ylab='', col=4, main='trend + season') 2382 | xx=c(time(msea), rev(time(msea))) 2383 | yy=c(lsea+ltr, rev(usea+utr)) 2384 | polygon(xx, yy, border=NA, col=astsa.col(4,.1)) 2385 | ``` 2386 | 2387 | 2388 | [top](#table-of-contents) 2389 | 2390 | --- 2391 | 2392 | ## Chapter 7 2393 | 2394 | Code in Introduction 2395 | 2396 | ```r 2397 | x = matrix(0, 128, 6) 2398 | for (i in 1:6) x[,i] = rowMeans(fmri[[i]]) 2399 | colnames(x)=c("Brush", "Heat", "Shock", "Brush", "Heat", "Shock") 2400 | tsplot(x, ncol=2, byrow=FALSE, main='') 2401 | mtext('Awake', outer=T, adj=.25) 2402 | mtext('Sedated', outer=T, adj=.75) 2403 | ``` 2404 | 2405 | ```r 2406 | attach(eqexp) # to use the names 2407 | 2408 | P = 1:1024; S = P+1024 2409 | x = cbind(EQ5[P], EQ6[P], EX5[P], EX6[P], NZ[P], EQ5[S], EQ6[S], 2410 | EX5[S], EX6[S], NZ[S]) 2411 | x.name = c("EQ5","EQ6","EX5","EX6","NZ") 2412 | colnames(x) = c(x.name, x.name) 2413 | tsplot(x, ncol=2, byrow=FALSE, main='') 2414 | mtext('P waves', outer=T, adj=.25) 2415 | mtext('S waves', outer=T, adj=.75) 2416 | 2417 | detach(eqexp) # Redemption 2418 | ``` 2419 | 2420 | 2421 | Example 7.1 2422 | ```r 2423 | tsplot(climhyd, ncol=2, col=2:7, lwd=2) # figure 7.3 2424 | Y = climhyd # Y to hold transformed series 2425 | Y[,6] = log(Y[,6]) # log inflow 2426 | Y[,5] = sqrt(Y[,5]) # sqrt precipitation 2427 | 2428 | L = 25 # setup 2429 | M = 100 2430 | alpha = .001 2431 | fdr = .001 2432 | nq = 2 # number of inputs (Temp and Precip) 2433 | 2434 | # Spectral Matrix 2435 | Yspec = mvspec(Y, spans=L, kernel="daniell", taper=.1, plot=FALSE) 2436 | n = Yspec$n.used # effective sample size 2437 | Fr = Yspec$freq # fundamental freqs 2438 | n.freq = length(Fr) # number of frequencies 2439 | Yspec$bandwidth # = 0.05 2440 | 2441 | # Coherencies (see section 4.7 also) 2442 | Fq = qf(1-alpha, 2, L-2); cn = Fq/(L-1+Fq) 2443 | plt.name = c("(a)","(b)","(c)","(d)","(e)","(f)") 2444 | dev.new() 2445 | par(mfrow=c(2,3), cex.lab=1.2) 2446 | # The coherencies are listed as 1,2,...,15=choose(6,2) 2447 | for (i in 11:15){ 2448 | tsplot(Fr,Yspec$coh[,i], ylab="Sq Coherence", xlab="Frequency", ylim=c(0,1), 2449 | main=paste("Inflow with", names(climhyd[i-10]), sep=' ')) 2450 | abline(h = cn); text(.45,.98, plt.name[i-10], cex=1.2) 2451 | } 2452 | 2453 | # Multiple Coherency 2454 | coh.15 = stoch.reg(Y, cols.full = c(1,5), cols.red = NULL, alpha, L, M, plot.which = "coh", 2455 | main="Inflow with Temp & Precip") 2456 | text(.45,.98, plt.name[6], cex=1.2) 2457 | 2458 | # Partial F (note F-stat is called eF in the code) 2459 | numer.df = 2*nq 2460 | denom.df = Yspec$df-2*nq 2461 | 2462 | dev.new() 2463 | par(mfrow=c(3,1), mar=c(3,3,2,1)+.5, mgp = c(1.5,0.4,0), cex.lab=1.2) 2464 | out.15 = stoch.reg(Y, cols.full = c(1,5), cols.red = 5, alpha, L, M, plot.which = "F.stat") 2465 | eF = out.15$eF 2466 | pvals = pf(eF, numer.df, denom.df, lower.tail = FALSE) 2467 | pID = FDR(pvals, fdr) 2468 | abline(h=c(eF[pID]), lty=2) 2469 | title(main = "Partial F Statistic") 2470 | 2471 | # Regression Coefficients 2472 | S = seq(from = -M/2+1, to = M/2 - 1, length = M-1) 2473 | 2474 | tsplot(S, coh.15$Betahat[,1], type = "h", xlab = "", ylab =names(climhyd[1]), 2475 | ylim = c(-.025, .055), lwd=2) 2476 | abline(h=0) 2477 | title(main = "Impulse Response Functions") 2478 | 2479 | tsplot(S, coh.15$Betahat[,2], type = "h", xlab = "Index", ylab = names(climhyd[5]), 2480 | ylim = c(-.015, .055), lwd=2) 2481 | abline(h=0) 2482 | ``` 2483 | 2484 | 2485 | Example 7.2 2486 | ```r 2487 | attach(beamd) 2488 | 2489 | tau = rep(0,3) 2490 | u = ccf(sensor1, sensor2, plot=FALSE) 2491 | tau[1] = u$lag[which.max(u$acf)] # 17 2492 | u = ccf(sensor3, sensor2, plot=FALSE) 2493 | tau[3] = u$lag[which.max(u$acf)] # -22 2494 | 2495 | Y = ts.union(sensor1=lag(sensor1,tau[1]), lag(sensor2, tau[2]), lag(sensor3, tau[3])) 2496 | Y = ts.union(Y, rowMeans(Y)) 2497 | colnames(Y) = c('sensor1', 'sensor2', 'sensor3', 'beam') 2498 | tsplot(Y, main="Infrasonic Signals and Beam") 2499 | 2500 | 2501 | detach(beamd) 2502 | ``` 2503 | 2504 | 2505 | 2506 | Example 7.4 2507 | ```r 2508 | attach(beamd) 2509 | 2510 | L = 9 2511 | fdr = .001 2512 | N = 3 2513 | Y = cbind(beamd, beam=rowMeans(beamd)) 2514 | n = nextn(nrow(Y)) 2515 | 2516 | Y.fft = mvfft(as.ts(Y))/sqrt(n) 2517 | Df = Y.fft[,1:3] # fft of the data 2518 | Bf = Y.fft[,4] # beam fft 2519 | 2520 | ssr = N*Re(Bf*Conj(Bf)) # raw signal spectrum 2521 | sse = Re(rowSums(Df*Conj(Df))) - ssr # raw error spectrum 2522 | 2523 | # Smooth 2524 | SSE = filter(sse, sides=2, filter=rep(1/L,L), circular=TRUE) 2525 | SSR = filter(ssr, sides=2, filter=rep(1/L,L), circular=TRUE) 2526 | SST = SSE + SSR 2527 | 2528 | par(mfrow=c(2,1)) 2529 | Fr = 0:(n-1)/n 2530 | nFr = 1:200 # freqs to plot 2531 | 2532 | tsplot( Fr[nFr], SST[nFr], type="l", ylab="log Power", xlab="", main="Sum of Squares",log="y") 2533 | lines(Fr[nFr], SSE[nFr], type="l", lty=2) 2534 | 2535 | eF = (N-1)*SSR/SSE; df1 = 2*L; df2 = 2*L*(N-1) 2536 | pvals = pf(eF, df1, df2, lower=FALSE) # p values for FDR 2537 | pID = FDR(pvals, fdr); Fq = qf(1-fdr, df1, df2) 2538 | 2539 | tsplot(Fr[nFr], eF[nFr], type="l", ylab="F-statistic", xlab="Frequency", main="F Statistic") 2540 | abline(h=c(Fq, eF[pID]), lty=1:2) 2541 | 2542 | 2543 | detach(beamd) 2544 | ``` 2545 | 2546 | 2547 | Example 7.5 2548 | ```r 2549 | attach(beamd) 2550 | 2551 | L = 9 2552 | M = 100 2553 | M2 = M/2 2554 | N = 3 2555 | Y = cbind(beamd, beam <- rowMeans(beamd)) 2556 | n = nextn(nrow(Y)) 2557 | n.freq = n/2 2558 | 2559 | Y[,1:3] = Y[,1:3]-Y[,4] # center each series 2560 | 2561 | Y.fft = mvfft(as.ts(Y))/sqrt(n) 2562 | Ef = Y.fft[,1:3] # fft of the error 2563 | Bf = Y.fft[,4] # beam fft 2564 | ssr = N*Re(Bf*Conj(Bf)) # Raw Signal Spectrum 2565 | sse = Re(rowSums(Ef*Conj(Ef))) # Raw Error Spectrum 2566 | 2567 | # Smooth 2568 | SSE = filter(sse, sides=2, filter=rep(1/L,L), circular=TRUE) 2569 | SSR = filter(ssr, sides=2, filter=rep(1/L,L), circular=TRUE) 2570 | 2571 | # Estimate Signal and Noise Spectra 2572 | fv = SSE/(L*(N-1)) # Equation (7.77) 2573 | fb = (SSR-SSE/(N-1))/(L*N) # Equation (7.78) 2574 | fb[fb<0] = 0 2575 | 2576 | H0 = N*fb/(fv+N*fb) 2577 | H0[ceiling(.04*n):n] = 0 # zero out H0 beyond frequency .04 2578 | 2579 | # Extend components to make it a valid transform 2580 | H0 = c(H0[1:n.freq], rev(H0[2:(n.freq+1)])) 2581 | h0 = Re(fft(H0, inverse = TRUE)) # Impulse Response 2582 | h0 = c(rev(h0[2:(M2+1)]), h0[1:(M2+1)]) # center it 2583 | h1 = spec.taper(h0, p = .5) # taper it 2584 | k1 = h1/sum(h1) # normalize it 2585 | f.beam = filter(Y$beam, filter=k1, sides=2) # filter it 2586 | 2587 | # Graphics 2588 | nFr = 1:50 # freqs to display 2589 | Fr = (nFr-1)/n # frequencies 2590 | 2591 | layout(matrix(c(1, 2, 4, 1, 3, 4), nc=2)) 2592 | tsplot(10*Fr, fb[nFr], type="l", ylab="Power", xlab="Frequency (Hz)") 2593 | lines(10*Fr, fv[nFr], lty=2); text(.24, 5, "(a)", cex=1.2) 2594 | tsplot(10*Fr, H0[nFr], type="l", ylab="Frequency Response", xlab="Frequency(Hz)") 2595 | text(.23, .84, "(b)", cex=1.2) 2596 | tsplot(-M2:M2, k1, type="l", ylab="Impulse Response", xlab="Index", lwd=1.5) 2597 | text(45, .022, "(c)", cex=1.2) 2598 | tsplot(cbind(f.beam,beam), spag=TRUE, lty=1:2, ylab="beam") 2599 | text(2040, 2, "(d)", cex=1.2) 2600 | 2601 | detach(beamd) 2602 | ``` 2603 | 2604 | Example 7.6 2605 | ```r 2606 | n = 128 # length of series 2607 | n.freq = 1 + n/2 # number of frequencies 2608 | Fr = (0:(n.freq-1))/n # the frequencies 2609 | N = c(5,4,5,3,5,4) # number of series for each cell 2610 | n.subject = sum(N) # number of subjects (26) 2611 | n.trt = 6 # number of treatments 2612 | L = 3 # for smoothing 2613 | num.df = 2*L*(n.trt-1) # dfs for F test 2614 | den.df = 2*L*(n.subject-n.trt) 2615 | 2616 | 2617 | # Design Matrix (Z): 2618 | Z1 = outer(rep(1,N[1]), c(1,1,0,0,0,0)) 2619 | Z2 = outer(rep(1,N[2]), c(1,0,1,0,0,0)) 2620 | Z3 = outer(rep(1,N[3]), c(1,0,0,1,0,0)) 2621 | Z4 = outer(rep(1,N[4]), c(1,0,0,0,1,0)) 2622 | Z5 = outer(rep(1,N[5]), c(1,0,0,0,0,1)) 2623 | Z6 = outer(rep(1,N[6]), c(1,-1,-1,-1,-1,-1)) 2624 | 2625 | Z = rbind(Z1, Z2, Z3, Z4, Z5, Z6) 2626 | ZZ = t(Z)%*%Z 2627 | 2628 | SSEF <- rep(NA, n) -> SSER 2629 | 2630 | HatF = Z%*%solve(ZZ, t(Z)) 2631 | HatR = Z[,1]%*%t(Z[,1])/ZZ[1,1] 2632 | 2633 | par(mfrow=c(3,3)) 2634 | loc.name = c("Cortex 1","Cortex 2","Cortex 3","Cortex 4","Caudate","Thalamus 1", 2635 | "Thalamus 2", "Cerebellum 1","Cerebellum 2") 2636 | 2637 | for(Loc in 1:9) { 2638 | i = n.trt*(Loc-1) 2639 | Y = cbind(fmri[[i+1]], fmri[[i+2]], fmri[[i+3]], fmri[[i+4]], fmri[[i+5]], fmri[[i+6]]) 2640 | Y = mvfft(spec.taper(Y, p=.5))/sqrt(n) 2641 | Y = t(Y) # Y is now 26 x 128 FFTs 2642 | 2643 | # Calculation of Error Spectra 2644 | for (k in 1:n) { 2645 | SSY = Re(Conj(t(Y[,k]))%*%Y[,k]) 2646 | SSReg = Re(Conj(t(Y[,k]))%*%HatF%*%Y[,k]) 2647 | SSEF[k] = SSY - SSReg 2648 | SSReg = Re(Conj(t(Y[,k]))%*%HatR%*%Y[,k]) 2649 | SSER[k] = SSY - SSReg 2650 | } 2651 | 2652 | # Smooth 2653 | sSSEF = filter(SSEF, rep(1/L, L), circular = TRUE) 2654 | sSSER = filter(SSER, rep(1/L, L), circular = TRUE) 2655 | 2656 | eF =(den.df/num.df)*(sSSER-sSSEF)/sSSEF 2657 | 2658 | tsplot(Fr, eF[1:n.freq], xlab="Frequency", ylab="F Statistic", ylim=c(0,7), main=loc.name[Loc]) 2659 | abline(h=qf(.999, num.df, den.df),lty=2) 2660 | } 2661 | ``` 2662 | 2663 | Example 7.7 2664 | ```r 2665 | n = 128 2666 | n.freq = 1 + n/2 2667 | Fr = (0:(n.freq-1))/n 2668 | nFr = 1:(n.freq/2) 2669 | N = c(5,4,5,3,5,4) 2670 | n.para = 6 # number of parameters 2671 | n.subject = sum(N) # total number of subjects 2672 | 2673 | L = 3 2674 | df.stm = 2*L*(3-1) # stimulus (3 levels: Brush,Heat,Shock) 2675 | df.con = 2*L*(2-1) # conscious (2 levels: Awake,Sedated) 2676 | df.int = 2*L*(3-1)*(2-1) # interaction 2677 | den.df = 2*L*(n.subject-n.para) # df for full model 2678 | 2679 | # Design Matrix: mu a1 a2 b g1 g2 2680 | Z1 = outer(rep(1,N[1]), c(1, 1, 0, 1, 1, 0)) 2681 | Z2 = outer(rep(1,N[2]), c(1, 0, 1, 1, 0, 1)) 2682 | Z3 = outer(rep(1,N[3]), c(1, -1, -1, 1, -1, -1)) 2683 | Z4 = outer(rep(1,N[4]), c(1, 1, 0, -1, -1, 0)) 2684 | Z5 = outer(rep(1,N[5]), c(1, 0, 1, -1, 0, -1)) 2685 | Z6 = outer(rep(1,N[6]), c(1, -1, -1, -1, 1, 1)) 2686 | 2687 | Z = rbind(Z1, Z2, Z3, Z4, Z5, Z6) 2688 | ZZ = t(Z)%*%Z 2689 | 2690 | rep(NA, n)-> SSEF -> SSE.stm -> SSE.con -> SSE.int 2691 | HatF = Z%*%solve(ZZ,t(Z)) 2692 | Hat.stm = Z[,-(2:3)]%*%solve(ZZ[-(2:3),-(2:3)], t(Z[,-(2:3)])) 2693 | Hat.con = Z[,-4]%*%solve(ZZ[-4,-4], t(Z[,-4])) 2694 | Hat.int = Z[,-(5:6)]%*%solve(ZZ[-(5:6),-(5:6)], t(Z[,-(5:6)])) 2695 | 2696 | par(mfrow=c(5,3), oma=c(0,2,0,0)) 2697 | loc.name = c("Cortex 1","Cortex 2","Cortex 3","Cortex 4","Caudate", "Thalamus 1", 2698 | "Thalamus 2", "Cerebellum 1","Cerebellum 2") 2699 | for(Loc in c(1:4,9)) { # only Loc 1 to 4 and 9 used 2700 | i = 6*(Loc-1) 2701 | Y = cbind(fmri[[i+1]], fmri[[i+2]], fmri[[i+3]], fmri[[i+4]], fmri[[i+5]], fmri[[i+6]]) 2702 | Y = mvfft(spec.taper(Y, p=.5))/sqrt(n) 2703 | Y = t(Y) 2704 | for (k in 1:n) { 2705 | SSY=Re(Conj(t(Y[,k]))%*%Y[,k]) 2706 | SSReg= Re(Conj(t(Y[,k]))%*%HatF%*%Y[,k]) 2707 | SSEF[k]=SSY-SSReg 2708 | SSReg=Re(Conj(t(Y[,k]))%*%Hat.stm%*%Y[,k]) 2709 | SSE.stm[k] = SSY-SSReg 2710 | SSReg=Re(Conj(t(Y[,k]))%*%Hat.con%*%Y[,k]) 2711 | SSE.con[k]=SSY-SSReg 2712 | SSReg=Re(Conj(t(Y[,k]))%*%Hat.int%*%Y[,k]) 2713 | SSE.int[k]=SSY-SSReg 2714 | } 2715 | # Smooth 2716 | sSSEF = filter(SSEF, rep(1/L, L), circular = TRUE) 2717 | sSSE.stm = filter(SSE.stm, rep(1/L, L), circular = TRUE) 2718 | sSSE.con = filter(SSE.con, rep(1/L, L), circular = TRUE) 2719 | sSSE.int = filter(SSE.int, rep(1/L, L), circular = TRUE) 2720 | eF.stm = (den.df/df.stm)*(sSSE.stm-sSSEF)/sSSEF 2721 | eF.con = (den.df/df.con)*(sSSE.con-sSSEF)/sSSEF 2722 | eF.int = (den.df/df.int)*(sSSE.int-sSSEF)/sSSEF 2723 | 2724 | tsplot(Fr[nFr],eF.stm[nFr],xlab="Frequency", ylab="F Statistic", ylim=c(0,12)) 2725 | abline(h=qf(.999, df.stm, den.df),lty=2) 2726 | if(Loc==1) mtext("Stimulus", side=3, line=.3, cex=.8) 2727 | mtext(loc.name[Loc], side=2, line=3, cex=.8) 2728 | tsplot(Fr[nFr],eF.con[nFr], xlab="Frequency", ylab="F Statistic", ylim=c(0,12)) 2729 | abline(h=qf(.999, df.con, den.df),lty=2) 2730 | if(Loc==1) mtext("Consciousness", side=3, line=.3, cex=.8) 2731 | tsplot(Fr[nFr],eF.int[nFr], xlab="Frequency",ylab="F Statistic", ylim=c(0,12)) 2732 | abline(h=qf(.999, df.int, den.df),lty=2) 2733 | if(Loc==1) mtext("Interaction", side=3, line= .3, cex=.8) 2734 | } 2735 | ``` 2736 | 2737 | 2738 | 2739 | Example 7.8 2740 | ```r 2741 | n = 128 2742 | n.freq = 1 + n/2 2743 | Fr = (0:(n.freq-1))/n 2744 | nFr = 1:(n.freq/2) 2745 | N = c(5,4,5,3,5,4) 2746 | L = 3 2747 | n.subject = sum(N) 2748 | 2749 | # Design Matrix 2750 | Z1 = outer(rep(1,N[1]), c(1,0,0,0,0,0)) 2751 | Z2 = outer(rep(1,N[2]), c(0,1,0,0,0,0)) 2752 | Z3 = outer(rep(1,N[3]), c(0,0,1,0,0,0)) 2753 | Z4 = outer(rep(1,N[4]), c(0,0,0,1,0,0)) 2754 | Z5 = outer(rep(1,N[5]), c(0,0,0,0,1,0)) 2755 | Z6 = outer(rep(1,N[6]), c(0,0,0,0,0,1)) 2756 | Z = rbind(Z1, Z2, Z3, Z4, Z5, Z6) 2757 | ZZ = t(Z)%*%Z 2758 | 2759 | A = rbind(diag(1,3), diag(1,3)) # Contrasts: 6 x 3 2760 | nq = nrow(A) 2761 | num.df = 2*L*nq 2762 | den.df = 2*L*(n.subject-nq) 2763 | HatF = Z%*%solve(ZZ, t(Z)) # full model hat matrix 2764 | 2765 | rep(NA, n)-> SSEF -> SSER 2766 | eF = matrix(0,n,3) 2767 | 2768 | par(mfrow=c(5,3), oma=c(0,2,0,0)) 2769 | 2770 | loc.name = c("Cortex 1","Cortex 2","Cortex 3","Cortex 4","Caudate","Thalamus 1","Thalamus 2", 2771 | "Cerebellum 1","Cerebellum 2") 2772 | cond.name = c("Brush", "Heat", "Shock") 2773 | 2774 | for(Loc in c(1:4,9)) { 2775 | i = 6*(Loc-1) 2776 | Y = cbind(fmri[[i+1]],fmri[[i+2]],fmri[[i+3]],fmri[[i+4]], fmri[[i+5]],fmri[[i+6]]) 2777 | Y = mvfft(spec.taper(Y, p=.5))/sqrt(n); Y = t(Y) 2778 | for (cond in 1:3){ 2779 | Q = t(A[,cond])%*%solve(ZZ, A[,cond]) 2780 | HR = A[,cond]%*%solve(ZZ, t(Z)) 2781 | for (k in 1:n){ 2782 | SSY = Re(Conj(t(Y[,k]))%*%Y[,k]) 2783 | SSReg= Re(Conj(t(Y[,k]))%*%HatF%*%Y[,k]) 2784 | SSEF[k]= (SSY-SSReg)*Q 2785 | SSReg= HR%*%Y[,k] 2786 | SSER[k] = Re(SSReg*Conj(SSReg)) 2787 | } 2788 | 2789 | # Smooth 2790 | sSSEF = filter(SSEF, rep(1/L, L), circular = TRUE) 2791 | sSSER = filter(SSER, rep(1/L, L), circular = TRUE) 2792 | eF[,cond]= (den.df/num.df)*(sSSER/sSSEF) } 2793 | tsplot(Fr[nFr], eF[nFr,1], xlab="Frequency", ylab="F Statistic", ylim=c(0,5), main='') 2794 | abline(h=qf(.999, num.df, den.df),lty=2) 2795 | if(Loc==1) mtext("Brush", side=3, line=.3, cex=1) 2796 | mtext(loc.name[Loc], side=2, line=3, cex=.9) 2797 | tsplot(Fr[nFr], eF[nFr,2], xlab="Frequency", ylab="F Statistic", ylim=c(0,5), main='') 2798 | abline(h=qf(.999, num.df, den.df),lty=2) 2799 | if(Loc==1) mtext("Heat", side=3, line=.3, cex=1) 2800 | tsplot(Fr[nFr], eF[nFr,3], xlab="Frequency", ylab="F Statistic", ylim=c(0,5), main='') 2801 | abline(h = qf(.999, num.df, den.df) ,lty=2) 2802 | if(Loc==1) mtext("Shock", side=3, line=.3, cex=1) 2803 | } 2804 | ``` 2805 | 2806 | 2807 | Example 7.9 2808 | ```r 2809 | P = 1:1024 2810 | S = P+1024 2811 | N = 8 2812 | n = 1024 2813 | p.dim = 2 2814 | m = 10 2815 | L = 2*m+1 2816 | 2817 | eq.P = as.ts(eqexp[P,1:8]) 2818 | eq.S = as.ts(eqexp[S,1:8]) 2819 | eq.m = cbind(rowMeans(eq.P), rowMeans(eq.S)) 2820 | ex.P = as.ts(eqexp[P,9:16]) 2821 | ex.S = as.ts(eqexp[S,9:16]) 2822 | ex.m = cbind(rowMeans(ex.P), rowMeans(ex.S)) 2823 | m.diff = mvfft(eq.m - ex.m)/sqrt(n) 2824 | 2825 | eq.Pf = mvfft(eq.P-eq.m[,1])/sqrt(n) 2826 | eq.Sf = mvfft(eq.S-eq.m[,2])/sqrt(n) 2827 | ex.Pf = mvfft(ex.P-ex.m[,1])/sqrt(n) 2828 | ex.Sf = mvfft(ex.S-ex.m[,2])/sqrt(n) 2829 | 2830 | fv11 = rowSums(eq.Pf*Conj(eq.Pf)) + rowSums(ex.Pf*Conj(ex.Pf))/(2*(N-1)) 2831 | fv12 = rowSums(eq.Pf*Conj(eq.Sf)) + rowSums(ex.Pf*Conj(ex.Sf))/(2*(N-1)) 2832 | fv22 = rowSums(eq.Sf*Conj(eq.Sf)) + rowSums(ex.Sf*Conj(ex.Sf))/(2*(N-1)) 2833 | fv21 = Conj(fv12) 2834 | 2835 | # Equal Means 2836 | T2 = rep(NA, 512) 2837 | for (k in 1:512){ 2838 | fvk = matrix(c(fv11[k], fv21[k], fv12[k], fv22[k]), 2, 2) 2839 | dk = as.matrix(m.diff[k,]) 2840 | T2[k] = Re((N/2)*Conj(t(dk))%*%solve(fvk,dk)) } 2841 | eF = T2*(2*p.dim*(N-1))/(2*N-p.dim-1) 2842 | 2843 | par(mfrow=c(2,2)) 2844 | 2845 | freq = 40*(0:511)/n # in Hz (cycles per second) 2846 | tsplot(freq, eF, xlab="Frequency (Hz)", ylab="F Statistic", main="Equal Means") 2847 | abline(h=qf(.999, 2*p.dim, 2*(2*N-p.dim-1))) 2848 | 2849 | # Equal P 2850 | kd = kernel("daniell",m); 2851 | u = Re(rowSums(eq.Pf*Conj(eq.Pf))/(N-1)) 2852 | feq.P = kernapply(u, kd, circular=TRUE) 2853 | u = Re(rowSums(ex.Pf*Conj(ex.Pf))/(N-1)) 2854 | fex.P = kernapply(u, kd, circular=TRUE) 2855 | 2856 | tsplot(freq, feq.P[1:512]/fex.P[1:512], xlab="Frequency (Hz)", ylab="F Statistic", 2857 | main="Equal P-Spectra") 2858 | abline(h = qf(.999, 2*L*(N-1), 2*L*(N-1))) 2859 | 2860 | # Equal S 2861 | u = Re(rowSums(eq.Sf*Conj(eq.Sf))/(N-1)) 2862 | feq.S = kernapply(u, kd, circular=TRUE) 2863 | u = Re(rowSums(ex.Sf*Conj(ex.Sf))/(N-1)) 2864 | fex.S = kernapply(u, kd, circular=TRUE) 2865 | 2866 | tsplot(freq, feq.S[1:512]/fex.S[1:512], xlab="Frequency (Hz)", ylab="F Statistic", 2867 | main="Equal S-Spectra") 2868 | abline(h=qf(.999, 2*L*(N-1), 2*L*(N-1))) 2869 | 2870 | # Equal Spectra 2871 | u = rowSums(eq.Pf*Conj(eq.Sf))/(N-1) 2872 | feq.PS = kernapply(u, kd, circular=TRUE) 2873 | u = rowSums(ex.Pf*Conj(ex.Sf)/(N-1)) 2874 | fex.PS = kernapply(u, kd, circular=TRUE) 2875 | fv11 = kernapply(fv11, kd, circular=TRUE) 2876 | fv22 = kernapply(fv22, kd, circular=TRUE) 2877 | fv12 = kernapply(fv12, kd, circular=TRUE) 2878 | 2879 | Mi = L*(N-1) 2880 | M = 2*Mi 2881 | TS = rep(NA,512) 2882 | 2883 | for (k in 1:512){ 2884 | det.feq.k = Re(feq.P[k]*feq.S[k] - feq.PS[k]*Conj(feq.PS[k])) 2885 | det.fex.k = Re(fex.P[k]*fex.S[k] - fex.PS[k]*Conj(fex.PS[k])) 2886 | det.fv.k = Re(fv11[k]*fv22[k] - fv12[k]*Conj(fv12[k])) 2887 | 2888 | log.n1 = log(M)*(M*p.dim) 2889 | log.d1 = log(Mi)*(2*Mi*p.dim) 2890 | log.n2 = log(Mi)*2 +log(det.feq.k)*Mi + log(det.fex.k)*Mi 2891 | log.d2 = (log(M)+log(det.fv.k))*M 2892 | r = 1 - ((p.dim+1)*(p.dim-1)/6*p.dim*(2-1))*(2/Mi - 1/M) 2893 | TS[k] = -2*r*(log.n1+log.n2-log.d1-log.d2) 2894 | } 2895 | 2896 | tsplot(freq, TS, xlab="Frequency (Hz)", ylab="Chi-Sq Statistic", main="Equal Spectral Matrices") 2897 | abline(h = qchisq(.9999, p.dim^2)) # about 23.5, so not on the plot 2898 | ``` 2899 | 2900 | 2901 | 2902 | 2903 | Example 7.10 2904 | ```r 2905 | P = 1:1024 2906 | S = P+1024 2907 | mag.P = log10(apply(eqexp[P,],2,max) - apply(eqexp[P,],2,min)) 2908 | mag.S = log10(apply(eqexp[S,],2,max) - apply(eqexp[S,],2,min)) 2909 | eq.P = mag.P[1:8] 2910 | eq.S = mag.S[1:8] 2911 | ex.P = mag.P[9:16] 2912 | ex.S = mag.S[9:16] 2913 | NZ.P = mag.P[17] 2914 | NZ.S = mag.S[17] 2915 | 2916 | # Compute linear discriminant function 2917 | cov.eq = var(cbind(eq.P, eq.S)) 2918 | cov.ex = var(cbind(ex.P, ex.S)) 2919 | cov.pooled = (cov.ex + cov.eq)/2 2920 | 2921 | means.eq = colMeans(cbind(eq.P,eq.S)); 2922 | means.ex = colMeans(cbind(ex.P,ex.S)) 2923 | slopes.eq = solve(cov.pooled, means.eq) 2924 | inter.eq = -sum(slopes.eq*means.eq)/2 2925 | slopes.ex = solve(cov.pooled, means.ex) 2926 | inter.ex = -sum(slopes.ex*means.ex)/2 2927 | d.slopes = slopes.eq - slopes.ex 2928 | d.inter = inter.eq - inter.ex 2929 | 2930 | # Classify new observation 2931 | new.data = cbind(NZ.P, NZ.S) 2932 | 2933 | d = sum(d.slopes*new.data) + d.inter 2934 | post.eq = exp(d)/(1+exp(d)) 2935 | 2936 | # Print (disc function, posteriors) and plot results 2937 | cat(d.slopes[1], "mag.P +" , d.slopes[2], "mag.S +" , d.inter,"\n") 2938 | cat("P(EQ|data) =", post.eq, " P(EX|data) =", 1-post.eq, "\n" ) 2939 | 2940 | tsplot(eq.P, eq.S, type='p', xlim=c(0,1.5), ylim=c(.75,1.25), 2941 | xlab="log mag(P)", ylab ="log mag(S)", pch = 8, cex=1.1, lwd=2, 2942 | main="Classification Based on Magnitude Features", col=4) 2943 | points(ex.P, ex.S, pch = 6, cex=1.1, lwd=2, col=6) 2944 | points(new.data, pch = 3, cex=1.1, lwd=2, col=3) 2945 | abline(a = -d.inter/d.slopes[2], b = -d.slopes[1]/d.slopes[2]) 2946 | text(eq.P-.07,eq.S+.005, label=names(eqexp[1:8]), cex=.8) 2947 | text(ex.P+.07,ex.S+.003, label=names(eqexp[9:16]), cex=.8) 2948 | text(NZ.P+.05,NZ.S+.003, label=names(eqexp[17]), cex=.8) 2949 | legend("topright",c("EQ","EX","NZ"),pch=c(8,6,3),pt.lwd=2,cex=1.1, col=c(4,6,3)) 2950 | 2951 | # Cross-validation 2952 | all.data = rbind(cbind(eq.P,eq.S), cbind(ex.P,ex.S)) 2953 | post.eq <- rep(NA, 8) -> post.ex 2954 | 2955 | for(j in 1:16) { 2956 | if (j <= 8) {samp.eq = all.data[-c(j, 9:16),]; samp.ex = all.data[9:16,]} 2957 | if (j > 8) {samp.eq = all.data[1:8,]; samp.ex = all.data[-c(j, 1:8),]} 2958 | 2959 | df.eq = nrow(samp.eq)-1; df.ex = nrow(samp.ex)-1 2960 | mean.eq = colMeans(samp.eq); mean.ex = colMeans(samp.ex) 2961 | cov.eq = var(samp.eq); cov.ex = var(samp.ex) 2962 | cov.pooled = (df.eq*cov.eq + df.ex*cov.ex)/(df.eq + df.ex) 2963 | slopes.eq = solve(cov.pooled, mean.eq) 2964 | inter.eq = -sum(slopes.eq*mean.eq)/2 2965 | slopes.ex = solve(cov.pooled, mean.ex) 2966 | inter.ex = -sum(slopes.ex*mean.ex)/2 2967 | d.slopes = slopes.eq - slopes.ex 2968 | d.inter = inter.eq - inter.ex 2969 | 2970 | d = sum(d.slopes*all.data[j,]) + d.inter 2971 | if (j <= 8) post.eq[j] = exp(d)/(1+exp(d)) 2972 | if (j > 8) post.ex[j-8] = 1/(1+exp(d)) 2973 | } 2974 | 2975 | Posterior = cbind(1:8, post.eq, 1:8, post.ex) 2976 | colnames(Posterior) = c("EQ","P(EQ|data)","EX","P(EX|data)") 2977 | # results from cross-validation 2978 | round(Posterior, 3) 2979 | ``` 2980 | 2981 | 2982 | 2983 | Example 7.11 2984 | 2985 | ```r 2986 | P = 1:1024 2987 | S = P+1024 2988 | p.dim = 2 2989 | n =1024 2990 | 2991 | eq = as.ts(eqexp[,1:8]) 2992 | ex = as.ts(eqexp[,9:16]) 2993 | nz = as.ts(eqexp[,17]) 2994 | f.eq <- array(dim=c(8,2,2,512)) -> f.ex 2995 | f.NZ = array(dim=c(2,2,512)) 2996 | 2997 | # determinant for 2x2 complex matrix 2998 | det.c = function(mat){return(Re(mat[1,1]*mat[2,2]-mat[1,2]*mat[2,1]))} 2999 | L = c(15,13,5) # for smoothing 3000 | for (i in 1:8){ # compute spectral matrices 3001 | f.eq[i,,,] = mvspec(cbind(eq[P,i],eq[S,i]), spans=L, taper=.5, plot=FALSE)$fxx 3002 | f.ex[i,,,] = mvspec(cbind(ex[P,i],ex[S,i]), spans=L, taper=.5, plot=FALSE)$fxx 3003 | } 3004 | u = mvspec(cbind(nz[P],nz[S]), spans=L, taper=.5) 3005 | f.NZ = u$fxx 3006 | bndwidth = u$bandwidth*40 # about .75 Hz 3007 | fhat.eq = apply(f.eq, 2:4, mean) # average spectra 3008 | fhat.ex = apply(f.ex, 2:4, mean) 3009 | 3010 | # plot the average spectra 3011 | par(mfrow=c(2,2)) 3012 | Fr = 40*(1:512)/n 3013 | tsplot(Fr, Re(fhat.eq[1,1,]), main="", xlab="Frequency (Hz)", ylab="") 3014 | tsplot(Fr, Re(fhat.eq[2,2,]), main="", xlab="Frequency (Hz)", ylab="") 3015 | tsplot(Fr, Re(fhat.ex[1,1,]), xlab="Frequency (Hz)", ylab="") 3016 | tsplot(Fr, Re(fhat.ex[2,2,]), xlab="Frequency (Hz)", ylab="") 3017 | mtext("Average P-spectra", side=3, line=-1.5, adj=.2, outer=TRUE) 3018 | mtext("Earthquakes", side=2, line=-1, adj=.8, outer=TRUE) 3019 | mtext("Average S-spectra", side=3, line=-1.5, adj=.82, outer=TRUE) 3020 | mtext("Explosions", side=2, line=-1, adj=.2, outer=TRUE) 3021 | par(fig = c(.75, .995, .75, .98), new = TRUE) 3022 | ker = kernel("modified.daniell", L)$coef; ker = c(rev(ker),ker[-1]) 3023 | plot((-33:33)/40,ker,type="l",ylab="",xlab="",cex.axis=.7,yaxp=c(0,.04,2)) 3024 | 3025 | # choose alpha 3026 | Balpha = rep(0,19) 3027 | for (i in 1:19){ alf=i/20 3028 | for (k in 1:256) { 3029 | Balpha[i]= Balpha[i] + Re(log(det.c(alf*fhat.ex[,,k] + (1-alf)*fhat.eq[,,k])/ det.c(fhat.eq[,,k]))- 3030 | alf*log(det.c(fhat.ex[,,k])/det.c(fhat.eq[,,k])))} } 3031 | alf = which.max(Balpha)/20 # = .4 3032 | 3033 | # calculate information criteria 3034 | rep(0,17) -> KLDiff -> BDiff -> KLeq -> KLex -> Beq -> Bex 3035 | for (i in 1:17){ 3036 | if (i <= 8) f0 = f.eq[i,,,] 3037 | if (i > 8 & i <= 16) f0 = f.ex[i-8,,,] 3038 | if (i == 17) f0 = f.NZ 3039 | for (k in 1:256) { # only use freqs out to .25 3040 | tr = Re(sum(diag(solve(fhat.eq[,,k],f0[,,k])))) 3041 | KLeq[i] = KLeq[i] + tr + log(det.c(fhat.eq[,,k])) - log(det.c(f0[,,k])) 3042 | Beq[i] = Beq[i] + Re(log(det.c(alf*f0[,,k]+(1-alf)*fhat.eq[,,k])/det.c(fhat.eq[,,k])) - 3043 | alf*log(det.c(f0[,,k])/det.c(fhat.eq[,,k]))) 3044 | tr = Re(sum(diag(solve(fhat.ex[,,k],f0[,,k])))) 3045 | KLex[i] = KLex[i] + tr + log(det.c(fhat.ex[,,k])) - log(det.c(f0[,,k])) 3046 | Bex[i] = Bex[i] + Re(log(det.c(alf*f0[,,k]+(1-alf)*fhat.ex[,,k])/det.c(fhat.ex[,,k])) - 3047 | alf*log(det.c(f0[,,k])/det.c(fhat.ex[,,k]))) 3048 | } 3049 | KLDiff[i] = (KLeq[i] - KLex[i])/n 3050 | BDiff[i] = (Beq[i] - Bex[i])/(2*n) 3051 | } 3052 | 3053 | x.b = max(KLDiff)+.1; x.a = min(KLDiff)-.1 3054 | y.b = max(BDiff)+.01; y.a = min(BDiff)-.01 3055 | 3056 | dev.new() 3057 | tsplot(KLDiff[9:16], BDiff[9:16], type="p", xlim=c(x.a,x.b), ylim=c(y.a,y.b), cex=1.1, lwd=2, 3058 | xlab="Kullback-Leibler Difference",ylab="Chernoff Difference", col=6, 3059 | main="Classification Based on Chernoff and K-L Distances", pch=6) 3060 | points(KLDiff[1:8], BDiff[1:8], pch=8, cex=1.1, lwd=2, col=4) 3061 | points(KLDiff[17], BDiff[17], pch=3, cex=1.1, lwd=2, col=3) 3062 | legend("topleft", legend=c("EQ", "EX", "NZ"), pch=c(8,6,3), pt.lwd=2, col=c(4,6,3)) 3063 | abline(h=0, v=0, lty=2, col=8) 3064 | text(KLDiff[-c(1,2,3,7,14)]-.075, BDiff[-c(1,2,3,7,14)], label=names(eqexp[-c(1,2,3,7,14)]), cex=.7) 3065 | text(KLDiff[c(1,2,3,7,14)]+.075, BDiff[c(1,2,3,7,14)], label=names(eqexp[c(1,2,3,7,14)]), cex=.7) 3066 | ``` 3067 | 3068 | 3069 | Example 7.12 3070 | 3071 | ```r 3072 | library(cluster) 3073 | P = 1:1024 3074 | S = P+1024 3075 | p.dim = 2 3076 | n =1024 3077 | 3078 | eq = as.ts(eqexp[,1:8]) 3079 | ex = as.ts(eqexp[,9:16]) 3080 | nz = as.ts(eqexp[,17]) 3081 | 3082 | f = array(dim=c(17,2,2,512)) 3083 | L = c(15,15) # for smoothing 3084 | for (i in 1:8){ # compute spectral matrices 3085 | f[i,,,] = mvspec(cbind(eq[P,i],eq[S,i]), spans=L, taper=.5, plot=FALSE)$fxx 3086 | f[i+8,,,] = mvspec(cbind(ex[P,i],ex[S,i]), spans=L, taper=.5, plot=FALSE)$fxx 3087 | } 3088 | f[17,,,] = mvspec(cbind(nz[P],nz[S]), spans=L, taper=.5, plot=FALSE)$fxx 3089 | 3090 | # calculate symmetric information criteria 3091 | JD = matrix(0,17,17) 3092 | for (i in 1:16){ 3093 | for (j in (i+1):17){ 3094 | for (k in 1:256) { # only use freqs out to .25 3095 | tr1 = Re(sum(diag(solve(f[i,,,k],f[j,,,k])))) 3096 | tr2 = Re(sum(diag(solve(f[j,,,k], f[i,,,k])))) 3097 | JD[i,j] = JD[i,j] + (tr1 + tr2 - 2*p.dim) 3098 | } 3099 | } 3100 | } 3101 | 3102 | JD = (JD + t(JD))/n 3103 | colnames(JD) = c(colnames(eq), colnames(ex), "NZ") 3104 | rownames(JD) = colnames(JD) 3105 | cluster.2 = pam(JD, k = 2, diss = TRUE) 3106 | 3107 | summary(cluster.2) # print results 3108 | par(mar=c(2,2,1,.5)+2, cex=3/4, cex.lab=4/3, cex.main=4/3) 3109 | clusplot(JD, cluster.2$cluster, col.clus=gray(.5), labels=3, lines=0, 3110 | col.p = c(rep(4,8), rep(6,8), 3), 3111 | main="Clustering Results for Explosions and Earthquakes") 3112 | text(-3.5,-1.5, "Group I", cex=1.1, font=2) 3113 | text(1.5,5,"Group II", cex=1.1, font=2) 3114 | ``` 3115 | 3116 | 3117 | Example 7.13 3118 | 3119 | ```r 3120 | n = 128 3121 | Per = abs(mvfft(fmri1[,-1]))^2/n 3122 | 3123 | par(mfrow=c(2,4), mar=c(3,2,2,1), mgp = c(1.6,.6,0), oma=c(0,1,0,0)) 3124 | for (i in 1:8){ 3125 | plot(0:20, Per[1:21,i], type="n", xaxt='n', ylim=c(0,8), main=colnames(fmri1)[i+1], xlab="Cycles", ylab="") 3126 | axis(1, seq(0,20,by=4)) 3127 | Grid(nx=NA, ny=NULL, minor=FALSE) 3128 | abline(v=seq(0,60,by=4), col='lightgray', lty=1) 3129 | lines(0:20, Per[1:21,i]) } 3130 | mtext("Periodogram", side=2, line=-.3, outer=TRUE, adj=c(.2,.8)) 3131 | 3132 | fxx = mvspec(fmri1[,-1], kernel("daniell", c(1,1)), taper=.5, plot=FALSE)$fxx 3133 | l.val = rep(NA,64) 3134 | for (k in 1:64) { 3135 | u = eigen(fxx[,,k], symmetric=TRUE, only.values=TRUE) 3136 | l.val[k] = u$values[1] 3137 | } 3138 | 3139 | dev.new() 3140 | par(mar=c(2.25,2,.5,.5)+.5, mgp = c(1.6,.6,0)) 3141 | plot(l.val, type="n", xaxt='n',xlab="Cycles (Frequency x 128)", ylab="First Principal Component") 3142 | axis(1, seq(4,60,by=8)) 3143 | Grid(nx=NA, ny=NULL, minor=FALSE) 3144 | abline(v=seq(4,60,by=8), col='lightgray', lty=1) 3145 | lines(l.val) 3146 | 3147 | # at freq k=4 3148 | u = eigen(fxx[,,4], symmetric=TRUE) 3149 | lam = u$values 3150 | evec = u$vectors 3151 | lam[1]/sum(lam) # % of variance explained 3152 | sig.e1 = matrix(0,8,8) 3153 | for (l in 2:5){ # last 3 evs are 0 3154 | sig.e1 = sig.e1 + lam[l]*evec[,l]%*%Conj(t(evec[,l]))/(lam[1]-lam[l])^2 3155 | } 3156 | sig.e1 = Re(sig.e1)*lam[1]*sum(kernel("daniell", c(1,1))$coef^2) 3157 | p.val = round(pchisq(2*abs(evec[,1])^2/diag(sig.e1), 2, lower.tail=FALSE), 3) 3158 | cbind(colnames(fmri1)[-1], abs(evec[,1]), p.val) # print table values 3159 | ``` 3160 | 3161 | 3162 | Example 7.14 3163 | ```r 3164 | bhat = sqrt(lam[1])*evec[,1] 3165 | Dhat = Re(diag(fxx[,,4] - bhat%*%Conj(t(bhat)))) 3166 | res = Mod(fxx[,,4] - Dhat - bhat%*%Conj(t(bhat))) 3167 | ``` 3168 | 3169 | Example 7.15 3170 | ```r 3171 | gr = diff(log(ts(econ5, start=1948, frequency=4))) # growth rate 3172 | tsplot(100*gr, col=2:6, lwd=2, ncol=2, main="Growth Rates (%)") 3173 | 3174 | 3175 | # scale each series to have variance 1 3176 | gr = ts(apply(gr,2,scale), freq=4) # scaling strips ts attributes 3177 | dev.new() 3178 | gr.spec = mvspec(gr, spans=c(7,7), detrend=FALSE, taper=.25, col=2:6, lwd=2) 3179 | legend("topright", colnames(econ5), lty=1:5, lwd=2, col=2:6) 3180 | 3181 | dev.new() 3182 | plot.spec.coherency(gr.spec, ci=NA, main="Squared Coherencies") 3183 | 3184 | # PCs 3185 | n.freq = length(gr.spec$freq) 3186 | lam = matrix(0,n.freq,5) 3187 | for (k in 1:n.freq) lam[k,] = eigen(gr.spec$fxx[,,k], symmetric=TRUE, only.values=TRUE)$values 3188 | 3189 | dev.new() 3190 | par(mfrow=c(2,1)) 3191 | tsplot(gr.spec$freq, lam[,1], ylab="", xlab="Frequency", main="First Eigenvalue") 3192 | abline(v=.25, lty=2) 3193 | tsplot(gr.spec$freq, lam[,2], ylab="", xlab="Frequency", main="Second Eigenvalue") 3194 | abline(v=.125, lty=2) 3195 | 3196 | e.vec1 = eigen(gr.spec$fxx[,,10], symmetric=TRUE)$vectors[,1] 3197 | e.vec2 = eigen(gr.spec$fxx[,,5], symmetric=TRUE)$vectors[,2] 3198 | round(Mod(e.vec1), 2); round(Mod(e.vec2), 3) 3199 | ``` 3200 | 3201 | 3202 | Example 7.17 (there is now a script for the spectral envelope) 3203 | 3204 | ```r 3205 | xdata = dna2vector(bnrf1ebv) 3206 | u = specenv(xdata, spans=c(7,7)) 3207 | 3208 | # details near the peak (coefs are for A, C, G, and T) 3209 | round(u,4)[1330:1336,] 3210 | ``` 3211 | 3212 | Example 7.18 3213 | 3214 | ```r 3215 | x = astsa::nyse 3216 | # possible transformations include absolute value and squared value 3217 | xdata = cbind(x, abs(x), x^2) 3218 | par(mfrow=2:1) 3219 | u = specenv(xdata, real=TRUE, spans=c(3,3)) 3220 | # peak at freq = .001 so let's 3221 | # plot the optimal transform 3222 | beta = u[2, 3:5] # scalings 3223 | b = beta/beta[2] # makes abs(x) coef=1 3224 | gopt = function(x) { b[1]*x+b[2]*abs(x)+b[3]*x^2 } 3225 | curve(gopt, -.2, .2, col=4, lwd=2, panel.first=Grid(nym=0)) 3226 | gabs = function(x) { b[2]*abs(x) } # corresponding to |x| 3227 | curve(gabs, -.2, .2, add=TRUE, col=6) 3228 | legend('bottomright', lty=1, col=c(4,6), legend=c('optimal', 'absolute value'), bg='white') 3229 | ``` 3230 | 3231 | [top](#table-of-contents) 3232 | 3233 | --- 3234 | --------------------------------------------------------------------------------