<span style="font-weight: 400;">Pseudorandom number generators are an integral part of many applications in statistics, modeling and simulations. ArrayFire therefore has provided high performant solutions to generate random numbers. The PRNG algorithms used in earlier versions were platform specific :</span>
<ol>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">CUDA : XORWOW</span></li>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">OpenCL : Threefry</span></li>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">CPU : Mersenne Twister</span></li>
</ol>
<span style="font-weight: 400;">While simple uses of random numbers would not have been affected by the differences in the engines, more rigorous requirements of randomness could not have been consistently provided by the earlier solutions.</span>

<span style="font-weight: 400;">A new class of PRNGs have emerged that have interesting statistical and computational performance called the <a href="http://www.thesalmons.org/john/random123/papers/random123sc11.pdf">Counter Based Random Number Generators</a>. These random number generators have two major advantages over Mersenne Twister(MT) which has been the standard for random number generation :</span>
<ol>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">Crush Resistance : CBRNGs pass rigorous and extensive statistical tests as opposed to MT and XORWOW.</span></li>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">Smaller Storage Space : The amount of storage space required to maintain state of the random engines is minimal compared to MT.</span></li>
</ol>
<span style="font-weight: 400;">Given these advantages, ArrayFire now includes Philox and Threefry algorithms which are counter based. </span>While certain PRNGs might seem more attractive in terms of performance, statistical or computational, it is our aim to provide users with the freedom to decide what tools might be most suitable to their requirements. Therefore, Mersenne Twister algorithm has been implemented for use as well.

In <strong>ArrayFire v3.4</strong>, users can select between the following PRNGs :
<ol>
 	<li>Philox (CBRNG)</li>
 	<li>Threefry (CBRNG)</li>
 	<li>Mersenne Twister</li>
</ol>
<h4>Usage</h4>
<span style="font-weight: 400;">Users can create a random engine object that contains the state of the engine. These objects are initialized by specifying the random engine type and seed and are then passed onto <span class="lang:default decode:true crayon-inline">randu</span> and <span class="lang:default decode:true crayon-inline">randn</span> which generate the sequence of random numbers.</span>
<pre class="lang:c++ decode:true">unsigned seed;
unsigned elem;
af::randomEngine rp(AF_RANDOM_ENGINE_PHILOX, seed);
af::array R = af::randu(elem, f32, rp);</pre>
Another method to select a random engine algorithm is to set the default random engine type. If needed the desired seed can be specified as well. Subsequent calls to <span class="lang:default decode:true crayon-inline ">randu</span>  and <span class="lang:default decode:true crayon-inline ">randn</span>  will utilize the default random engine without needing to alter these function calls in the code base. These default random engines contain the state of the engine and can be reset or changed as required by the user.
<pre class="lang:c++ decode:true ">unsigned seed;
setSeed(seed);
setDefaultRandomEngine(AF_RANDOM_ENGINE_THREEFRY);
//Or AF_RANDOM_ENGINE_DEFAULT, AF_RANDOM_ENGINE_PHILOX, AF_RANDOM_ENGINE_MERSENNE
af::array R = af::randu(elem, f32);//Utilizes threefry PRNG algorithm initialized with 'seed'</pre>
As of now, the default random engine type is <span class="lang:default decode:true crayon-inline ">AF_RANDOM_ENGINE_PHILOX</span> . For further details on usage, please refer to the <a href="http://arrayfire.org/docs/group__random__mat.htm">documentation</a>.
<h4>Performance Numbers</h4>
&nbsp;
<h4>Future Plans</h4>
XORWOW and MRG32K3a random engines will be added in the future. Apart from random engines, users can also benefit from the following random number distributions which are planned for inclusion in subsequent releases :
<ul>
 	<li class="task-list-item enabled hovered">Exponential</li>
 	<li class="task-list-item enabled">Gamma</li>
 	<li class="task-list-item enabled">Chi-squared</li>
 	<li class="task-list-item enabled">Non-central Chi-squared</li>
 	<li class="task-list-item enabled">Poisson</li>
</ul>
We look forward to your feedback on the improved random number generation and any feature requests to improve it further. Join us on the ArrayFire <a href="https://github.com/arrayfire/arrayfire">GitHub</a> page or the ArrayFire <a href="https://groups.google.com/forum/#!forum/arrayfire-users">Google Group</a> to contribute to the discussion.