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

Making DiagNormal and friends less restrictive, removing Float64 restriction

Open oschulz opened this issue 3 years ago • 4 comments

Currently, we have

const DiagNormal = MvNormal{Float64, PDiagMat{Float64,Vector{Float64}}, Vector{Float64}}

This is quite restrictive, it results in

julia> d = MvNormal(fill(0.0f1, 5), Diagonal(fill(1.0f0, 5)))

julia> d.Σ isa PDiagMat
true

julia> d isa DiagNormal
false

We just ran into the same with dual numbers - a diagonal MvNormal of Float64 is a DiagNormal, but an MvNormal of ForwardDiff.Dual of Float64 is not.

This is relevant since some methods in "mvnormal.jl" are specialized for DiagNormal.

IsoNormal and FullNormal are also limited to Float64, currently. Can we just define

const IsoNormal  = MvNormal{<:Real,ScalMat{<:Real},Vector{<:Real}}
const DiagNormal = MvNormal{<:Real,PDiagMat{<:Real,Vector{<:Real}},Vector{<:Real}}
const FullNormal = MvNormal{<:Real,PDMat{<:Real,Matrix{<:Real}},Vector{<:Real}}

const ZeroMeanIsoNormal{Axes}  = MvNormal{<:Real,ScalMat{<:Real},Zeros{<:Real,1,Axes}}
const ZeroMeanDiagNormal{Axes} = MvNormal{<:Real,PDiagMat{<:Real,Vector{<:Real}},Zeros{<:Real,1,Axes}}
const ZeroMeanFullNormal{Axes} = MvNormal{<:Real,PDMat{<:Real,Matrix{<:Real}},Zeros{<:Real,1,Axes}}

?

oschulz avatar Jan 23 '22 15:01 oschulz

This would make the types non-concrete, I think it might be better to define

const IsoNormal{T<:Real} = MvNormal{T,ScalMat{T},Vector{T}}

etc. Unfortunately, in any case it would be a breaking change (e.g., dispatches on SomeType{IsoNormal} would break).

devmotion avatar Jan 23 '22 15:01 devmotion

Unfortunately, in any case it would be a breaking change

Argh, yes ...

So maybe we change the specializations in "mvnormal.jl" to use things like MvNormal{<:Real,ScalMat{<:Real},Vector{<:Real}} directly, for now?

oschulz avatar Jan 24 '22 08:01 oschulz

Yes, that could be done. Might be a bit more convenient though to define and work with the more general type aliases (AbstractIsoNormal{T} etc. maybe?) and define the existing aliases as special cases (eg const IsoNormal = AbstractIsoNormal{Float64}).

devmotion avatar Jan 24 '22 10:01 devmotion

Yes, that sounds good!

oschulz avatar Jan 24 '22 10:01 oschulz