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

rand(dist) does not consistently honor the element type of dist #1071

Open
vargonis opened this issue Feb 20, 2020 · 11 comments · May be fixed by #1905
Open

rand(dist) does not consistently honor the element type of dist #1071

vargonis opened this issue Feb 20, 2020 · 11 comments · May be fixed by #1905

Comments

@vargonis
Copy link

One has

julia> typeof(rand(Uniform{Float32}(0f0,1f0)))
Float64

Similar inconsistencies occurs with Exponential and Gamma, although not with Normal. Relatedly:

julia> eltype(Uniform{Float32}(0f0,1f0))
Float64

This is rather easy to fix. I've already taken care of the few cases that are currently producing errors in my code---take a look here. However, this is not complete and does not merit a PR.

@andreasnoack
Copy link
Member

It's Normal that is the odd one out here. The element type of a distribution specifies the type of the parameters, not the type of the variates produced by rand. See #1045 (comment)

@vargonis
Copy link
Author

vargonis commented Feb 20, 2020 via email

@andreasnoack
Copy link
Member

The overhead I'm referring to is overhead for the programmer. The complexity of managing your methods grows a lot in the number of type parameters that you have to support. Drawing Float32 variates is, of course, a reasonable use case but the question is how to support it. It could be as part of the distribution type or it could be part of the rand method. I suspect that the latter might be a simpler solution.

@vargonis
Copy link
Author

By the way, I just realized that there's the ValueSupport type which can be either Int or Float64. So, here I'm really colliding with the limitations of Distributions' design... :/

@andreasnoack
Copy link
Member

The original design of Distributions was ended up being too strict as it only allowed parameters and variates to be either Int or Float64. To support automatic differentiation, we've moved towards making most distributions parametric to allow the parameters to be dual numbers. We might need further adjustments of the design to handle e.g. GPU cases. We have also had discussions about simplifying the rich abstract type tree used in Distributions as it doesn't help much and is sometimes a problem, see e.g. the discussion of the empirical distribution.

@vargonis
Copy link
Author

Looking forward to see the new design! I do hope it will allow for distributions with arbitrary support. Having just Int and Float64 is annoyingly limiting.

@richardreeve
Copy link
Contributor

This was solved by #951 before I stopped working on it by imputing return type from parameter type where appropriate. It had been an ongoing bugbear of mine, but it didn't seem high on other people's priority lists... it seems like the kind of thing that should be fixed somehow before a v1.0 release at any rate.

@ztangent
Copy link

ztangent commented Jun 3, 2021

This is still an issue vis a vis Dirichlet and Normal, see discussion in #1338 .

@ParadaCarleton
Copy link
Contributor

ParadaCarleton commented Sep 8, 2023

This was solved by #951 before I stopped working on it by imputing return type from parameter type where appropriate. It had been an ongoing bugbear of mine, but it didn't seem high on other people's priority lists... it seems like the kind of thing that should be fixed somehow before a v1.0 release at any rate.

I don't know how we want to define eltype, but I do think we need to settle on a single consistent definition and enforce it.

@ParadaCarleton
Copy link
Contributor

ParadaCarleton commented Oct 23, 2023

I'd like to ask for a decision on this again; besides ruling out GPU support, machine learning applications, compatibility with other packages (which try to preserve types), and precisions other than 64 bits, it seems like the inconsistent behavior of rand and eltype makes property-based testing substantially harder.

@dpaetzel
Copy link

dpaetzel commented Jul 18, 2024

Is there any progress on this or maybe a way to help to get this resolved?

To add to this (I've read many but not all of the linked issues so far), the current behaviour breaks the promise from the standard library that rand!(rng, A, S) is the same as copyto!(A, rand(rng, S, size(A))) but for the allocation of an additional array.

Compare:

julia> using Random
julia> using Distributions
julia> T = Float32
julia> n = 3
julia> dist = Uniform{T}(zero(T), one(T))
julia> A = Vector{T}(undef, n)
julia> rand!(Random.Xoshiro(1), dist, A)
julia> B = Vector{T}(undef, n)
julia> copyto!(B, rand(Random.Xoshiro(1), dist, n))
julia> print(A == B)
false

(I guess it doesn't make much sense to open another issue for this inconsistency which is highly likely caused by the other problems with the return types?)

Thank you for putting so much work into this library! 🙂

EDIT: For context: I want to be able to memory map large arrays to save some RAM but in order to do that I have to use rand! to write into the memory-mapped array. At the same time, I need random number generation to be reproducible. Right now, this does not work as expected due to above problem.

EDIT': Of course I can work around this, just wanted to point out the inconsistency with the standard lib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants