inits
?
Yes, the inits
and inits
control the range
of the initial values, but the chain is still allowed to move
freely after this initial step, as shown in the following example.
Please report to the next question to learn how you can specify hard limits for the chains.
## a log-pdf to sample from
p.log <- function(x) {
B <- 0.03 # controls 'bananacity'
-x[1]^2 / 200 - 1 / 2 * (x[2] + B * x[1]^2 - 100 * B)^2
}
unif_inits <- data.frame(
a = runif(10, min = -10, max = -5),
b = runif(10, min = -10, max = -5)
)
set.seed(20201209)
res1 <- MCMCEnsemble(
p.log,
inits = unif_inits,
max.iter = 3000, n.walkers = 10,
method = "stretch",
coda = TRUE
)
#> Using stretch move with 10 walkers.
summary(res1$samples)
#>
#> Iterations = 1:300
#> Thinning interval = 1
#> Number of chains = 10
#> Sample size per chain = 300
#>
#> 1. Empirical mean and standard deviation for each variable,
#> plus standard error of the mean:
#>
#> Mean SD Naive SE Time-series SE
#> a -4.621 11.729 0.2141 1.0784
#> b -2.126 6.839 0.1249 0.9295
#>
#> 2. Quantiles for each variable:
#>
#> 2.5% 25% 50% 75% 97.5%
#> a -28.95 -13.072 -3.8362 3.809 17.211
#> b -20.63 -4.627 0.3295 2.364 4.209
plot(res1$samples)
res2 <- MCMCEnsemble(
p.log,
inits = unif_inits,
max.iter = 3000, n.walkers = 10,
method = "differential.evolution",
coda = TRUE
)
#> Using differential.evolution move with 10 walkers.
summary(res2$samples)
#>
#> Iterations = 1:300
#> Thinning interval = 1
#> Number of chains = 10
#> Sample size per chain = 300
#>
#> 1. Empirical mean and standard deviation for each variable,
#> plus standard error of the mean:
#>
#> Mean SD Naive SE Time-series SE
#> a -4.136 9.160 0.16723 0.8741
#> b -0.236 4.078 0.07446 0.4401
#>
#> 2. Quantiles for each variable:
#>
#> 2.5% 25% 50% 75% 97.5%
#> a -22.63 -10.777 -3.657 3.218 11.823
#> b -13.00 -1.561 1.179 2.444 4.324
plot(res2$samples)
There is no built-in way to define hard limits for the parameter and make sure they never go outside of this range.
The recommended way to address this issue is to handle these cases in
the function f
you provide.
For example, to keep parameters in the 0-1 range:
p.log.restricted <- function(x) {
if (any(x < 0, x > 1)) {
return(-Inf)
}
B <- 0.03 # controls 'bananacity'
-x[1]^2 / 200 - 1 / 2 * (x[2] + B * x[1]^2 - 100 * B)^2
}
unif_inits <- data.frame(
a = runif(10, min = 0, max = 1),
b = runif(10, min = 0, max = 1)
)
res <- MCMCEnsemble(
p.log.restricted,
inits = unif_inits,
max.iter = 3000, n.walkers = 10,
method = "stretch",
coda = TRUE
)
#> Using stretch move with 10 walkers.
summary(res$samples)
#>
#> Iterations = 1:300
#> Thinning interval = 1
#> Number of chains = 10
#> Sample size per chain = 300
#>
#> 1. Empirical mean and standard deviation for each variable,
#> plus standard error of the mean:
#>
#> Mean SD Naive SE Time-series SE
#> a 0.4893 0.2933 0.005354 0.02960
#> b 0.6585 0.2659 0.004854 0.02577
#>
#> 2. Quantiles for each variable:
#>
#> 2.5% 25% 50% 75% 97.5%
#> a 0.01970 0.2284 0.4886 0.7428 0.9728
#> b 0.05949 0.4930 0.7391 0.8683 0.9904
plot(res$samples)
This might seem inconvenient but in most cases, users will define
their posterior probability as the product of a prior probability and
the likelihood. In this situation, values that are not contained in the
log-prior density automatically return -Inf
in the
log-posterior and it is not necessary to define it explicitly:
prior.log <- function(x) {
dunif(x, log = TRUE)
}
lkl.log <- function(x) {
B <- 0.03 # controls 'bananacity'
-x[1]^2 / 200 - 1 / 2 * (x[2] + B * x[1]^2 - 100 * B)^2
}
posterior.log <- function(x) {
sum(prior.log(x)) + lkl.log(x)
}
res <- MCMCEnsemble(
posterior.log,
inits = unif_inits,
max.iter = 5000, n.walkers = 10,
method = "stretch",
coda = TRUE
)
#> Using stretch move with 10 walkers.
summary(res$samples)
#>
#> Iterations = 1:500
#> Thinning interval = 1
#> Number of chains = 10
#> Sample size per chain = 500
#>
#> 1. Empirical mean and standard deviation for each variable,
#> plus standard error of the mean:
#>
#> Mean SD Naive SE Time-series SE
#> a 0.5154 0.2902 0.004104 0.02478
#> b 0.6838 0.2356 0.003332 0.02035
#>
#> 2. Quantiles for each variable:
#>
#> 2.5% 25% 50% 75% 97.5%
#> a 0.02785 0.2611 0.5357 0.7700 0.9854
#> b 0.12319 0.5347 0.7367 0.8734 0.9893
plot(res$samples)