Complex Uniform Distribution between 1+0im and 2+0im

I am trying to extend Uniform so rand can generate random numbers for Complex types (to test IntelVectorMath library for Complex types)

# zeros like syntax
function Distributions.Uniform(::Type{T}, a, b) where {T <: Real}
    return Uniform(T(a), T(b))
end

# Complex support
function Distributions.Uniform(T::Type{Complex{P}}, a, b) where {P}
    aR, aI =reim(T(a))
    bR, bI =reim(T(b))
    if aR == bR
        outR = P(0) #?? Ask about this
    else
        outR = Uniform(P, min(aR,bR), max(aR,bR))
    end
    if aI == bI
        outI = P(0)  #?? Ask about this
    else
        outI = Uniform(P, min(aI,bI), max(aI,bI))
    end
    return complex(outR, outI)
end

# doesn't work:
Uniform(Complex{Float64},1,2)

The problem arises when a and b are equal. In literature, the probability is 0. However, in Julia’s implementation, it is not apparent that when we define Unifrom(a,b), is it a [a, b] or (a,b).

If it is [a, b] then Uniform(a, a) should always give a
if is is (a, b) then Uniform(a, a) should give a constant 0 distribution that rand always gives some null situation.

My implementation is faulty, but I can’t find anything in Distributions doc anything about Complex types. Probably it should be a multi-dimensional distribution.

Here is my opinion on the issue.

Uniform(a, b) as per the docs returns [a, b] but demands that a < b. I feel like this should stay.

We should introduce a new distribution d = Singleton{X} that rand(d) returns the constant X. Then the product measure defined by OP will work as intended. This notation is used in https://github.com/MikeInnes/Poirot.jl .

Last, we should resolve https://github.com/JuliaStats/Distributions.jl/issues/142 and Ill like to hijack the issue and say that generic convolution should also work.

1 Like

I updated OP. We also need extend complex() so it can get Distributions types.

Another issue that is related is my problem with the Uniform definition and its API. I talked about it here:

I created a PR to solve it here:


From the mathematical point of view, a and b bounds may not be part of the distribution and so their type shouldn’t be part of the Distribution definition. Actually their probability is equal to 0!

Having probability 0 does not mean it does not occur. Either definition is self-consistent.

To see this more clearly, the probability for any value on an interval [a, b] gets returned by a uniform random distribution on it is 0.

3 Likes

I imagine that the problem arises before this: since complex numbers have no canonical ordering, it’s hard to make sense of a < x < b. Commonly, complex uniform distributions are defined over unit circles.

As for the problem of singular/meaningless parameters: I think it is preferable if constructors simply error, instead of doing something clever. Currently

julia> Uniform(0,0)
ERROR: ArgumentError: Uniform: the condition a < b is not satisfied.

which is fine, but

julia> Normal(1, 0)
Normal{Float64}(μ=1.0, σ=0.0)
3 Likes

I think the reason why Uniform does not permit a = b is due to the docs being written as

  Uniform(a,b)

  The continuous uniform distribution over an interval [a, b] has probability
  density function

f(x; a, b) = \frac{1}{b - a}, \quad a \le x \le b

which would imply that a \neq b due to the division by 0. But returning the Singleton as described in my first reply is perfectly sensible to, with some rewriting of the docs.

No, it would be type unstable. While the compiler can handle this to a limited extent, it is not good design without a compelling reason.

Also, it is a convention for T constructors to return T objects — this is not enforced, but it is not good style to violate this.

1 Like

You’re right I didn’t think this through in that direction.

1 Like