相関の強い二変量正規分布に対してハイブリッドモンテカルロを使ってみた。上から順に、サンプリング結果、x1の自己相関、x2の自己相関。
自己相関ほぼ完全になし、という結果になった。ギブスサンプラーだとこうはいかない。ただし、
- 微分方程式を解く時間のスケールが小さすぎると自己相関が出たので良い感じのスケールをちょっとだけ探索した。
- ステップ幅を固定にしたら怪しげな自己相関の挙動がでた。
- 計算時間でギブスサンプラーと比較してどちらが有利かは今回は検討してません。
という点は追記しておきます。
PRML 11章 を読んで適当に実装してみた。リープフロッグのところで無駄な計算をしているので要改良。
# Hybrid MC sampling # [Remark] # "p" in this source file is "r" in PRML # "q" in this source file is "z" in PRML # Setting h <- 0.01 Sigma <- matrix(c(3,2.5,2.5,3),nc=2) iSigma <- solve(Sigma) # Energy : log of density function E <- function(q){ sum(q * (iSigma %*% q)) # normal distribution } dE <- function(q){ 2*iSigma %*% q } # Kinematic K <- function(p){ sum(p^2) } # Hamiltonian H <- function(p,q){ E(q) + K(p) } # Leapfrog method step.leapfrog <- function(p,q,h){ p.half <- p-(h/2)*dE(q) q.1 <- q+h*2*p.half p.1 <- p.half-(h/2)*dE(q.1) list(p=p.1,q=q.1) } #------------- # Main #------------- N <- 3000 # The number of sampling R <- 30 # Leapfrog step counts q.values <- matrix(rep(0,2*N),nc=2) # Buffer p=rnorm(2) # initial state q=rnorm(2) # initial state H.value <- H(p,q) for( n in 1:N){ h <- 0.01+0.1*runif(1) # Leapfrog step size p.old <- p q.old <- q H.old <- H.value for( i in 1:R ){ nxt <- step.leapfrog(p,q,h) p <- nxt$p q <- nxt$q } if( exp(H(p,q)-H.old) < runif(1) ){ # rejection p <- p.old q <- q.old } q.values[n,] <- q p <- rnorm(2) H.value <- H(p,q) } # Plotting results par(mfrow=c(3,1)) plot(q.values,xlab="x1",ylab="x2",main="Result of hybrid MC sampler",pch=20,col="gray") acf(q.values[,1],main="Auto-correlation function of x1") acf(q.values[,2],main="Auto-correlation function of x2") dev2bitmap(file="hybridMC.jpg",width=6,height=18,gaa=4,taa=4)
関連エントリ:ハミルトン系の数値計算 (PRML11章)