New Distribution Stack Overflow

I am currently trying to implement a distribution using the Distributions.jl interface. However, when following the guidelines mentioned here for multivariate distributions (Create New Samplers and Distributions · Distributions.jl) I always end up with a stack overflow and I absolutely cannot figure out why.

Here is a small example:

struct Mean_Shift_Normal <: Sampleable{Multivariate, Continuous}
    shift::Real
    size::Int
end

ms = Mean_Shift_Normal(0.5, 2)

Base.length(s::Mean_Shift_Normal) = s.size

function _rand!(rng::AbstractRNG, s::Mean_Shift_Normal, x::AbstractVector{<:Real})
    z = rand(MvNormal(zeros(s.size), ones(s.size)))
    z = z .+ s.shift
    x .= z
    return x
end  

calling rand(ms) results in a stack overflow.

If anyone has an idea why this is happening or what I am doing wrong, I would appreciate any help.

2 Likes

I tried a bit without success to understand the stack overflow (which BTW doesn’t seem to touch your _rand! ever) and then noticed the documentation for the current version seems to have different interface requirements.

Sorry for the late reply. I think the mistake is actually a rather silly one. If I replace the function with

Distributions._rand!(rng::AbstractRNG, s::Mean_Shift_Normal, x::AbstractVector{<:Real}) = begin
       z = rand(MvNormal(zeros(s.size), ones(s.size)))
       z = z .+ s.shift
       x .= z
       x
end

then everything works fine. Still do not understand though why it is giving me a stack overflow instead of throwing a not implemented error or similar.

3 Likes

Ah, should have thought of that: the same undefined(?) behavior occurs if you try to extend Base functions for example. So you should always either import the function beforehand or specify the module as you did.

Edit: did a quick search and found no direct explanation in the Julia documentation. Does anyone else have a reference at hand?