// @(#)root/unuran:$Id$
// Author: L. Moneta Tue Sep 26 16:25:09 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Header file for class TUnuran

#ifndef ROOT_TUnuran
#define ROOT_TUnuran

#include <string>

#ifndef ROOT_Math_TUnuranBaseDist
#include "TUnuranBaseDist.h"
#endif


class TUnuranContDist;
class TUnuranDiscrDist;
class TUnuranMultiContDist;
class TUnuranEmpDist;

#include <memory>

//______________________________________________________________________
/**
   TUnuran class.
   Interface to the UNU.RAN package for generating non uniform random
   numbers. This class wraps the UNU.RAN calls in C++ methods.
   It provides methods for initializing Unuran and then to sample the
   desired distribution.
   It provides support for initializing UNU.RAN in these following way (various signatures
   for TUnuran::Init)
   - with string API via TUnuran::Init passing the distribution type and the method
   - using a one-dimensional distribution object defined by TUnuranContDist
   - using a multi-dimensional distribution object defined by TUnuranMultiContDist
   - using a discrete one-dimensional distribution object defined by TUnuranDiscrDist
   - using an empirical distribution defined by TUnuranEmpDist
   - using pre-defined distributions. Presently only support for Poisson (TUnuran::InitPoisson)
     and Binomial (TUnuran::InitBinomial) are provided. Other distributions can however be generated
     using the previous methods (in particular via the string API)

   The sampling is provided via these methods:
    - TUnuran::Sample()   returns a double for all one-dimensional distribution
    - TUnuran::SampleDiscr()  returns an integer for one-dimensional discrete distribution
    - TUnuran::Sample(double *) sample a multi-dimensional distribution. A pointer to a vector with
      size at least equal to the distribution dimension must be passed

   In addition is possible to set the random number generator in the constructor of the class, its seed
   via the TUnuran::SetSeed() method.
*/
///////////////////////////////////////////////////////////////////////


//class TUnuranGenerator;
struct unur_gen;
typedef struct unur_gen UNUR_GEN;

// struct unur_urng_generic;
// typedef struct unur_urng_generic UNUR_URNG;

struct unur_distr;
typedef struct unur_distr UNUR_DISTR;

struct unur_urng;
typedef struct unur_urng  UNUR_URNG;


class TRandom;
class TH1;

class TUnuran {

public:

   /**
      Constructor with a generator instance and given level of log output
   */
   TUnuran (TRandom * r = 0, unsigned int log = 0);


   /**
      Destructor
   */
   ~TUnuran ();

private:
   // usually copying is non trivial, so we make this unaccessible

   /**
      Copy constructor
   */
   TUnuran(const TUnuran &);

   /**
      Assignment operator
   */
   TUnuran & operator = (const TUnuran & rhs);

public:


   /**
      initialize with Unuran string interface
   */
   bool Init(const std::string & distr, const std::string  & method);


   /**
      Initialize method for continuous one-dimensional distribution.
      User must provide a distribution object (which is copied inside) and a string for a method.
      For the list of available method for 1D cont. distribution see the
      <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCONT">UnuRan doc</A>.
      A re-initialization is needed whenever distribution parameters have been changed.
   */
   bool Init(const TUnuranContDist & distr, const std::string & method = "auto");

   /**
      Initialize method for continuous multi-dimensional distribution.
      User must provide a distribution object (which is copied inside) and a string for a method.
      For the list of available method for multivariate cont. distribution see the
      <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCVEC">UnuRan doc</A>
      A re-initialization is needed whenever distribution parameters have been changed.

   */
   bool Init(const TUnuranMultiContDist & distr, const std::string & method = "hitro");


   /**
      Initialize method for continuous one-dimensional discrete distribution.
      User must provide a distribution object (which is copied inside) and a string for a method.
      For the list of available method for 1D discrete distribution see the
      <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fDISCR">UnuRan doc</A>
      A re-initialization is needed whenever distribution parameters have been changed.

   */
   bool Init(const TUnuranDiscrDist & distr, const std::string & method = "auto");


   /**
      Initialize method for continuous empirical distribution.
      User must provide a distribution object (which is copied inside) and a string for a method.
      The distribution object can represent binned (only 1D) or unbinned (1D or multi-dim) data
      The method for the unbinned empirical distribution are based on the kernel smoothing, see
      <A href="http://statmath.wu-wien.ac.at/software/unuran/doc/unuran.html#EMPK">UnuRan doc</A>
      A re-initialization is needed whenever distribution parameters have been changed.

   */
   bool Init(const TUnuranEmpDist & distr, const std::string & method = "empk");


   /**
      Initialize method for the Poisson distribution
      Used to generate poisson numbers for a constant parameter mu of the Poisson distribution.
      Use after the method TUnuran::SampleDiscr to generate the numbers.
      The flag reinit perform a fast re-initialization when only the distribution parameters
      are changed in the subsequent calls.
      If the same TUnuran object is used to generate with other distributions it cannot be used.
   */
   bool InitPoisson(double mu, const std::string & method = "dstd");

