Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove constraint on AbstractPDMat #1552

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

oxinabox
Copy link
Contributor

@oxinabox oxinabox commented May 18, 2022

Closes #1219
Tests it works by using BlockDiagonals.jl

Basic philosophy:

  • Anything that worked with PDMats before should be just as fast
  • Anything that didn't work before should be correct, but might be slower
    • (e.g. we might recompute the cholesky everytime rand is called)

TODO

@devmotion
Copy link
Member

I think it would be great if it would be possible to use different matrices and types as covariance matrices.

I'm not happy about the added complexity in Distributions though and think there should be a better way to handle this. In particular, I think that similar generalizations are also desirable in other scenarios where currently AbstractPDMats are required.

Maybe we could instead add these fallbacks of invquad, invquad!, unwhiten! etc. for AbstractMatrix to PDMats instead? And then only loosen the restrictions in the types of e.g. MvNormal in Distributions?

@oxinabox
Copy link
Contributor Author

oxinabox commented May 18, 2022

I think that would make sense.
It also would make it easier for other matrix packages to overload them.

One issue is I have no interest in implementing all of them, just like these 3, which is all we need for MvNormal.

@andreasnoack what do you think. Would such a PR be welcomed to PDMats.jl?

I would still want to add these test types here.


One thing I have shown here right now is the code changes are not hard or deep.
Just a few operations.
This is much easier than creating the work arounds.

@oxinabox oxinabox changed the title WIP remove constraint on AbstractPDMat Remove constraint on AbstractPDMat May 19, 2022
@oxinabox
Copy link
Contributor Author

This should now be good to go.

@devmotion
Copy link
Member

I started the registration process for PDMats 0.11.11: JuliaRegistries/General#61420 Let's rerun tests when it's available.

src/multivariate/mvnormal.jl Outdated Show resolved Hide resolved
src/multivariate/mvnormal.jl Outdated Show resolved Hide resolved

function MvNormal(μ::AbstractVector{T}, Σ) where T
MvNormal{T, typeof(Σ), typeof(μ)}(μ, Σ)
end
function MvNormal(μ::AbstractVector{<:Real}, Σ::AbstractPDMat{<:Real})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess here we might want to change it to

Suggested change
function MvNormal::AbstractVector{<:Real}, Σ::AbstractPDMat{<:Real})
function MvNormal::AbstractVector{<:Real}, Σ::AbstractMatrix{<:Real})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests pass, right now.
It took some effort to make sure the constructors cover the right cases and don't stackoverflow, or ambiguity error.
I could go and give them another pass over now that it is working, but I wouldn't want to just go and relax the ones there right now whily-nilly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think without this relaxation you can provoke a test error when you use something like MvNormal(::Vector{Float32}, ::BlockDiagonal{Float64}).

Comment on lines +200 to +202
μc = convert(AbstractArray{R}, μ)
Σc = convert(AbstractArray{R}, Σ)
MvNormal{R, typeof(Σc), typeof(μc)}(μc, Σc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not needed it seems, is it?

Suggested change
μc = convert(AbstractArray{R}, μ)
Σc = convert(AbstractArray{R}, Σ)
MvNormal{R, typeof(Σc), typeof(μc)}(μc, Σc)
MvNormal(convert(AbstractArray{R}, μ), convert(AbstractArray{R}, Σ))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is so we can call the parameterized constructor.
Otherwise we get a stackoverflow.

src/multivariate/mvnormal.jl Outdated Show resolved Hide resolved
end

function MvNormalCanon(μ::AbstractVector{T}, h::AbstractVector{T}, J::AbstractPDMat) where {T<:Real}
function MvNormalCanon(μ::AbstractVector{T}, h::AbstractVector{T}, J::P) where {T<:Real, P}
Copy link
Member

@devmotion devmotion May 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function MvNormalCanon::AbstractVector{T}, h::AbstractVector{T}, J::P) where {T<:Real, P}
function MvNormalCanon::AbstractVector{T}, h::AbstractVector{T}, J::AbstractMatrix{T}) where {T<:Real}

end
end

function MvNormalCanon(μ::AbstractVector{T}, h::AbstractVector{T}, J::AbstractPDMat) where {T<:Real}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we want to keep this function but change J::AbstractPDMat to J::AbstractMatrix{<:Real}.

R = promote_type(T, eltype(J))
MvNormalCanon(convert(AbstractArray{R}, μ), convert(AbstractArray{R}, h), convert(AbstractArray{R}, J))
MvNormalCanon{T,P,typeof(μ)}(convert(AbstractArray{R}, μ), convert(AbstractArray{R}, h), convert(AbstractArray{R}, J))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the old function here (relaxed to AbstractMatrix, see above):

Suggested change
MvNormalCanon{T,P,typeof(μ)}(convert(AbstractArray{R}, μ), convert(AbstractArray{R}, h), convert(AbstractArray{R}, J))
MvNormalCanon(convert(AbstractArray{R}, μ), convert(AbstractArray{R}, h), convert(AbstractArray{R}, J))

src/multivariate/mvnormalcanon.jl Outdated Show resolved Hide resolved
src/multivariate/mvnormalcanon.jl Outdated Show resolved Hide resolved
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AbstractPDMat restriction causes problems
2 participants