GaussianDistributions.jl icon indicating copy to clipboard operation
GaussianDistributions.jl copied to clipboard

Sampling from a dirac delta

Open cstjean opened this issue 7 years ago • 2 comments

I occasionally like having Gaussians with covariance=0 (this is natural, given the formulation in MiniKalman.jl). The math for Kalman filtering works fine, but when sampling I have an issue, which is exacerbated by https://github.com/JuliaArrays/StaticArrays.jl/pull/533:

julia> rand(Gaussian([1.0,2], SDiagonal(0.0,0.0)))   # before StaticArrays#533
2-element Array{Float64,1}:
 1.0
 2.0

julia> rand(Gaussian([1.0,2], Diagonal(SVector(0.0,0.0))))
ERROR: PosDefException: matrix is not positive definite; Cholesky factorization failed.
Stacktrace:
 [1] #cholesky!#127(::Bool, ::Function, ::Diagonal{Float64,MArray{Tuple{2},Float64,1,2}}, ::Val{false}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/LinearAlgebra/src/diagonal.jl:524
 [2] #cholesky#128 at ./none:0 [inlined]
 [3] cholesky at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/LinearAlgebra/src/diagonal.jl:533 [inlined] (repeats 2 times)
 [4] rand(::Random.MersenneTwister, ::Gaussian{Array{Float64,1},Diagonal{Float64,SArray{Tuple{2},Float64,1,2}}}) at /home/cst-jean/.julia/packages/GaussianDistributions/k5dmO/src/GaussianDistributions.jl:82
 [5] rand(::Gaussian{Array{Float64,1},Diagonal{Float64,SArray{Tuple{2},Float64,1,2}}}) at /home/cst-jean/.julia/packages/GaussianDistributions/k5dmO/src/GaussianDistributions.jl:80

cholesky of an all-0 Diagonal matrix fails. I don't know where/if it should be special-cased. Any thought? According to Wikipedia, there can be a cholesky decomposition of a positive semi-definite matrix, but that case doesn't seem to be handled by LinearAlgebra.

cstjean avatar Nov 15 '18 15:11 cstjean

Related to e.g. #27249. There is check=false we can try, but maybe this gives garbage instead of positive semidefinite factors. In the end maybe we have to diverge from Base and provide our own chol wrapper here I think.

mschauer avatar Nov 15 '18 17:11 mschauer

You can of course use PSD and provide PSD(sqrt(Diagonal(v))) but further on you might need to define some methods as +(a::PSD, b::PSD) = PSD(sqrt((a.σ*a.σ') + (b.σ*b.σ')) etc. I think this would have the side effect of implementing the square root Kalman filter...

mschauer avatar Nov 15 '18 18:11 mschauer