Is there a “UniformDraw” distribution in Turing.jl / Distributions.jl, i.e. given an array of element, the distribution selects one of the elements randomly.
Example:
x = [1,10,32,100]
val ~ UniformDraw(x)
val
is then 1, 10, 32, 100 randomly selected.
I can implement it naively like this using DiscreteUniform
(including a version that takes a list of percentages/weights using Categorical
).
"""
Return a normalized vector, i.e. where the sum is 1.
"""
using Turing
function simplex(v)
return v./sum(v)
end
@model function uniformDrawTest(x,pcts=[1,2,3,4])
# Select value uniformly
function uniformDraw(x)
n = length(x)
ix1 ~ DiscreteUniform(1,n)
return x[ix1]
end
# Select a value based on probabilities in pcts
function uniformDraw(x,pcts)
n = length(x)
ix2 ~ Categorical(simplex(pcts))
return x[ix2]
end
val1 ~ Dirac(uniformDraw(x))
val2 ~ Dirac(uniformDraw(x,pcts)
val3 ~ Dirac(uniformDraw(x)) # will be same as val1
end
x = [1,10,32,100]
pcts = [1,2,3,4]
model = uniformDrawTest(x,pcts)
chns = sample(model, PG(15), 10_000)
display(chns)
There are at least two drawbacks with this:
- I have to wrap the result with
Dirac
. - But more seriously is that the indices (
ix1
andix2
) are both global in the model, soval1
andval3
will always be the same value.