# Sampler for arbitrary univariate distribution?

**URL:** <https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538>\
**Category:** General Usage\
**Created:** [June 16, 2020, 5:53pm UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538 "2020-06-16T17:53:06Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [June 16, 2020, 5:53pm UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/1 "2020-06-16T17:53:06Z")

</div>

Do we have a sampler for arbitrary univariate distributions implemented somewhere (Ziggurat algorithm or so)?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 17, 2020, 9:11am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/2 "2020-06-17T09:11:08Z")

</div>

Not that I am aware of.

If you have the inverse CDF available, you can just draw a uniform z \sim [0,1] with `rand`, and use F^{-1}(z).

If you only have the CDF, or it is significantly (10–20x times) cheaper than the inverse CDF, you can use a rootfinder to invert it,

[https://github.com/JuliaMath/Roots.jl](https://github.com/JuliaMath/Roots.jl)

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [June 17, 2020, 9:21am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/3 "2020-06-17T09:21:40Z")

</div>

I found [AdaptiveRejectionSampling.jl](https://github.com/mauriciogtec/AdaptiveRejectionSampling.jl), which works fine for my use case - my PDF is actually log-concave, so not fully arbitrary.

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [June 17, 2020, 9:23am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/4 "2020-06-17T09:23:02Z")

</div>

Would be nice to have something like this at some point:

> **[1810.04744.pdf](https://arxiv.org/pdf/1810.04744.pdf)**
>
> 410.44 KB

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 17, 2020, 10:00am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/5 "2020-06-17T10:00:43Z")

</div>

Thanks for the pointer to this very neat paper — it is a nice algorithm, and has a lot of instructive numerical tricks. Implementing something like this in Julia could make a perfect GSOC project for an interested student.

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [June 17, 2020, 11:29am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/6 "2020-06-17T11:29:16Z")

</div>

I agree, that would make for a nice student project. And we should already have all the infrastructure in place to do the necessary analysis (derivate, etc.) on the PDF automatically.

---

<div class="post-metadata">

**Author:** ![\_stla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/_stla/32/35613_2.png) [@\_stla](https://discourse.julialang.org/u/_stla)\
**Post date:** [April 22, 2022, 9:07am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/7 "2022-04-22T09:07:58Z")

</div>

You can use the **ApproxFun** package. It implements the inverse cdf method but with a powerful approximation of the inverse cdf.

```julia
julia> using ApproxFun

julia> f = Fun(x -> exp(-x .^ 2 ./ 2), Interval(1.0, 5.0));
       nsims = 10
10

julia> sample(f, nsims)
10-element Vector{Float64}:
 1.336082989485405
 1.607069776542474
 1.3183351647553678
 1.2442608801899127
 1.9691499351124122
 1.9865874975396451
 1.3504069890433499
 1.2596452654971557
 2.274739748928468
 1.463090656181052

```

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [April 22, 2022, 11:25am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/8 "2022-04-22T11:25:53Z")

</div>

Thanks!

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [April 23, 2022, 9:48am UTC](https://discourse.julialang.org/t/sampler-for-arbitrary-univariate-distribution/41538/9 "2022-04-23T09:48:16Z")

</div>

This `sample` function does not seem to be documented in `ApproxFun` package documentation. How did you find about it?
