<span style="font-weight: 400;">Pseudorandom number generators (PRNGs) are an integral part of many applications in statistics, modeling, and simulations. In ArrayFire v3.4, we introduce random number generation enhancements that improve speed, accuracy, storage, and unity among the ArrayFire backends.</span>

<span style="font-weight: 400;">Previously in ArrayFire v3.3, each ArrayFire backend used a different PRNG. In ArrayFire v3.4, each ArrayFire backend is able to select from among 3 different random number generators.</span>
<table>
<tbody>
<tr>
<td colspan="2">ArrayFire v3.3 (platform specific)</td>
<td rowspan="4"></td>
<td colspan="2">ArrayFire v3.4 (all generators on all platforms)</td>
</tr>
<tr>
<td>CUDA</td>
<td>XORWOW</td>
<td rowspan="3">CUDA,
OpenCL,
CPU</td>
<td rowspan="3">Philox (CBRNG),
Threefry (CBRNG),
Mersenne Twister</td>
</tr>
<tr>
<td>OpenCL</td>
<td>Threefry (CBRNG)</td>
</tr>
<tr>
<td>CPU</td>
<td>Mersenne Twister</td>
</tr>
</tbody>
</table>
<span style="font-weight: 400;">As see above, the XORWOW generator (which was only available for CUDA devices previously) has been replaced by the Philox generator which is available along with Threefry and Mersenne Twister on all ArrayFire supported devices. Philox and Threefry are</span><span style="font-weight: 400;"> <a href="http://www.thesalmons.org/john/random123/papers/random123sc11.pdf">Counter Based Random Number Generators</a> (CBRNGs). CBRNGs have two major advantages over PRNGs:</span>
<ol>
 	<li style="font-weight: 400;"><span style="font-weight: 400;">Crush Resistance - CBRNGs pass rigorous and extensive statistical tests while Mersenne Twister and XORWOW are not as accurate.</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 CBRNGs is minimal compared to Mersenne Twister.</span></li>
</ol>
<span style="font-weight: 400;">For these reasons, ArrayFire v3.4 now includes both the Philox and Threefry CBRNGs. Mersenne Twister will continue to be maintained due to its ubiquity in technical computing.</span>
<h4>Usage</h4>
<span style="font-weight: 400;">Users create a random engine object that contains the state of the engine. These objects are initialized by specifying the random engine type and seed. Then the objects are passed into the <span class="lang:default decode:true crayon-inline">randu</span> and <span class="lang:default decode:true crayon-inline">randn</span> functions 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. These default random engines contain the state of the engine and can be reset or changed 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>
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>
[caption id="attachment_9312" align="aligncenter" width="600"]<a href="http://sandbox.arrayfire.com/wp-content/uploads/2016/09/cuda.png"><img class="wp-image-9312 size-full" src="http://sandbox.arrayfire.com/wp-content/uploads/2016/09/cuda.png" alt="OpenCL Backend Performance" width="600" height="371" /></a> OpenCL Backend Performance[/caption]

[caption id="attachment_9313" align="aligncenter" width="600"]<a href="http://sandbox.arrayfire.com/wp-content/uploads/2016/09/opencl.png"><img class="wp-image-9313 size-full" src="http://sandbox.arrayfire.com/wp-content/uploads/2016/09/opencl.png" alt="CUDA Backend Performance" width="600" height="371" /></a> CUDA Backend Performance[/caption]
<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 our <a href="https://github.com/arrayfire/arrayfire">GitHub</a> page, <a href="https://groups.google.com/forum/#!forum/arrayfire-users">Google Group</a> or <a href="https://gitter.im/arrayfire/arrayfire?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge">Gitter</a> to contribute to the discussion.