# Copy of R-code given in the Appendix # A.2 More on Poisson–HMMs, including estimation by EM pois.HMM.generate_sample <- function(n,m,lambda,gamma,delta=NULL) { if(is.null(delta))delta<-solve(t(diag(m)-gamma+1),rep(1,m)) mvect <- 1:m state <- numeric(n) state[1] <- sample(mvect,1,prob=delta) for (i in 2:n) state[i]<-sample(mvect,1,prob=gamma[state[i-1],]) x <- rpois(n,lambda=lambda[state]) x } pois.HMM.lalphabeta<-function(x,m,lambda,gamma,delta=NULL) { if(is.null(delta))delta<-solve(t(diag(m)-gamma+1),rep(1,m)) n <- length(x) lalpha <- lbeta<-matrix(NA,m,n) allprobs <- outer(x,lambda,dpois) foo <- delta*allprobs[1,] sumfoo <- sum(foo) lscale <- log(sumfoo) foo <- foo/sumfoo lalpha[,1] <- log(foo)+lscale for (i in 2:n) { foo <- foo%*%gamma*allprobs[i,] sumfoo <- sum(foo) lscale <- lscale+log(sumfoo) foo <- foo/sumfoo lalpha[,i] <- log(foo)+lscale } lbeta[,n] <- rep(0,m) foo <- rep(1/m,m) lscale <- log(m) for (i in (n-1):1) { foo <- gamma%*%(allprobs[i+1,]*foo) lbeta[,i] <- log(foo)+lscale sumfoo <- sum(foo) foo <- foo/sumfoo lscale <- lscale+log(sumfoo) } list(la=lalpha,lb=lbeta) } pois.HMM.EM <- function(x,m,lambda,gamma,delta, maxiter=1000,tol=1e-6,...) { n <- length(x) lambda.next <- lambda gamma.next <- gamma delta.next <- delta for (iter in 1:maxiter) { lallprobs <- outer(x,lambda,dpois,log=TRUE) fb <- pois.HMM.lalphabeta(x,m,lambda,gamma,delta=delta) la <- fb$la lb <- fb$lb c <- max(la[,n]) llk <- c+log(sum(exp(la[,n]-c))) for (j in 1:m) { for (k in 1:m) { gamma.next[j,k] <- gamma[j,k]*sum(exp(la[j,1:(n-1)]+ lallprobs[2:n,k]+lb[k,2:n]-llk)) } lambda.next[j] <- sum(exp(la[j,]+lb[j,]-llk)*x)/ sum(exp(la[j,]+lb[j,]-llk)) } gamma.next <- gamma.next/apply(gamma.next,1,sum) delta.next <- exp(la[,1]+lb[,1]-llk) delta.next <- delta.next/sum(delta.next) crit <- sum(abs(lambda-lambda.next)) + sum(abs(gamma-gamma.next)) + sum(abs(delta-delta.next)) if(crit