# Markov chain Monte Carlo (MCMC)

Gen supports standard Markov Chain Monte Carlo algorithms and allows users to write their own custom kernels.

`Gen.elliptical_slice`

`Gen.hmc`

`Gen.involutive_mcmc`

`Gen.mala`

`Gen.metropolis_hastings`

`Gen.mh`

`Gen.reversal`

`Gen.@kern`

`Gen.@pkern`

`Gen.@rkern`

`Gen.metropolis_hastings`

— Function```
(new_trace, accepted) = metropolis_hastings(
trace, selection::Selection;
check=false, observations=EmptyChoiceMap())
```

Perform a Metropolis-Hastings update that proposes new values for the selected addresses from the internal proposal (often using ancestral sampling), returning the new trace (which is equal to the previous trace if the move was not accepted) and a Bool indicating whether the move was accepted or not.

```
(new_trace, accepted) = metropolis_hastings(
trace, proposal::GenerativeFunction, proposal_args::Tuple;
check=false, observations=EmptyChoiceMap())
```

Perform a Metropolis-Hastings update that proposes new values for some subset of random choices in the given trace using the given proposal generative function, returning the new trace (which is equal to the previous trace if the move was not accepted) and a Bool indicating whether the move was accepted or not.

The proposal generative function should take as its first argument the current trace of the model, and remaining arguments `proposal_args`

. If the proposal modifies addresses that determine the control flow in the model, values must be provided by the proposal for any addresses that are newly sampled by the model.

```
(new_trace, accepted) = metropolis_hastings(
trace, proposal::GenerativeFunction, proposal_args::Tuple,
involution::Union{TraceTransformDSLProgram,Function};
check=false, observations=EmptyChoiceMap())
```

Perform a generalized (reversible jump) Metropolis-Hastings update based on an involution (bijection that is its own inverse) on a space of choice maps, returning the new trace (which is equal to the previous trace if the move was not accepted) and a Bool indicating whether the move was accepted or not.

Most users will want to construct `involution`

using the Trace Transform DSL with the `@transform`

macro, but for more user control it is also possible to provide a Julia function for `involution`

, that has the following signature:

`(new_trace, bwd_choices::ChoiceMap, weight) = involution(trace::Trace, fwd_choices::ChoiceMap, fwd_retval, fwd_args::Tuple)`

The generative function `proposal`

is executed on arguments `(trace, proposal_args...)`

, producing a choice map `fwd_choices`

and return value `fwd_ret`

. For each value of model arguments (contained in `trace`

) and `proposal_args`

, the `involution`

function applies an involution that maps the tuple `(get_choices(trace), fwd_choices)`

to the tuple `(get_choices(new_trace), bwd_choices)`

. Note that `fwd_ret`

is a deterministic function of `fwd_choices`

and `proposal_args`

. When only discrete random choices are used, the `weight`

must be equal to `get_score(new_trace) - get_score(trace)`

.

When continuous random choices are used, the `weight`

returned by the involution must include an additive correction term that is the determinant of the the Jacobian of the bijection on the continuous random choices that is obtained by currying the involution on the discrete random choices (this correction term is automatically computed if the involution is constructed using the Trace Transform DSL). NOTE: The Jacobian matrix of the bijection on the continuous random choices must be full-rank (i.e. nonzero determinant). The `check`

keyword argument to the involution can be used to enable or disable any dynamic correctness checks that the involution performs; for successful executions, `check`

does not alter the return value.

`Gen.mh`

— Function```
(new_trace, accepted) = mh(trace, selection::Selection; ..)
(new_trace, accepted) = mh(trace, proposal::GenerativeFunction, proposal_args::Tuple; ..)
(new_trace, accepted) = mh(trace, proposal::GenerativeFunction, proposal_args::Tuple, involution; ..)
```

Alias for `metropolis_hastings`

. Perform a Metropolis-Hastings update on the given trace.

`Gen.mala`

— Function```
(new_trace, accepted) = mala(
trace, selection::Selection, tau::Real;
check=false, observations=EmptyChoiceMap())
```

Apply a Metropolis-Adjusted Langevin Algorithm (MALA) update.

`Gen.hmc`

— Function```
(new_trace, accepted) = hmc(
trace, selection::Selection; L=10, eps=0.1,
check=false, observations=EmptyChoiceMap())
```

Apply a Hamiltonian Monte Carlo (HMC) update that proposes new values for the selected addresses, returning the new trace (which is equal to the previous trace if the move was not accepted) and a `Bool`

indicating whether the move was accepted or not.

Hamilton's equations are numerically integrated using leapfrog integration with step size `eps`

for `L`

steps. See equations (5.18)-(5.20) of Neal (2011).

**References**

Neal, Radford M. (2011), "MCMC Using Hamiltonian Dynamics", Handbook of Markov Chain Monte Carlo, pp. 113-162. URL: http://www.mcmchandbook.net/HandbookChapter5.pdf

`Gen.elliptical_slice`

— Function```
new_trace = elliptical_slice(
trace, addr, mu, cov;
check=false, observations=EmptyChoiceMap())
```

Apply an elliptical slice sampling update to a given random choice with a multivariate normal prior.

Also takes the mean vector and covariance matrix of the prior.

`Gen.@pkern`

— Macro```
@pkern function k(trace, args...;
check=false, observations=EmptyChoiceMap())
...
return trace
end
```

Declare a Julia function as a primitive stationary kernel.

The first argument of the function should be a trace, and the return value of the function should be a `(trace, metadata)`

where `metadata`

is user-provided (but could be useful information, like the result of an accept-reject decision.

There should be keyword arguments check and observations.

`Gen.@kern`

— Macro```
@kern function k(trace, args...)
...
end
```

Construct a composite MCMC kernel.

The resulting object is a Julia function that is annotated as a composite MCMC kernel, and can be called as a Julia function or applied within other composite kernels.

`Gen.@rkern`

— Macro`@rkern k1 : k2`

Declare that two primitive stationary kernels are reversals of one another.

The two kernels must have the same argument type signatures.

`Gen.reversal`

— Function`k2 = reversal(k1)`

Return the reversal kernel for a given kernel.

`Gen.involutive_mcmc`

— Function`(new_trace, accepted) = involutive_mcmc(trace, proposal::GenerativeFunction, proposal_args::Tuple, involution; ..)`

Alias for the involutive form of `metropolis_hastings`

.