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.
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
""" 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
- But more seriously is that the indices (
ix2) are both global in the model, so
val3will always be the same value.