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

fix type stability of sampling from Chisq, TDist, Gamma #1885

Merged
merged 12 commits into from
Aug 23, 2024

Conversation

Red-Portal
Copy link
Contributor

This addresses #1884

@codecov-commenter
Copy link

codecov-commenter commented Aug 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 85.99%. Comparing base (13029c0) to head (2091cd7).
Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1885   +/-   ##
=======================================
  Coverage   85.99%   85.99%           
=======================================
  Files         144      144           
  Lines        8666     8666           
=======================================
  Hits         7452     7452           
  Misses       1214     1214           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@quildtide
Copy link
Contributor

Should probably add method eltype(d::Gamma) = partype(d) and friends.

There are many side effects associated with changing Gamma. The following list is not exhaustive, but I think they will be impacted:

  • Beta
  • BetaPrime
  • InverseGamma
  • Chi

Chisq will have some side effects too, e.g.:

  • FDist

@Red-Portal
Copy link
Contributor Author

Hi @quildtide ,

Okay so to be precise, I'll do the following:

  • Identify all the distributions that are affected by sampling Gammas. If the type of the sampled gamma affects the type of the final sample, add eltype = partype
  • Add tests for the type stability

Would that be sufficient?

@quildtide
Copy link
Contributor

Not a maintainer, so don't take my word for granted. If the route this pull request takes is chosen, then the things you propose doing would indeed be a good idea.

Beta has two sampling paths, IIRC, where it sometimes uses a Gamma sampler, and sometimes uses a different sampler, so you will probably need to alter the other path too, if the Gamma path is returning partype values now (I think it is).


I know that some of the maintainers have pushed back to some degree in the past on making eltype == partype for Distributions that aren't already doing that (Normal and a few friends), but @devmotion seems to be calling the shots right now, and he seems to back the core idea of this pull req for TDist.

src/univariate/continuous/tdist.jl Outdated Show resolved Hide resolved
@@ -105,7 +105,7 @@ cf(d::Exponential, t::Real) = 1/(1 - t * im * scale(d))


#### Sampling
rand(rng::AbstractRNG, d::Exponential) = xval(d, randexp(rng))
rand(rng::AbstractRNG, d::Exponential{T}) where {T} = xval(d, randexp(rng, T))
Copy link
Member

Choose a reason for hiding this comment

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

This is a slightly different case and easily broken (e.g., when T is not a floating point number type). In the TDist and Gamma case we just try to avoid promotions of a sample from another rand call, whereas this case goes deeper into the question of how rand should behave wrt parameters etc. (see also #1433 (comment)).

Suggested change
rand(rng::AbstractRNG, d::Exponential{T}) where {T} = xval(d, randexp(rng, T))
rand(rng::AbstractRNG, d::Exponential) = xval(d, randexp(rng))

Copy link
Contributor Author

@Red-Portal Red-Portal Aug 18, 2024

Choose a reason for hiding this comment

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

If we do this though, the return type of rand(Gamma(Float32, Float32)) changes depending on the value of the shape parameter because shape == 1 samples from Exponential. (This is why the tests are currently failing.) Should we let this happen? I imagine some people will be super surprised by such behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @devmotion could you comment on this?

Copy link
Member

Choose a reason for hiding this comment

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

That's a good point. I didn't realize that GammaMTSampler already respects the parameter types (but samples are not necessarily of the parameter type:

d = shape(g) - 1//3
c = inv(3 * sqrt(d))
# Pre-compute scaling factor
κ = d * scale(g)
# We also pre-compute the factor in the squeeze function
return GammaMTSampler(promote(d, c, κ, 331//10_000)...)
).

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 that's an argument for using the same approach as for Normal here, until we move to a better/different API:

Suggested change
rand(rng::AbstractRNG, d::Exponential{T}) where {T} = xval(d, randexp(rng, T))
rand(rng::AbstractRNG, d::Exponential{T}) where {T} = xval(d, randexp(rng, float(T)))

test/univariate/continuous/chisq.jl Outdated Show resolved Hide resolved
@Red-Portal Red-Portal requested a review from devmotion August 18, 2024 00:15
@Red-Portal Red-Portal requested a review from devmotion August 22, 2024 23:48
Copy link
Member

@devmotion devmotion left a comment

Choose a reason for hiding this comment

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

Can you also add a test for Exponential?

test/univariate/continuous/gamma.jl Outdated Show resolved Hide resolved
test/univariate/continuous/tdist.jl Outdated Show resolved Hide resolved
@Red-Portal
Copy link
Contributor Author

Red-Portal commented Aug 23, 2024

  • I also added back the type stability tests for Chisq since we now know that the gamma samplers respect the parameter type.
  • I removed the type stability test for Entropy(TDist) because it is not type stable (it returns Union{Float32, Float64}) because $\nu = \mathrm{Inf}$ returns entropy(Normal), which is also not type stable.

@Red-Portal Red-Portal requested a review from devmotion August 23, 2024 18:57
@devmotion devmotion merged commit 3946acc into JuliaStats:master Aug 23, 2024
11 checks passed
quildtide added a commit to quildtide/Distributions.jl that referenced this pull request Sep 4, 2024
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.

4 participants