   /**
      Initialize method for the Binomial distribution
      Used to generate poisson numbers for a constant parameters (n,p) of the Binomial distribution.
      Use after the method TUnuran::SampleDiscr to generate the numbers.
      The flag reinit perform a fast re-initialization when only the distribution parameters
      are changed in the subsequent calls.
      If the same TUnuran object is used to generate with other distributions it cannot be used.
   */
   bool InitBinomial(unsigned int ntot, double prob, const std::string & method = "dstd");

   /**
      Reinitialize UNURAN by changing the distribution parameters but mantaining same distribution and method
      It is implemented now only for predefined discrete distributions like the poisson or the binomial
   */
   bool ReInitDiscrDist(unsigned int npar, double * params);

   /**
      Sample 1D distribution
      User is responsible for having previously correctly initialized with TUnuran::Init
   */
   double Sample();

   /**
      Sample multidimensional distributions
      User is responsible for having previously correctly initialized with TUnuran::Init
   */
   bool SampleMulti(double * x);

   /**
      Sample discrete distributions
      User is responsible for having previously correctly initialized with TUnuran::Init
   */
   int SampleDiscr();

   /**
      set the random engine.
      Must be called before init to have effect
    */
   void SetRandom(TRandom * r) {
      fRng = r;
   }

   /**
      return instance of the random engine used
    */
   TRandom * GetRandom() {
      return fRng;
   }


   /**
      set the seed for the random number generator
    */
   void SetSeed(unsigned int seed);

   /**
      set log level
   */
   bool SetLogLevel(unsigned int iflag = 1);

   /**
      set stream for log and error (not yet implemented)
   */
   bool SetLogStream() { return false;}

   /**
      used Unuran method
    */
   const std::string & MethodName() const { return fMethod; }

protected:


   bool SetRandomGenerator();

   bool SetContDistribution(const TUnuranContDist & dist );

   bool SetMultiDistribution(const TUnuranMultiContDist & dist );

   bool SetDiscreteDistribution(const TUnuranDiscrDist & dist );

   bool SetEmpiricalDistribution(const TUnuranEmpDist & dist );

   /**
      change the method and initialize Unuran with the previously given distribution
    */
   bool SetMethodAndInit();



// private:

   UNUR_GEN * fGen;                      //pointer to the UnuRan C generator struct
   UNUR_DISTR * fUdistr;                 //pointer to the UnuRan C distribution struct
   UNUR_URNG  * fUrng;                   // pointer to Unuran C random generator struct
   std::auto_ptr<TUnuranBaseDist>         fDist;       // pointer for distribution wrapper
   TRandom * fRng;                       //pointer to ROOT random number generator
   std::string fMethod;                  //string representing the method

};


