1次元ハイブリッドモンテカルロを実装してみた
1次元HMCのコードを書いたのでメモ
動機はNUTSに挑戦する前にパラメータと尤度、ハミルトニアンの振る舞いについて理解しておきたかったので
偉大なる先輩のblogはこちら
ハイブリッドモンテカルロを実装してみた
http://d.hatena.ne.jp/koh_ta/20121116/1353074113
######################################################## #HMC #initial value epsilon<-0.25 N<-1000 L<-4 p<-rep(NA, N) q<-rep(NA, N) s<-rep(NA, N) h<-rep(NA, N) p[1]<-rnorm(0, 1, n=1) q[1]<-3 h[1]<-hamiltonian(q[1], p[1]) SD<-2 MU<-1 #q obey to N(3, 2.2) f:function itself, df:differentiation function f<-function(x){dnorm(x, mean=MU, sd=SD)} df<-function(x){dnorm(x, mean=MU, sd=SD) * (-1/(2*SD^2)*(2*x-2*MU) )} hamiltonian<-function(q,p){log(exp(f(q))-(p^2)/2)} #ploting function and differentiation function plot(df, -1, 3) par(new=T) plot(f, -1, 3, col="red") leapfrog<-function(q_var, p_var, epsilon){ p_var<-p_var-(epsilon*df(q_var)/2) q_var<-q_var+epsilon*p_temp p_var<-p_var-(epsilon*df(q_var)/2) cat(q_var, p_var, "\r\n") c(q_var, p_var) } for(i in 2:N){ p_temp<-p[i-1] q_temp<-q[i-1] for(j in 1:L){ qp_temp<-leapfrog(q_temp, p_temp, epsilon) q_temp<-qp_temp[1] p_temp<-qp_temp[2] } #accept by hamiltonian ratio alpha<-min(1, hamiltonian(q_temp, p_temp)/hamiltonian(q[1], p[1]), na.rm=TRUE) if(alpha>runif(1)){ q[i]<-q_temp p[i]<- (-1)*p_temp s[i]<-1 }else{ q[i]<-q[i-1] p[i]<-p[i-1] s[i]<-0 } h[i]<-hamiltonian(q[i], p[i]) } ylim<-c(-2, 4) plot(p,type="l",ylim=ylim) par(new=T) plot(q, col="red",type="l",ylim=ylim) par(new=T) plot(s, col="blue", ylim=ylim) par(new=T) plot(h, col="green",type="l",ylim=ylim)