Skip to content

Commit 65d712d

Browse files
committed
updates
1 parent f304761 commit 65d712d

3 files changed

Lines changed: 77 additions & 104 deletions

File tree

BayesianTools/R/SMC.R

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11

22
#' SMC sampler
3-
#' @author Florian Hartig, Matthias Speich
4-
#' @description Sequential Monte Carlo Sampler
3+
#'
4+
#' @description A Sequential Monte Carlo (SMC) Sampler with differential evolution updating to avoid particle depletion
5+
#'
56
#' @param bayesianSetup either an object of class bayesianSetup created by \code{\link{createBayesianSetup}} (recommended), or a log target function
67
#' @param initialParticles initial particles - either a draw from the prior, provided as a matrix with the single parameters as columns and each row being one particle (parameter vector), or a numeric value with the number of desired particles. In this case, the sampling option must be provided in the prior of the BayesianSetup.
78
#' @param iterations number of iterations
8-
#'
99
#' @param exponents series of exponents to build the intermediate distributions
1010
#' @param lastMutateSteps how many resampling (MCMC) steps after the SMC iterations to increase sample diversity.
1111
#' @param proposal optional proposal class
1212
#' @param x Parameter to generate the exponential sequence for building intermediary distributions. Default value from Jeremiah et al. (2012)
1313
#' @param m Parameter to generate the exponential sequence for building intermediary distributions. Default value from Jeremiah et al. (2012)
1414
#' @param sampling Which algorithm to use for particle (re)sampling. Options are "multinomial" (default), "residual" and "systematic"
15-
#' @param ess.limit Threshold value of effective sample size below which resampling is done (fraction of effective sample size). By default, the value is set to half the number of particles. To resample at each step, use a value >= the number of particles.
16-
#' @param ess.factor
15+
#' @param ess.limit Threshold value (as a fraction between 0 and 1) of the effective sample compared to the number of particles at which resampling is done. To resample at each step, use a value > 1.
1716
#' @param lastResample Iteration (starting from the end) at which particle resampling is forced. To deactivate this, set to a value < 0
1817
#'
1918
#' @param resampling deprecated, use resamplingSteps to modify resampling
@@ -28,6 +27,9 @@
2827
#'
2928
#' @details The sampler can be used for rejection sampling as well as for sequential Monte Carlo. For the former case set the iterations to one.
3029
#' @note The SMC currently assumes that the initial particle is sampled from the prior. If a better initial estimate of the posterior distribution is available, this the sampler should be modified to include this. Currently, however, this is not included in the code, so the appropriate adjustments have to be done by hand.
30+
#'
31+
#' @author Florian Hartig, Matthias Speich
32+
#'
3133
#' @export
3234
#' @example /inst/examples/SMCHelp.R
3335
smcSampler <- function(bayesianSetup,
@@ -43,7 +45,7 @@ smcSampler <- function(bayesianSetup,
4345
x=3.11,
4446
m=7E-08,
4547
sampling="multinomial",
46-
ess.limit=NULL,
48+
ess.limit=0.5,
4749
ess.factor = 0.95,
4850
lastResample = 1,
4951
pars.lower=NULL,
@@ -72,7 +74,7 @@ smcSampler <- function(bayesianSetup,
7274
info$ess.vec <- info$exponents <- vector("numeric", 10000)
7375
info$diagnostics <- diag.end <- list()
7476
lastAccept <- vector("numeric", lastMutateSteps)
75-
77+
if(ess.limit < 0) stop("ess.limit can't be < 0")
7678

7779
setup <- checkBayesianSetup(bayesianSetup)
7880

@@ -102,7 +104,7 @@ smcSampler <- function(bayesianSetup,
102104
particles <- initialParticles
103105
rejectionRate = 0
104106
particleSize = nrow(initialParticles)
105-
if(is.null(ess.limit)){ess.limit <- round(particleSize) * 0.5}
107+
ess.limit.abs = round(particleSize) * ess.limit
106108

107109
weights <- oldweights <- oldInter <- rep(0, particleSize)
108110

@@ -237,8 +239,16 @@ smcSampler <- function(bayesianSetup,
237239
ess <- 1 / sum(exp(2 * weights))
238240
oldInter <- oldExp * posteriorValues + (1-oldExp) * importanceValues
239241

242+
# TODO 8.3.26 - what's up with this alternative call using ess.factor, which was also present ? For the moment, I erased this option from the code.
243+
# ess.factor was in the main function call
240244
#inter.out <- beta.search(ess=ess, target.ess = (ess * ess.factor), posteriorValues = posteriorValues, importanceValues = importanceValues, oldInter = oldInter, curWeights = weights, curExp = curExp)
241-
inter.out <- beta.search(ess=ess, target.ess = (ess.limit-1), posteriorValues = posteriorValues, importanceValues = importanceValues, oldInter = oldInter, curWeights = weights, curExp = curExp)
245+
inter.out <- beta.search(ess=ess,
246+
target.ess = (ess.limit.abs-1), # TODO 8.3.26 why -1?
247+
posteriorValues = posteriorValues,
248+
importanceValues = importanceValues,
249+
oldInter = oldInter,
250+
curWeights = weights,
251+
curExp = curExp)
242252
curExp <- inter.out$newExp
243253
weights <- inter.out$weights
244254
interDist <- inter.out$interDist
@@ -258,7 +268,7 @@ smcSampler <- function(bayesianSetup,
258268
# Resample also on the last iteration, or at the iteration (starting from the end) given by the parameter lastResample (output is based
259269
# on the location of particles in parameter space, the weights are not considered in the output)
260270

261-
if(ess < ess.limit | icount == (length(exponents) - lastResample) | doResample){
271+
if(ess < ess.limit.abs | icount == (length(exponents) - lastResample) | doResample){
262272

263273
oldExp <- curExp
264274

BayesianTools/man/smcSampler.Rd

Lines changed: 56 additions & 93 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

BayesianTools/tests/testthat/test-SMC.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ test_that("resampling works", {
1919
weights = log(c(1,2,3)/6)
2020
size = 10000
2121

22-
x1 = replicate(size, resample(weights))
22+
x1 = replicate(size, BayesianTools:::resample(weights))
2323
dif = table(x1) - exp(weights) * size * 3
2424
expect_lt(sum(abs(dif)), 300)
2525

0 commit comments

Comments
 (0)