#endif /* ROOT_Math_TUnuran */
 TUnuran.h:1
 TUnuran.h:2
 TUnuran.h:3
 TUnuran.h:4
 TUnuran.h:5
 TUnuran.h:6
 TUnuran.h:7
 TUnuran.h:8
 TUnuran.h:9
 TUnuran.h:10
 TUnuran.h:11
 TUnuran.h:12
 TUnuran.h:13
 TUnuran.h:14
 TUnuran.h:15
 TUnuran.h:16
 TUnuran.h:17
 TUnuran.h:18
 TUnuran.h:19
 TUnuran.h:20
 TUnuran.h:21
 TUnuran.h:22
 TUnuran.h:23
 TUnuran.h:24
 TUnuran.h:25
 TUnuran.h:26
 TUnuran.h:27
 TUnuran.h:28
 TUnuran.h:29
 TUnuran.h:30
 TUnuran.h:31
 TUnuran.h:32
 TUnuran.h:33
 TUnuran.h:34
 TUnuran.h:35
 TUnuran.h:36
 TUnuran.h:37
 TUnuran.h:38
 TUnuran.h:39
 TUnuran.h:40
 TUnuran.h:41
 TUnuran.h:42
 TUnuran.h:43
 TUnuran.h:44
 TUnuran.h:45
 TUnuran.h:46
 TUnuran.h:47
 TUnuran.h:48
 TUnuran.h:49
 TUnuran.h:50
 TUnuran.h:51
 TUnuran.h:52
 TUnuran.h:53
 TUnuran.h:54
 TUnuran.h:55
 TUnuran.h:56
 TUnuran.h:57
 TUnuran.h:58
 TUnuran.h:59
 TUnuran.h:60
 TUnuran.h:61
 TUnuran.h:62
 TUnuran.h:63
 TUnuran.h:64
 TUnuran.h:65
 TUnuran.h:66
 TUnuran.h:67
 TUnuran.h:68
 TUnuran.h:69
 TUnuran.h:70
 TUnuran.h:71
 TUnuran.h:72
 TUnuran.h:73
 TUnuran.h:74
 TUnuran.h:75
 TUnuran.h:76
 TUnuran.h:77
 TUnuran.h:78
 TUnuran.h:79
 TUnuran.h:80
 TUnuran.h:81
 TUnuran.h:82
 TUnuran.h:83
 TUnuran.h:84
 TUnuran.h:85
 TUnuran.h:86
 TUnuran.h:87
 TUnuran.h:88
 TUnuran.h:89
 TUnuran.h:90
 TUnuran.h:91
 TUnuran.h:92
 TUnuran.h:93
 TUnuran.h:94
 TUnuran.h:95
 TUnuran.h:96
 TUnuran.h:97
 TUnuran.h:98
 TUnuran.h:99
 TUnuran.h:100
 TUnuran.h:101
 TUnuran.h:102
 TUnuran.h:103
 TUnuran.h:104
 TUnuran.h:105
 TUnuran.h:106
 TUnuran.h:107
 TUnuran.h:108
 TUnuran.h:109
 TUnuran.h:110
 TUnuran.h:111
 TUnuran.h:112
 TUnuran.h:113
 TUnuran.h:114
 TUnuran.h:115
 TUnuran.h:116
 TUnuran.h:117
 TUnuran.h:118
 TUnuran.h:119
 TUnuran.h:120
 TUnuran.h:121
 TUnuran.h:122
 TUnuran.h:123
 TUnuran.h:124
 TUnuran.h:125
 TUnuran.h:126
 TUnuran.h:127
 TUnuran.h:128
 TUnuran.h:129
 TUnuran.h:130
 TUnuran.h:131
 TUnuran.h:132
 TUnuran.h:133
 TUnuran.h:134
 TUnuran.h:135
 TUnuran.h:136
 TUnuran.h:137
 TUnuran.h:138
 TUnuran.h:139
 TUnuran.h:140
 TUnuran.h:141
 TUnuran.h:142
 TUnuran.h:143
 TUnuran.h:144
 TUnuran.h:145
 TUnuran.h:146
 TUnuran.h:147
 TUnuran.h:148
 TUnuran.h:149
 TUnuran.h:150
 TUnuran.h:151
 TUnuran.h:152
 TUnuran.h:153
 TUnuran.h:154
 TUnuran.h:155
 TUnuran.h:156
 TUnuran.h:157
 TUnuran.h:158
 TUnuran.h:159
 TUnuran.h:160
 TUnuran.h:161
 TUnuran.h:162
 TUnuran.h:163
 TUnuran.h:164
 TUnuran.h:165
 TUnuran.h:166
 TUnuran.h:167
 TUnuran.h:168
 TUnuran.h:169
 TUnuran.h:170
 TUnuran.h:171
 TUnuran.h:172
 TUnuran.h:173
 TUnuran.h:174
 TUnuran.h:175
 TUnuran.h:176
 TUnuran.h:177
 TUnuran.h:178
 TUnuran.h:179
 TUnuran.h:180
 TUnuran.h:181
 TUnuran.h:182
 TUnuran.h:183
 TUnuran.h:184
 TUnuran.h:185
 TUnuran.h:186
 TUnuran.h:187
 TUnuran.h:188
 TUnuran.h:189
 TUnuran.h:190
 TUnuran.h:191
 TUnuran.h:192
 TUnuran.h:193
 TUnuran.h:194
 TUnuran.h:195
 TUnuran.h:196
 TUnuran.h:197
 TUnuran.h:198
 TUnuran.h:199
 TUnuran.h:200
 TUnuran.h:201
 TUnuran.h:202
 TUnuran.h:203
 TUnuran.h:204
 TUnuran.h:205
 TUnuran.h:206
 TUnuran.h:207
 TUnuran.h:208
 TUnuran.h:209
 TUnuran.h:210
 TUnuran.h:211
 TUnuran.h:212
 TUnuran.h:213
 TUnuran.h:214
 TUnuran.h:215
 TUnuran.h:216
 TUnuran.h:217
 TUnuran.h:218
 TUnuran.h:219
 TUnuran.h:220
 TUnuran.h:221
 TUnuran.h:222
 TUnuran.h:223
 TUnuran.h:224
 TUnuran.h:225
 TUnuran.h:226
 TUnuran.h:227
 TUnuran.h:228
 TUnuran.h:229
 TUnuran.h:230
 TUnuran.h:231
 TUnuran.h:232
 TUnuran.h:233
 TUnuran.h:234
 TUnuran.h:235
 TUnuran.h:236
 TUnuran.h:237
 TUnuran.h:238
 TUnuran.h:239
 TUnuran.h:240
 TUnuran.h:241
 TUnuran.h:242
 TUnuran.h:243
 TUnuran.h:244
 TUnuran.h:245
 TUnuran.h:246
 TUnuran.h:247
 TUnuran.h:248
 TUnuran.h:249
 TUnuran.h:250
 TUnuran.h:251
 TUnuran.h:252
 TUnuran.h:253
 TUnuran.h:254
 TUnuran.h:255
 TUnuran.h:256
 TUnuran.h:257
 TUnuran.h:258
 TUnuran.h:259
 TUnuran.h:260
 TUnuran.h:261
 TUnuran.h:262
 TUnuran.h:263
 TUnuran.h:264
 TUnuran.h:265
 TUnuran.h:266
 TUnuran.h:267
 TUnuran.h:268
 TUnuran.h:269