| shakeandbake {hitandrun} | R Documentation |
"Shake and Bake" sampler
Description
The "Shake and Bake" method generates a Markov Chain whose stable state converges on the uniform distribution over a the boundary of a convex polytope defined by a set of linear inequality constraints. shakeandbake further uses the Moore-Penrose pseudo-inverse to eliminate an arbitrary set of linear equality constraints before applying the "Shake and Bake" sampler.
sab.init and sab.run together provide a re-entrant version of shakeandbake so that the Markov chain can be continued if convergence is not satisfactory.
Usage
shakeandbake(constr, n.samples=1E4,
thin.fn = function(n) { ceiling(log(n + 1)/4 * n^3) }, thin = NULL,
x0.randomize=FALSE, x0.method="slacklp", x0 = NULL, eliminate = TRUE)
sab.init(constr,
thin.fn = function(n) { ceiling(log(n + 1)/4 * n^3) }, thin = NULL,
x0.randomize=FALSE, x0.method="slacklp", x0 = NULL, eliminate = TRUE)
sab.run(state, n.samples)
Arguments
constr |
Linear constraints that define the sampling space (see details) |
n.samples |
The desired number of samples to return. The sampler is run for |
thin.fn |
Function that specifies a thinning factor depending on the dimension of the sampling space after equality constraints have been eliminated. Will only be invoked if |
thin |
The thinning factor |
x0 |
Seed point for the Markov Chain. The seed point is specified in the original space, and transformed to the sampling space automatically. |
x0.method |
Method to generate the seed point if |
x0.randomize |
Whether to generate a random seed point if |
eliminate |
Whether to eliminate redundant constraints before constructing the transformation to the sampling space and (optionally) calculating the seed point. |
state |
A state object, as generated by |
Details
The constraints are given as a list with the elements constr, dir and rhs. dir is a vector with values '=' or '<='. constr is a matrix and rhs a vector, which encode the standard linear programming constraint froms Ax = b and Ax \leq b (depending on dir). The lengths of rhs and dir must match the number of rows of constr.
shakeandbake applies solution.basis to generate a basis of the (translated) solution space of the linear constraints (if any). An affine transformation is generated using createTransform and applied to the constraints. Then, a seed point satisfying the inequality constraints is generated using createSeedPoint. The closest face to this point is found using findFace. Finally, sab is used to generate the samples.
Value
For shakeandbake, a matrix containing the generated samples as rows.
For sab.init, a state object, containing:
basis |
The basis for the sampling space. See |
transform |
The sampling space transformation. See |
constr |
The linear inequality constraints translated to the sampling space. See |
x0 |
The generated seed point. See |
i0 |
The index of the closest face. See |
thin |
The thinning factor to be used. |
For sab.run, a list containing:
samples |
A matrix containing the generated samples as rows. |
state |
A state object that can be used to continue sampling from the Markov chain (i.e. |
Note
"Shake and Bake" is a Markov Chain Monte Carlo (MCMC) method, so generated samples form a correlated time series.
Author(s)
Gert van Valkenhoef
See Also
Examples
# Sample from the 3-simplex with the additional constraint that w_1/w_2 = 2
# Three inequality constraints, two equality constraints
constr <- mergeConstraints(simplexConstraints(3), exactRatioConstraint(3, 1, 2, 2))
samples <- shakeandbake(constr, n.samples=1000)
stopifnot(dim(samples) == c(1000, 3))
stopifnot(all.equal(apply(samples, 1, sum), rep(1, 1000)))
sel <- samples[,3] > 0.5 # detect which side we're on
stopifnot(all.equal(samples[sel,], matrix(rep(c(0,0,1), each=sum(sel)), ncol=3)))
stopifnot(all.equal(samples[!sel,], matrix(rep(c(2/3,1/3,0), each=sum(sel)), ncol=3)))
# Sample from the unit rectangle (no equality constraints)
constr <- list(
constr = rbind(c(1,0), c(0,1), c(-1,0), c(0,-1)),
dir=rep('<=', 4),
rhs=c(1, 1, 0, 0))
state <- sab.init(constr)
result <- sab.run(state, n.samples=1000)
faces <- result$faces
samples <- result$samples
stopifnot(all(samples >= -1e-15 & samples <= 1 + 1e-15))
stopifnot(all.equal(samples[faces==1,1], rep(1, sum(faces==1))))
stopifnot(all.equal(samples[faces==2,2], rep(1, sum(faces==2))))
stopifnot(all.equal(samples[faces==3,1], rep(0, sum(faces==3))))
stopifnot(all.equal(samples[faces==4,2], rep(0, sum(faces==4))))
# Continue sampling from the same chain:
result <- sab.run(result$state, n.samples=1000)
samples <- rbind(samples, result$samples)