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

Added eltype for multivariate distributions #882

Merged
merged 11 commits into from
Jul 11, 2019
Merged

Added eltype for multivariate distributions #882

merged 11 commits into from
Jul 11, 2019

Conversation

theogf
Copy link
Contributor

@theogf theogf commented May 8, 2019

Should solve #813

@mschauer
Copy link
Member

mschauer commented May 8, 2019

This conflates eltype (e.g. Vector{Float64}) with the eltype of the eltype (e.g Float64).

@theogf
Copy link
Contributor Author

theogf commented May 8, 2019

@mschauer So I am not sure what you mean by this, but for MvNormal, multiple functions rely on eltype(d::MvNormal) and it is currently set to a default Float64
I removed the eltype for Multonomial as they were a problem for the tests.

@matbesancon matbesancon requested a review from mschauer May 12, 2019 12:04
@matbesancon
Copy link
Member

@mschauer in that case eltype could be the atomic-most type? Another issue is that what is eltype if the type of the covariance matrix and the mean vector differ?

@theogf
Copy link
Contributor Author

theogf commented May 13, 2019

@mschauer in that case eltype could be the atomic-most type? Another issue is that what is eltype if the type of the covariance matrix and the mean vector differ?

From the constructors it does not seem possible to have different elementary types for the mean and the covariance (also it would not make so much sense).

@matbesancon
Copy link
Member

it would if you are doing Automatic Differentiation on the mean, the covariance would be Float while the mean elements would be Dual

@theogf
Copy link
Contributor Author

theogf commented May 13, 2019

I am not super familiar with the backend of AD but what would be the negative side of having both Dual?

@mschauer
Copy link
Member

I see the interface exists a while but I think if there is need for a function returning the atomic element type it should not be called eltype. In the case your change is "internally consistent" with the current interface we could move this concern to a separate issue though.

@theogf
Copy link
Contributor Author

theogf commented May 14, 2019

eltype is needed since it is called directly by rand, see #894 and #813

@mschauer
Copy link
Member

Then rand calls the wrong function ...

@matbesancon
Copy link
Member

eltype(::Dirichlet{T}) where {T<:Real} = T
@theogf you don't need the type bound here, since by construction a Dirichlet has always T<:Real

@matbesancon
Copy link
Member

@mschauer are you good with fixing this behaviour here? As mentioned modifying the whole interface can go in another issue

@mschauer
Copy link
Member

Ok!

@matbesancon
Copy link
Member

ping @theogf can you merge master into this branch and adapt for the comment I let above?

@theogf
Copy link
Contributor Author

theogf commented Jun 4, 2019

Sorry I am away till next week, I take care of it as soon as I am back.

@rfourquet
Copy link

I'm not familiar with this package, but wanted to note that currently, in Random, the meaning of eltype is extended to mean: for whatever object x (not a type), we must have rand(x) isa eltype(x). So @mschauer comments go in the direction of having Distributions and Random be consistent.

However, we are there is a discussion on whether we should have a function gentype instead of eltype (rand(x) isa gentype(x)), which defaults to eltype (e.g. rand(collection) returns an element of the collection, so eltype makes sense). The idea is that eltype for a distribution is not an ideal name, but more importantly, do we want the possibility of eltype(x) != gentype(x) ? I'm just putting this here in case you want to chime in at JuliaLang/julia#31968 (it would be great!)

@mschauer
Copy link
Member

This needs to be rebased. Could someone chime in with a link to a good explanation?

@matbesancon
Copy link
Member

@mschauer I think this is fine with commit
d2c36fe ?

@mschauer
Copy link
Member

I thought something went wrong because the diff of the branch versus master shows 65 files changed.

@matbesancon
Copy link
Member

ah you're right. @theogf can you from your branch:

  1. merge origin/master
  2. push

This should do it

@codecov-io
Copy link

codecov-io commented Jun 11, 2019

Codecov Report

Merging #882 into master will increase coverage by 0.11%.
The diff coverage is 66.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #882      +/-   ##
==========================================
+ Coverage   76.45%   76.57%   +0.11%     
==========================================
  Files         108      108              
  Lines        5157     5161       +4     
