# Generate next random value based on a given statistical distribution in julia?

**URL:** <https://discourse.julialang.org/t/generate-next-random-value-based-on-a-given-statistical-distribution-in-julia/22872>\
**Category:** General Usage\
**Created:** [April 7, 2019, 2:17pm UTC](https://discourse.julialang.org/t/generate-next-random-value-based-on-a-given-statistical-distribution-in-julia/22872 "2019-04-07T14:17:11Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![bsnyh](https://avatars.discourse-cdn.com/v4/letter/b/ce7236/32.png) [@bsnyh](https://discourse.julialang.org/u/bsnyh)\
**Post date:** [April 7, 2019, 2:17pm UTC](https://discourse.julialang.org/t/generate-next-random-value-based-on-a-given-statistical-distribution-in-julia/22872/1 "2019-04-07T14:17:11Z")

</div>

```julia
mutable struct DistrRng{T<:Sampleable}
	d::T
	rng::MersenneTwister

	function DistrRng(d::T, rng::MersenneTwister) where T <: Sampleable
		return new{T}(d, deepcopy(rng))
	end
	function DistrRng(d::T; seed::Int = nullIndex) where T <: Sampleable
		rng = (seed >= 0 ? MersenneTwister(seed) : MersenneTwister(rand(UInt32)))
		return new{T}(d, rng)
	end
end

global GlobalRngBackup = MersenneTwister(0); 

function copyRng!(dest::MersenneTwister, src::MersenneTwister)
	
	dest.seed = src.seed
	dest.state = src.state
	dest.vals = src.vals
	dest.ints = src.ints
	dest.idxF = src.idxF
	dest.idxI = src.idxI
	
end

function Base.rand(distrRng::DistrRng, n::Int)
	rng = distrRng.rng # shorthand
	copyRng!(GlobalRngBackup, GLOBAL_RNG)
	copyRng!(GLOBAL_RNG, rng)
	value = rand(distrRng.d, n)
	copyRng!(rng, GLOBAL_RNG)
	copyRng!(GLOBAL_RNG, GlobalRngBackup) 
	return value
end
function Base.rand(distrRng::DistrRng)
	return rand(distrRng, 1)[1]
end

```

The above is a very interesting piece of code to randomly generate a number following a given probability distribution sampler and random number generator, with the help of rewriting the default `Base.rand` functions. I only have a few confusing points as the following.  
1: In the first inner constructor inside of the `mutable struct DistrRng`, `deepcopy` is used. Then, in the function `copyRng!`, apparently, a simple reassignment is used. I was wondering, why is this?  
2: Is there a better way to accomplish this, besides rewriting this `Base.rand()` function?

---

<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:** [April 7, 2019, 5:49pm UTC](https://discourse.julialang.org/t/generate-next-random-value-based-on-a-given-statistical-distribution-in-julia/22872/2 "2019-04-07T17:49:52Z")

</div>

> [@bsnyh](#):
>
> I was wondering, why is this?

You should probably ask the author of the algorithm.

But this code looks weird, with all that copying back and forth. It is unclear why that is needed, or what it is supposed to accomplish. It is generally best to just provide `rng`s to functions that use randomness explicitly, with the understanding that they may be mutated in an unpredictable manner, and not rely on the specifics.

---

<div class="post-metadata">

**Author:** ![bsnyh](https://avatars.discourse-cdn.com/v4/letter/b/ce7236/32.png) [@bsnyh](https://discourse.julialang.org/u/bsnyh)\
**Post date:** [April 8, 2019, 7:11am UTC](https://discourse.julialang.org/t/generate-next-random-value-based-on-a-given-statistical-distribution-in-julia/22872/3 "2019-04-08T07:11:47Z")

</div>

@Tamas_Papp, thanks for replying. Here is my understanding. The key function, based on my understanding, is the `Base.rand(distrRng::DistrRng, n::Int)` function. The intended goal is to generate next random value using the `d` attribute (which is for the statistical distribution) of the defined DistrRng type, and the random number generator, which is `rng` attribute of the defined DistrRng type. The author is trying to use the provided `rand` function in the `Base` module/library. Since `Base.rand(::AbstractRNG, ::Distribution)` does not exist for all distributions, the author uses the provided `Base.rand(::Distribution)`, indeed, it’s `rand(distrRng.d,n)` inside of the `Base.rand(distrRng::DistrRng, n::Int)` to generate the next random number with distribution in distrRng, and with RNG in “GLOBAL\_RNG”. That’s why the copying back and forth, before and after calling the `rand(distrRng.d,n)` function.

---

<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:** [April 8, 2019, 7:19am UTC](https://discourse.julialang.org/t/generate-next-random-value-based-on-a-given-statistical-distribution-in-julia/22872/4 "2019-04-08T07:19:48Z")

</div>

FWIW, I am still not getting what is going on here, but as I said, you should probably talk to the author.

Also, it may be better to just formulate a question about what _you_ want to do, instead of trying to figure out what someone’s code does. Doing that without context is particularly difficult.

If you are trying to implement another RNG, there is [some documentation](https://docs.julialang.org/en/v1/stdlib/Random/#Creating-new-generators-1), even though the API is not finalized yet. In particular, an RNG should define a few particular `rand` methods for bits types, the rest is optimization.
