class MetropolisHastingsBenchmark extends BreezeBenchmark {
val burnIn = 1024*1024
val dropCount = 25
val numSamples = 1024*1024
val bufferSize = 1024*32
val epsilon = 1e-8
def likelihood(x: Double) = 2*math.log1p(1+epsilon-x) + 3*math.log1p(x*x*x+epsilon) //Epsilon is present to avoid throwing exceptions in the unlikely event either 0 or 1 is sampled
def gaussianJump(x: Double) = Gaussian(x, 1)
def gaussianJumpLogProb(start: Double, end: Double) = 0.0 // It would actually be this, but due to symmetry why bother? -math.pow(start-end,2)/2.0
def pullAllSamples(m: Rand[Double]) = {
var result = 0.0
cfor(0)(i => i<numSamples, i => i+1)(i => {
result = m.draw()
})
result
}
def pullAllSamplesWithWork(m: Rand[Double]) = {
var result = 0.0
cfor(0)(i => i<numSamples/4, i => i+1)(i => {
val x = m.draw()
cfor(0)(j => j < 400, j => j+1)(j => {
result += math.log(math.exp(x)) / (1+x*x)
})
})
result
}
def timeMarkovChain(reps: Int) = run(reps) {
val m = MarkovChain.metropolisHastings(0.5, gaussianJump _)(likelihood _)
pullAllSamples(m)
}
def timeMarkovChainEquiv(reps: Int) = run(reps) {
val m = ArbitraryMetropolisHastings(likelihood _, gaussianJump _, gaussianJumpLogProb _, 0.5, burnIn=0, dropCount=0)