Required methods to sample a multivariate distribution


I have a question, maybe you can answer me.

Following this Distributions.jl documentation, when I define a multivariate distribution, I implement the two functions :

function Distributions._rand!(rng::Distributions.AbstractRNG, X::MyDistribution, x::AbstractVector{T}) where {T}
     x .= #something
     return x
function Base.rand(rng::Distributions.AbstractRNG,X::MyDistribution)
     x = zeros(length(X)) #allocate
     x .= #something, in fact exactly the same something as the previous function. 
     return x

I remember that a while ago both were needed, and now it simply became an habit. But:

  1. First, I cannot recall why both interfaces would be needed, would you by chance point me to the right place ?
  2. Then, I define a lot of distributions, and I wander if I cannot just use one method for the second function as:
function Base.rand(rng::Distributions.AbstractRNG,X<:MyAbstractDistributionFamilly)
     x = zeros(length(X)) #allocate

and then only define the Distributions._rand!(..) version for each subtype.

Edit: This might be related: `Base.rand` but `Random.rand!`?

According to a thread on Slack with @Sukera and @Andy Dienes, the situation is as follows:

  • Distributions.rand === Random.rand === Base.rand
  • Random.rand’s API and Distributions._rand!'s API are conflicting with each other and incompatible.

Thus, keeping only the DIstributions._rand! looks like it is enough, and everything else can be ditched. At least for the moment.