-
Notifications
You must be signed in to change notification settings - Fork 429
Open
Description
Distributions.jl/src/product.jl
Lines 239 to 250 in abb151c
""" | |
product_distribution(dists::AbstractVector{<:Normal}) | |
Create a multivariate normal distribution by stacking the univariate normal distributions. | |
The resulting distribution of type [`MvNormal`](@ref) has a diagonal covariance matrix. | |
""" | |
function product_distribution(dists::AbstractVector{<:Normal}) | |
µ = map(mean, dists) | |
σ2 = map(var, dists) | |
return MvNormal(µ, Diagonal(σ2)) | |
end |
product_distribution
on an array of Normals creates a DiagNormal. That's actually quite satisfying to look at, but the original Product is quite substantially faster:
julia> using Distributions, Chairmarks
julia> dists = [Normal(0.0), Normal(1.0), Normal(2.0, 3.0), Normal(4.0, 0.2)];
julia> prod = Product(dists);
julia> mvnorm = product_distribution(dists);
rand
julia> @be rand($prod)
Benchmark: 3556 samples with 805 evaluations
min 23.034 ns (2 allocs: 96 bytes)
median 24.845 ns (2 allocs: 96 bytes)
mean 33.334 ns (2 allocs: 96 bytes, 0.25% gc time)
max 5.135 μs (2 allocs: 96 bytes, 98.75% gc time)
julia> @be rand($mvnorm)
Benchmark: 8044 samples with 260 evaluations
min 32.212 ns (2 allocs: 96 bytes)
median 34.935 ns (2 allocs: 96 bytes)
mean 42.677 ns (2 allocs: 96 bytes, 0.07% gc time)
max 13.362 μs (2 allocs: 96 bytes, 98.83% gc time)
logpdf
julia> x = rand(prod)
4-element Vector{Float64}:
1.7947570646417756
1.050115051070052
-1.0885138050761758
4.265595405348341
julia> @be logpdf($prod, $x)
Benchmark: 3290 samples with 1220 evaluations
min 23.498 ns
median 23.599 ns
mean 23.693 ns
max 44.125 ns
julia> @be logpdf($mvnorm, $x)
Benchmark: 2827 samples with 464 evaluations
min 61.332 ns (2 allocs: 96 bytes)
median 62.409 ns (2 allocs: 96 bytes)
mean 71.665 ns (2 allocs: 96 bytes, 0.14% gc time)
max 9.668 μs (2 allocs: 96 bytes, 98.51% gc time)
Similar performance differences are observed when taking the gradient of logpdf.
Perhaps there are some performance improvements that can be done for DiagNormal
?
repro
(ppl) pkg> st
Status `~/ppl/Project.toml`
[0ca39b1e] Chairmarks v1.3.1
[31c24e10] Distributions v0.25.120
julia> versioninfo()
Julia Version 1.11.5
Commit 760b2e5b739 (2025-04-14 06:53 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: macOS (arm64-apple-darwin24.0.0)
CPU: 10 × Apple M1 Pro
WORD_SIZE: 64
LLVM: libLLVM-16.0.6 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Metadata
Metadata
Assignees
Labels
No labels