Performance des pseudo-RNGs
==
L'objectif de ce premier TP est d'évaluer, de manière quantitative, les performances des générateurs de nombres pseudo-aléatoires.
::: info
**Prérequis**:
* compilateur c/c++ classique
* cmake récent
* gnuplot
:::
# Warmup
1. Récupérez le code du TP sur https://github.com/dcoeurjo/BenchSampling
Pour l'évaluation des performances, deux outils sont possibles : [google benchmark](https://github.com/google/benchmark) (lib google pour du micro-benchmarking), ou alors une utilisation classique des [chronos c++](https://cplusplus.com/reference/chrono/) de la stl.
2. Compilez le projet avec les exemples, eg.:
:::success
mkdir build
cd build
cmake .. (<-deux points uniquement)
:::
# Performances des générateurs usuels
3. Pour un lancer de dé classique et en utilisant la métrique (cf `benchGenerator.cpp` ou `test-timer.cpp`) que vous voulez, évaluez les performances des générateurs suivants sur un range $[0:6)$: `std::rand()`, `drand48()`, `pcg32` (inclus dans le code source) et ceux de la STL sous le format:
```c++=
std::random_device rd; // a seed source for the random number engine
std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> distrib(1, 6);`
```
Avec comme générateur: `std::mt19937` ou `std::minstd_rand`.
Par exemple, effectuez un grand nombre de lancers de dé et comparer la distribution obtenue au test uniforme $\frac{1}{6}$.
4. Pourquoi est-ce une mauvaise idée de faire `std::rand() % 6` pour un tirage aléatoire entre 0 et 5 ?
# Cas d'étude
Considérons le générateur suivant sur $[0,1]$ et sur les entiers non signés:
```c++=
double trig(double x)
{
double y = 43757.5453*sin( std::abs(x) * 12.9898);
return y - floor(y);
}
uint trigInt(uint i)
{
return (uint)(trig(double(i))*double(float(0xffffffffu)));
}
```
5. Implémentez ces pseudoRNG et testez l'uniformité de la distribution sur générée (via le test du dé précédent par exemple).
Pour une évaluation plus formelle, nous allons utiliser la plateforme de test [testU01](http://simul.iro.umontreal.ca/testu01/tu01.html) issue de l'article https://dl.acm.org/doi/10.1145/1268776.1268777.
:::info
Pour cette partie du TP, nous aurons besoin de compiler la bibliothèque [testU01](http://simul.iro.umontreal.ca/testu01/tu01.html):
```
cd testU01
./configure --prefix=$PWD/local
make
make install
```
:::
:::info
Ensuite, dé-commentez les lignes 22 à 24 du fichier `CMakeLists.txt`
:::
6. Complétez le fichier `test-test01.cpp` avec le PRNG précédent et évaluez ses performances `bbattery_SmallCrush()` et `bbattery_Crush()`
7. Vérifier que le générateur `pcg32` passe bien les tests.