PartitionedDistributions
PartitionedDistributions provides functionality for partitioning the variables of Distributions.jl's distributions into blocks and computing the associated conditional and marginal distributions.
PartitionedDistributions.conditionalPartitionedDistributions.marginalPartitionedDistributions.pointwise_conditional_logpdfsPartitionedDistributions.pointwise_conditional_logpdfs!!
PartitionedDistributions.marginal — Function
marginal(dist, keep_indices...)Return the marginal distribution of dist at the indices keep_indices.
keep_indices must index into any point in the support of dist.
See also: conditional
Examples
julia> using Distributions, InvertedIndices, PartitionedDistributions
julia> dist = MvNormal([1.0, 2.0, 3.0], [1.0 0.5 0.25; 0.5 1.0 0.5; 0.25 0.5 1.0]);
julia> marginal(dist, 1) # specify index to keep
Normal{Float64}(μ=1.0, σ=1.0)
julia> marginal(dist, [1, 3]) # specify indices to keep
MvNormal{Float64, PDMats.PDMat{Float64, Matrix{Float64}}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}(
dim: 2
μ: [1.0, 3.0]
Σ: [1.0 0.25; 0.25 1.0]
)
julia> marginal(dist, Not(2)) # alternatively, specify index to marginalize over
MvNormal{Float64, PDMats.PDMat{Float64, Matrix{Float64}}, SubArray{Float64, 1, Vector{Float64}, Tuple{Vector{Int64}}, false}}(
dim: 2
μ: [1.0, 3.0]
Σ: [1.0 0.25; 0.25 1.0]
)For a ProductNamedTupleDistribution, we can additionally provide a NamedTuple of indices to keep.
julia> d = product_distribution((x=MvNormal([0.0, 0.0], [1.0 0.5; 0.5 1.0]), y=Normal()));
julia> marginal(d, (; x=2))
ProductNamedTupleDistribution{(:x,)}(
x: Normal{Float64}(μ=0.0, σ=1.0)
)PartitionedDistributions.conditional — Function
conditional(dist, x, keep_indices...)Return the distribution of dist at the indices keep_indices conditioned on the elements of x not at x[keep_indices...].
x must be in the support of dist, and keep_indices must index into any point in the support of dist.
See also: marginal
Examples
By providing a single index, we can compute the univariate distribution of a single element of a multivariate normal distribution conditioned on the other element(s).
julia> using Distributions, InvertedIndices, PartitionedDistributions
julia> dist = MvNormal([1.0, 2.0], [1.0 0.5; 0.5 1.0]);
julia> conditional(dist, [1.0, 2.0], 1) # specify index to keep
Normal{Float64}(μ=1.0, σ=0.8660254037844386)
julia> conditional(dist, [1.0, 2.0], 1:1) # specify indices to keep
FullNormal(
dim: 1
μ: [1.0]
Σ: [0.75;;]
)
julia> conditional(dist, [1.0, 2.0], Not(2)) # alternatively, specify index to condition on
FullNormal(
dim: 1
μ: [1.0]
Σ: [0.75;;]
)For a ProductNamedTupleDistribution, we can additionally provide a NamedTuple of indices to keep.
julia> d = product_distribution((x=MvNormal([0.0, 0.0], [1.0 0.5; 0.5 1.0]), y=Normal()));
julia> obs = (x=[0.1, 0.2], y=0.3);
julia> conditional(d, obs, (; x=2))
ProductNamedTupleDistribution{(:x,)}(
x: Normal{Float64}(μ=0.05, σ=0.8660254037844386)
)PartitionedDistributions.pointwise_conditional_logpdfs — Function
pointwise_conditional_logpdfs(dist, x) -> logpCompute pointwise conditional log-PDF of x for a given distribution.
Returns a collection with the same structure as x where each scalar is the log-PDF of the distribution conditioned on all other elements of x and evaluated only on the corresponding element of x.
For array-variate distributions, this is equivalent to
[logpdf(conditional(dist, x, i), x[i]) for i in LinearIndices(x)]but is generally much more efficient.
See pointwise_conditional_logpdfs!! for a maybe-in-place version.
See also: conditional
Examples
Here's an example with a multivariate normal distribution:
julia> using Distributions, PartitionedDistributions
julia> dist = MvNormal([ 0.8, -0.9], [1.3 0.7; 0.7 0.5]);
julia> x = [2.9, 0.4];
julia> pointwise_conditional_logpdfs(dist, x)
2-element Vector{Float64}:
-0.47172139161049054
0.012188177057073202Here's an example with a NamedTuple-variate distribution:
julia> nt_dist = product_distribution((x = dist, y = Normal()));
julia> z = (; x, y=0.7)
(x = [2.9, 0.4], y = 0.7)
julia> pointwise_conditional_logpdfs(nt_dist, z)
(x = [-0.47172139161049054, 0.012188177057073202], y = -1.1639385332046728)PartitionedDistributions.pointwise_conditional_logpdfs!! — Function
pointwise_conditional_logpdfs!!(logp, dist, x) -> logpdfsMaybe-in-place version of pointwise_conditional_logpdfs.
If all scalar values in logp can be mutated, then logp is filled in-place and returned. Otherwise, a new collection is returned.