/**
 * \file NombreAleatoireMersenneTwister.h
 * Classe de modelisation d'un generateur de nombres aleatoires.
 * 
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */

#ifndef ____NOMBREALEATOIREMERSENNETISTER____
#define ____NOMBREALEATOIREMERSENNETISTER____

#include "NombreAleatoireBaseClasse.h"

#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfU
#define UPPER_MASK 0x80000000U
#define LOWER_MASK 0x7fffffffU

#define TEMPERING_MASK_B 0x9d2c5680U
#define TEMPERING_MASK_C 0xefc60000U
#define TEMPERING_SHIFT_U(y)  (y >> 11)
#define TEMPERING_SHIFT_S(y)  (y << 7)
#define TEMPERING_SHIFT_T(y)  (y << 15)
#define TEMPERING_SHIFT_L(y)  (y >> 18)

/**
 * \class NombreAleatoireMersenneTwister
 * Classe de modelisation d'un generateur de nombres aleatoires.
 * 
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */

class NombreAleatoireMersenneTwister : public NombreAleatoireBaseClasse {

  private :
    unsigned long mt[N];
    int mti;
    int first;
    unsigned long mag01[2];

  public :

/**
 * Constructeur d'un objet NombreAleatoireBaseClasse.
 *
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    NombreAleatoireMersenneTwister(void);

/**
 * Constructeur d'un objet NombreAleatoireMersenneTwister.
 *
 * @param s La valeur d'initialisation du germe du generateur de nombres aleatoires.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    NombreAleatoireMersenneTwister(unsigned long s);

/**
 * Destructeur d'un objet NombreAleatoireMersenneTwister.
 *
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    ~NombreAleatoireMersenneTwister(void);

/**
 * Affectation du germe du generateur de nombres aleatoires.
 *
 * @param s La valeur d'affectation du germe du generateur de nombres aleatoires.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual void init(unsigned long s);

/**
 * Tirage d'un nombre aleatoire entier.
 *
 * @param limite La valeur maximale+1 tiree au sort.
 * @return Un nombre aleatoire entier compris entre 0 et limite-1.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual int rand(int limite);

/**
 * Tirage d'un nombre aleatoire entier.
 *
 * @param limite La valeur maximale+1 tiree au sort.
 * @return Un nombre aleatoire entier compris entre 0 et limite-1.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual long rand(long limite);

/**
 * Tirage d'un nombre aleatoire reel.
 *
 * @param limite La valeur maximale tiree au sort.
 * @return Un nombre aleatoire reel compris entre 0 et limite.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual float rand(float limite);

/**
 * Tirage d'un nombre aleatoire reel.
 *
 * @param limite La valeur maximale tiree au sort.
 * @return Un nombre aleatoire reel compris entre 0 et limite.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual double rand(double limite);

/**
 * Tirage d'un nombre aleatoire reel et reinitialisation du germe du generateur.
 *
 * @param limite La valeur maximale tiree au sort.
 * @param seed La valeur d'affectation du germe du generateur de nombres aleatoires.
 * @return Un nombre aleatoire reel compris entre 0 et limite.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual float rand(float limite,unsigned long seed);

/**
 * Tirage d'un nombre aleatoire reel et reinitialisation du germe du generateur.
 *
 * @param limite La valeur maximale tiree au sort.
 * @param seed La valeur d'affectation du germe du generateur de nombres aleatoires.
 * @return Un nombre aleatoire reel compris entre 0 et limite.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual double rand(double limite,unsigned long seed);

/**
 * Tirage d'un nombre aleatoire reel et reinitialisation du germe du generateur.
 *
 * @param limite La valeur maximale tiree au sort.
 * @param seed La valeur d'affectation du germe du generateur de nombres aleatoires.
 * @return Un nombre aleatoire reel compris entre 0 et limite.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual double rand(double limite,double seed);

/**
 * Tirage d'un nombre aleatoire reel compris entre 0 et 1.
 *
 * @return Un nombre aleatoire reel compris entre 0 et 1.
 * @author Nicolas Janey
 * @author nicolas.janey@univ-fcomte.fr
 * @version 1.0, 01/01/10
 */
    virtual double rand_0_1(void);

    unsigned long genrand(void);
};

#endif
