# Turing.jl: UniformDraw distribution?

**URL:** https://discourse.julialang.org/t/turing-jl-uniformdraw-distribution/65123
**Category:** Probabilistic Programming
**Tags:** turing, distributions
**Created:** [July 22, 2021, 4:59pm UTC](https://discourse.julialang.org/t/turing-jl-uniformdraw-distribution/65123 "2021-07-22T16:59:44Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Hakan\_Kjellerstrand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hakan_kjellerstrand/32/8447_2.png) [@Hakan\_Kjellerstrand](https://discourse.julialang.org/u/Hakan_Kjellerstrand)
#### Post date: [July 22, 2021, 4:59pm UTC](https://discourse.julialang.org/t/turing-jl-uniformdraw-distribution/65123/1 "2021-07-22T16:59:44Z")

</div>

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:

```julia
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`).

```julia
"""
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` and `ix2`) are both global in the model, so `val1` and `val3` will always be the same value.

---

<div class="post-metadata">

### Author: ![torfjelde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torfjelde/32/206542_2.png) [@torfjelde](https://discourse.julialang.org/u/torfjelde)
#### Post date: [July 22, 2021, 10:50pm UTC](https://discourse.julialang.org/t/turing-jl-uniformdraw-distribution/65123/2 "2021-07-22T22:50:29Z")

</div>

It’s already available in Distributions.jl as [`DiscreteNonParametric`](https://juliastats.org/Distributions.jl/stable/univariate/#Distributions.DiscreteUniform) 🙂

```julia
julia> using Distributions

julia> d = DiscreteNonParametric([1,10,32,100], ones(4) ./ 4);

julia> rand(d)
32

julia> rand(d)
32

julia> rand(d)
100

julia> rand(d)
100

julia> rand(d)
10

julia> logpdf(d, 10)
-1.3862943611198906

julia> logpdf(d, 100)
-1.3862943611198906

```

If you want, you can define the following constructor:

```julia
julia> UniformDraw(xs) = DiscreteNonParametric(xs, ones(length(xs)) ./ length(xs))
UniformDraw (generic function with 1 method)

julia> d = UniformDraw([1,10,32,100])
DiscreteNonParametric{Int64, Float64, Vector{Int64}, Vector{Float64}}(support=[1, 10, 32, 100], p=[0.25, 0.25, 0.25, 0.25])

julia> rand(d)
1

```

---

<div class="post-metadata">

### Author: ![Hakan\_Kjellerstrand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hakan_kjellerstrand/32/8447_2.png) [@Hakan\_Kjellerstrand](https://discourse.julialang.org/u/Hakan_Kjellerstrand)
#### Post date: [July 23, 2021, 4:55am UTC](https://discourse.julialang.org/t/turing-jl-uniformdraw-distribution/65123/3 "2021-07-23T04:55:20Z")

</div>

Thanks @torfjelde !

That was exactly what I looked for. (I must have search in an old Distribution documentation.)
