/* fonctions pour generateurs aleatoires     */
/*                         cmv  23/06/94     */
/*  R.Ansari 04/2000  Copie de nbrand.h .c   */

#ifndef SRANDGEN_H_SEEN
#define SRANDGEN_H_SEEN

#include "machdefs.h"
#include <stdlib.h>

/* ------- SPECIFIQUE Mac Darwin OSX  <= 10.2 (gcc < 3.x) -------- */
#if defined(Darwin) &&  defined(__GNUC__) && (__GNUC__ < 3)
#include "osx_values.h"
/* Declaration de drand48 et srand48 etc , mis ds SysSpec 
                                          Reza 11/02/2003 */
#ifdef __cplusplus
extern "C" {
#endif
unsigned short int * seed48(unsigned short int seed16v[3]);
void srand48(long seedval);
/* Faute de mieux pour le moment : */
#ifdef __cplusplus
}
#endif
#define drand48() ((double)(random())/LONG_MAX)
#endif
/* ------- FIN SPECIFIQUE Mac OSX / Darwin V <= 10.2 --------- */

#ifdef __cplusplus
/* Declaration en fonctions inlines pour du C++ */
inline float frand01() { return ( (float) drand48() ); }
inline double drand01() { return ( drand48() ); }
inline double ranf01() { return ( drand48() ); }

inline float frandpm1() { return ( 2. * (float) drand48()  - 1.); }
inline double drandpm1() { return ( 2. * drand48() - 1.); }
inline double ranfpm1() { return ( 2. * drand48() - 1.); }
#else
/* les memes en define pour du C */
#define frand01() ( (float) drand48() )
#define drand01() ( drand48() )
#define ranf01() drand01()

#define frandpm1() ( 2. * frand01() - 1.)
#define drandpm1() ( 2. * drand01() - 1.)
#define ranfpm1() drandpm1()
#endif

struct tirage_alea {
  int Nbin;
  double Min,Max,Lbin;
  double *Tab;
};
typedef struct tirage_alea TIREALEA;

#ifdef __cplusplus
extern "C" {
#endif

void Ini_Ranf_Quick(long seed_val, int lp);
void Ini_Ranf(unsigned short seed_16v[3], int lp);
void Get_Ranf(unsigned short seed_16v[3], int lp);
void Auto_Ini_Ranf(int lp);

void SetGauRange(double range);
float NorRand1(void);
double GauRnd1(double am, double s);
float NorRand(void);
double GauRnd(double am, double s);
int NormCo(double *a,double *b
          ,double mx,double my,double sx,double sy,double ro);
void NormGau(double *x,double *y
            ,double mx,double my,double sa,double sb,double teta);

int PoissRand(double mu);

TIREALEA *init_tirage_alea(int nbin,double xmin,double xmax,double (*fonc) (double));
double tirage_alea(TIREALEA *alea);
int end_tirage_alea(TIREALEA *alea);

#ifdef __cplusplus
}
#endif

/* -- Declaration d'une classe pour la centralier la doc -- Oct 2006 */
#ifdef __cplusplus
namespace SOPHYA {
class RandomGenerator {
 public:
  /*! \brief Automatic initialization through Auto_Ini_Ranf() */
  static inline void AutoInit(int lp=0) { Auto_Ini_Ranf(lp); return; } 
  /*! \brief Return a random number \b r with a flat distribution  0<=r<=1 */ 
  static inline double Flat01() { return drand48(); }
  /*! \brief Return a random number \b r with a flat distribution  -1<=r<=1 */ 
  static inline double Flatpm1() { return drandpm1(); }
  /*! \brief Return a random number following a zero mean gaussian distribution  */ 
  static inline double Gaussian(double sigma=1.) { return GauRnd(0., sigma); }
  /*! \brief Return a random number following a Poisson distribution with mean \b mu  */ 
  static inline int    Poisson(double mu) { return PoissRand(mu); }
};
} /* namespace SOPHYA */
#endif

#endif