==========================================
+ Hits         3943     3952       +9     
+ Misses       1214     1209       -5
Impacted Files Coverage Δ
src/multivariates.jl 79.03% <ø> (ø) ⬆️
src/multivariate/dirichletmultinomial.jl 98.55% <100%> (ø) ⬆️
src/samplers/gamma.jl 100% <100%> (ø) ⬆️
src/multivariate/mvlognormal.jl 96.82% <100%> (+0.05%) ⬆️
src/multivariate/mvnormalcanon.jl 80.85% <100%> (+0.41%) ⬆️
src/multivariate/dirichlet.jl 59.57% <100%> (+0.21%) ⬆️
src/multivariate/mvnormal.jl 70.65% <100%> (+0.17%) ⬆️
src/multivariate/mvtdist.jl 58.24% <47.05%> (+5.49%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6561a7e...ad4e660. Read the comment docs.

@theogf
Copy link
Contributor Author

theogf commented Jun 11, 2019

Sorry I completely messed up things with git, the force-push should have got rid of my mistakes

@matbesancon
Copy link
Member

no trouble. There seems to be some misses in codecov, can you check if there are things that should be covered?

@matbesancon
Copy link
Member

ping @theogf

@matbesancon matbesancon mentioned this pull request Jun 19, 2019
@theogf
Copy link
Contributor Author

theogf commented Jun 21, 2019

So I wrote some tests, but I quickly started to realize that there are a lot more issues.

  • all GenericMvTDist constructors were restricted to Float64 (this is corrected now).
  • Float16 cannot be tested since there are no PDMat{Float16} constructor for some reason
  • The sampler for GenerivMvTDist make calls to the Gamma samplers but all Gamma structs (GammIPSampler, GammaMTSampler, etc)are also restricted to Float64 components.

Should I just continue pulling the string and parametrize everything until it works?

src/samplers/gamma.jl Outdated Show resolved Hide resolved
src/samplers/gamma.jl Outdated Show resolved Hide resolved
test/types.jl Outdated Show resolved Hide resolved
test/types.jl Outdated Show resolved Hide resolved
src/samplers/gamma.jl Outdated Show resolved Hide resolved
@@ -32,7 +32,10 @@ end

GenericMvTDist(df::Real, μ::Vector{S}, Σ::Cov) where {Cov<:AbstractPDMat, S<:Real} = GenericMvTDist(df, μ, Σ, allzeros(μ))

GenericMvTDist(df::T, Σ::Cov) where {Cov<:AbstractPDMat, T<:Real} = GenericMvTDist(df, zeros(dim(Σ)), Σ, true)
function GenericMvTDist(df::T, Σ::Cov) where {Cov<:AbstractPDMat, T<:Real}
R = Base.promote_eltype(T, Σ)
Copy link
Member

Choose a reason for hiding this comment

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

Are you sure Base.promote_eltype is what's needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think so, we want a promote_type between T and eltype of Σ and T<:Real

@matbesancon
Copy link
Member

A significant amount of code has been added, should there be some additions in the doc? In the tests?

@theogf
Copy link
Contributor Author

theogf commented Jun 21, 2019

Most of the code has been about relaxing the constructors MvTDist to Real variables and to parametrize the Gamma samplers (previously fixed to Float64).
Maybe I should add a line in extends.md to suggest to implement eltype for new distributions.

@matbesancon
Copy link
Member

matbesancon commented Jun 21, 2019 via email

@matbesancon
Copy link
Member

@theogf I'm ok with merging this soon-ish (this week), if you want to add tests before for lines not covered let me know. You can see lines not covered here:
https://codecov.io/gh/JuliaStats/Distributions.jl/compare/432545afd3a29397e2308a99a4978b588676c671...365802f9e4cb438a67adb32b3b1fefe376c7713e/changes

@matbesancon
Copy link
Member

@theogf sorry I let this slept longer than intended, can you merge master into this branch, I'll merge it then

@theogf
Copy link
Contributor Author

theogf commented Jul 10, 2019

@matbesancon Done! Sorry I also did not answer you, I was first confused by the report and ended up forgetting about it!

@matbesancon
Copy link
Member

ok, this should be good in ~1hour. I think the coverage decreased because of the new eltype methods

@matbesancon matbesancon merged commit d876df0 into JuliaStats:master Jul 11, 2019
@matbesancon
Copy link
Member

Thanks @theogf

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.

5 participants