<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. In the earlier versions, PRNG algorithms 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 Counter Based Random Number Generators. 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, users now have the ability to select between these PRNGs :</span>
<ol>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">Philox (CBRNG)</span></li>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">Threefry (CBRNG)</span></li>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">Mersenne Twister</span></li>
</ol>
<span style="font-weight: 400;">The API changes to incorporate user controlled random number generators has been minimal. The method to generate a sequence of random numbers is slightly altered. <span class="lang:default decode:true  crayon-inline ">randu</span>  and <span class="lang:default decode:true  crayon-inline ">randn</span>  can accept an additional parameter for the random number generator. A random number generator can be initialized by specifying the random engine type and its seed.</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 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.
<pre class="lang:c++ decode:true">unsigned seed;
setSeed(seed);
setDefaultRandomEngine(AF_RANDOM_ENGINE_PHILOX);
setDefaultRandomEngine(AF_RANDOM_ENGINE_THREEFRY);
setDefaultRandomEngine(AF_RANDOM_ENGINE_MERSENNE);
setDefaultRandomEngine(AF_RANDOM_ENGINE_DEFAULT);</pre>
&nbsp;