Sampling from ArrayLike sampler without explicit dimensions returns nothing
I have defined an independent multivariate sampler as per the docs:
using Distributions
struct ProductSampler <: Sampleable{Multivariate,Continuous}
rawsampler::Sampleable{Univariate,Continuous}
k::Integer
end
Base.length(s::ProductSampler) = s.k
function Distributions._rand!(rng::Random.AbstractRNG,
ps::ProductSampler, x::AbstractVector{T}) where T<:Real
for i in 1:ps.k; x[i] = Base.rand(rng, ps.rawsampler); end
return nothing
end
I then try it out:
ps = ProductSampler(Uniform(), 2)
rand(ps)
gives nothing, which is not what I expected.
By contrast, rand(ps, 1) yields the expected random uniform vector of length 2.
I then looked up the method that is called:
julia> @which rand(ps)
rand(s::Sampleable, dims::Int64...)
@ Distributions ~/.julia/packages/Distributions/psM3H/src/genericrand.jl:22
One more step back:
@which rand(Distributions.default_rng(), ps)
rand(rng::Random.AbstractRNG, s::Sampleable{<:ArrayLikeVariate, Continuous})
@ Distributions ~/.julia/packages/Distributions/psM3H/src/genericrand.jl:47
which looks like it wrongly does an in-place update without returning a value:
# these are workarounds for sampleables that incorrectly base `eltype` on the parameters
function rand(rng::AbstractRNG, s::Sampleable{<:ArrayLikeVariate,Continuous})
return rand!(rng, sampler(s), Array{float(eltype(s))}(undef, size(s)))
end
Is this a bug?
Seems to be a bug, either in the docs or the implementation. Possibly fixed by #1905.
Regarding the docs here, what I found unclear is in what namespace I have to add methods. By trial and error I found what worked was to extend Random.rand for univariate and Distributions._rand! for multivariate samplers.