Probability Distributions

## Built-In Distributions

``bernoulli(prob_true::Real)``

Samples a `Bool` value which is true with given probability

source
``normal(mu::Real, std::Real)``

Samples a `Float64` value from a normal distribution.

source
``mvnormal(mu::AbstractVector{T}, cov::AbstractMatrix{U}} where {T<:Real,U<:Real}``

Samples a `Vector{Float64}` value from a multivariate normal distribution.

source
``gamma(shape::Real, scale::Real)``

Sample a `Float64` from a gamma distribution.

source
``inv_gamma(shape::Real, scale::Real)``

Sample a `Float64` from a inverse gamma distribution.

source
``beta(alpha::Real, beta::Real)``

Sample a `Float64` from a beta distribution.

source
``categorical(probs::AbstractArray{U, 1}) where {U <: Real}``

Given a vector of probabilities `probs` where `sum(probs) = 1`, sample an `Int` `i` from the set {1, 2, .., `length(probs)`} with probability `probs[i]`.

source
``uniform(low::Real, high::Real)``

Sample a `Float64` from the uniform distribution on the interval [low, high].

source
``uniform_discrete(low::Integer, high::Integer)``

Sample an `Int` from the uniform distribution on the set {low, low + 1, ..., high-1, high}.

source
``poisson(lambda::Real)``

Sample an `Int` from the Poisson distribution with rate `lambda`.

source
``piecewise_uniform(bounds, probs)``

Samples a `Float64` value from a piecewise uniform continuous distribution.

There are `n` bins where `n = length(probs)` and `n + 1 = length(bounds)`. Bounds must satisfy `bounds[i] < bounds[i+1]` for all `i`. The probability density at `x` is zero if `x <= bounds[1]` or `x >= bounds[end]` and is otherwise `probs[bin] / (bounds[bin] - bounds[bin+1])` where `bounds[bin] < x <= bounds[bin+1]`.

source
``beta_uniform(theta::Real, alpha::Real, beta::Real)``

Samples a `Float64` value from a mixture of a uniform distribution on [0, 1] with probability `1-theta` and a beta distribution with parameters `alpha` and `beta` with probability `theta`.

source

## Defining New Distributions

Probability distributions are singleton types whose supertype is `Distribution{T}`, where `T` indicates the data type of the random sample.

``abstract type Distribution{T} end``

By convention, distributions have a global constant lower-case name for the singleton value. For example:

``````struct Bernoulli <: Distribution{Bool} end
const bernoulli = Bernoulli()``````

Distributions must implement two methods, `random` and `logpdf`.

`random` returns a random sample from the distribution:

``````x::Bool = random(bernoulli, 0.5)
x::Bool = random(Bernoulli(), 0.5)``````

`logpdf` returns the log probability (density) of the distribution at a given value:

``````logpdf(bernoulli, false, 0.5)
logpdf(Bernoulli(), false, 0.5)``````

Distribution values should also be callable, which is a syntactic sugar with the same behavior of calling `random`:

``bernoulli(0.5) # identical to random(bernoulli, 0.5) and random(Bernoulli(), 0.5)``

A new Distribution type must implement the following methods:

``val::T = random(dist::Distribution{T}, args...)``

Sample a random choice from the given distribution with the given arguments.

source
``lpdf = logpdf(dist::Distribution{T}, value::T, args...)``

Evaluate the log probability (density) of the value.

source
``has::Bool = has_output_grad(dist::Distribution)``

Return true of the gradient if the distribution computes the gradient of the logpdf with respect to the value of the random choice.

source
``grads::Tuple = logpdf_grad(dist::Distribution{T}, value::T, args...)``

Compute the gradient of the logpdf with respect to the value, and each of the arguments.

If `has_output_grad` returns false, then the first element of the returned tuple is `nothing`. Otherwise, the first element of the tuple is the gradient with respect to the value. If the return value of `has_argument_grads` has a false value for at position `i`, then the `i+1`th element of the returned tuple has value `nothing`. Otherwise, this element contains the gradient with respect to the `i`th argument.

source

A new Distribution type must also implement `has_argument_grads`.