lot.h

Go to the documentation of this file.
00001 ///
00002 /// \file   lot.h
00003 /// \brief  Random number generators
00004 ///
00005 /// A series of random number generators are provided here. Any one of three
00006 /// uniform random number generators can be chosen. By default the Mersenne
00007 /// twister is used.
00008 ///
00009 /// \author Kent Holsinger & Paul Lewis
00010 /// \date   2004-06-26
00011 ///
00012 
00013 // This file is part of MCMC++, a library for constructing C++ programs
00014 // that implement MCMC analyses of Bayesian statistical models.
00015 // Copyright (c) 2004-2006 Kent E. Holsinger
00016 //
00017 // MCMC++ is free software; you can redistribute it and/or modify
00018 // it under the terms of the GNU General Public License as published by
00019 // the Free Software Foundation; either version 2 of the License, or
00020 // (at your option) any later version.
00021 //
00022 // MCMC++ is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with MCMC++; if not, write to the Free Software
00029 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00030 //
00031 
00032 #ifndef __LOT_H
00033 #define __LOT_H
00034 
00035 // standard includes
00036 #include <cassert>
00037 // local includes
00038 #include "mcmc++/util.h"
00039 
00040 /// typedef to allow more succint declarations for some variables
00041 ///
00042 typedef std::vector<double> DblVect;
00043 
00044 /// \class lot
00045 /// \brief Provides a series of random number generators
00046 ///
00047 /// This class provides a series of random number generators. Three different
00048 /// uniform random number generators are provided. By default the Mersenne
00049 /// twister is used. Sources are acknowledged in the source code by including 
00050 /// copyright information (where appropriate).
00051 ///
00052 /// It is given the name "lot" because the noun lot is defined as "an object 
00053 /// used in deciding something by chance" according to The New Merriam-Webster 
00054 /// Dictionary,
00055 ///
00056 /// To seed the random number generator with a specific value (useful for
00057 /// debugging stochastic simulations), do the following:
00058 ///
00059 /// \code
00060 ///     lot rng;
00061 ///     rng.set_seed(1234L);
00062 /// \endcode
00063 ///
00064 /// You can, of course pick any number you like.
00065 ///
00066 
00067 class lot {
00068 public:
00069   enum {
00070     RAN_POL = 1,   ///< Paul's original RNG from J. Monahan, NCSU
00071     RAN_KNU,       ///< Knuth's rng.c translated to C++
00072     RAN_MT         ///< Mersenne twister MT19937 
00073   };
00074 
00075   enum {
00076     PRECISE = 100, ///< use double version of uniform with RAN_KNU
00077     FAST           ///< retrieve double from uniform long with RAN_KNU
00078   };
00079 
00080   enum {
00081     OPEN = 1000,   ///< uniform on (0,1) with RAN_MT
00082     ZERO,          ///< uniform on [0,1) with RAN_MT
00083     ZERO_ONE       ///< uniform on [0,1] with RAN_MT
00084   };
00085 
00086   lot(int type = RAN_MT, int gType = ZERO);
00087   ~lot(void);
00088   void set_generator(int type, int gType);
00089 
00090   /// First seed from RAN_POL
00091   ///
00092   inline long seed(void) {
00093     return ix;
00094   }
00095 
00096   /// Second seed from RAN_POL
00097   ///
00098   inline long init_seed(void) {
00099     return ix0;
00100   }
00101 
00102   void randomize (int spin = 100);
00103   void set_seed (long s);
00104 
00105   void dememorize (int spin = 100);
00106 
00107   void ran_start(long seed);
00108   void ranf_start(long seed);
00109 
00110   int random_int(int);
00111   long random_long(long maxval = Util::int_max);
00112 
00113   /// Uniform random integer in [0, Util::int_max-1] with RAN_KNU
00114   ///
00115   inline long ran_knu(void) {
00116     return *ran_arr_ptr >= 0 ? *ran_arr_ptr++ : ran_arr_cycle();
00117   }
00118 
00119   /// Uniform random number
00120   ///
00121   /// RAN_POL & RAN_KNU produce uniform on [0,1)
00122   /// RAN_MT produces uniform on [0,1) by default
00123   /// RAN_MT can produce uniform on (0,1) or [0,1]
00124   /// \see Set_MT
00125   ///
00126   inline double uniform(void) {
00127     return (this->*do_uniform)();
00128   }
00129 
00130   void ran_array(std::vector<long>& x, int n);
00131   void ranf_array(std::vector<double>& aa, int n);
00132 
00133   void MT_sgenrand(long seed);
00134   void MT_init_by_array(unsigned long* init_key, int key_length);
00135   void MT_R_initialize(int seed);
00136   unsigned long MT_genrand_int(void);
00137   // uniform (0,1): mapped to uniform() by default
00138   double MT_genrand(void);
00139   // uniform [0,1)
00140   double MT_genrand_with_zero(void);
00141   // uniform [0,1]
00142   double MT_genrand_with_zero_one(void);
00143   bool Set_MT(int type);
00144 
00145   double beta(double aa, double bb);
00146   int binom(double nin, double pp);
00147   double cauchy(double l, double s);
00148   double chisq(double n);
00149   std::vector<double> dirichlet(std::vector<double> c);
00150   double expon(void);
00151   /// Exponential random deviate
00152   ///
00153   /// \param lambda   The exponential parameter (\f$\lambda\f$)
00154   ///
00155   /// \f[ f(x) = \lambda e^{-\lambda x} \f]
00156   ///
00157   /// \f[ \mu = \frac{1}{\lambda} \f]
00158   /// \f[ \sigma^2 = \left(\frac{1}{\lambda}\right)^2 \f]
00159   ///
00160   /// Calls expon() to do the real work
00161   ///
00162   inline double exponential(const double lambda) {
00163     return (lambda*expon());
00164   }
00165   double f(double m, double n);
00166   double gamma(double a, double scale = 1.0);
00167   double geom(double p);
00168   int hypergeom(int nn1, int nn2, int kk);
00169   /// Inverse gamma random deviate
00170   ///
00171   /// \f[ f(1/x) = \frac{1}{s^a \Gamma(a)}x^{a-1}e^{-x/s} \f]
00172   ///
00173   /// or equivalently
00174   ///
00175   /// \f[ f(y) = \frac{\lambda^a (1/y)^{a+1} e^{-\lambda/y}}{\Gamma(a)} \f]
00176   /// \f[ \lambda = 1/s \f]
00177   ///
00178   /// \param a   Shape (\f$a\f$)
00179   /// \param s   Scale (\f$s\f$)
00180   ///
00181   /// \f[ \mbox{E}(x) = \frac{\lambda}{a-1} \quad , \quad a > 1 \f]
00182   /// \f[ \mbox{Var}(x) = \frac{\lambda^2}{(a-1)^2(a-2)} \quad , \quad a > 2 \f]
00183   ///
00184   inline double igamma(const double a, const double s = 1.0) {
00185     return 1.0/gamma(a, s);
00186   }
00187   double lnorm(double logmean, double logsd);
00188   double logis(double location, double scale);
00189   std::vector<int> multinom(unsigned n, const std::vector<double>& p);
00190   double nbinom(double n, double p);
00191   int poisson(double mu);
00192   /// Normal random deviate
00193   ///
00194   /// \f[ f(x) = \frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^2}{2\sigma^2}} \f]
00195   ///
00196   /// \param mu   Mean (\f$\mu\f$)
00197   /// \param sd   Standard deviation (\f$\sigma\f$)
00198   ///
00199   /// \f[ \mbox{E}(x) = \mu \f]
00200   /// \f[ \mbox{Var}(x) = \sigma^2 \f]
00201   ///
00202   /// Calls snorm() to do the real work.
00203   ///
00204   inline double norm(const double mu, const double sd) {
00205     return sd*snorm() + mu;
00206   }
00207   double snorm(void);
00208   double t(double df);
00209   double weibull(double shape, double scale);
00210 
00211   /// First element of internal array in RAN_KNU
00212   ///
00213   /// Public only to allow testing of PRECISE 
00214   ///
00215   inline double get_ran_u_0(void) const {
00216     return ran_u[0];
00217   }
00218 
00219 private:
00220   double POL_uniform(void);
00221   double POL_uniform_open(void);
00222   double KNU_uniform(void);
00223   double KNU_uniform_from_long(void);
00224 
00225   // The following methods are from the numerical math library in R
00226   // and are used by some of the RNGs derived from R.
00227   //
00228   inline double fmax2(const double x, const double y) {
00229     return (x < y) ? y : x;
00230   }
00231   inline double fmin2(const double x, const double y) {
00232     return (x < y) ? x : y;
00233   }
00234   inline int imax2(int x, int y) {
00235     return (x < y) ? y : x;
00236   }
00237   inline int imin2(int x, int y) {
00238     return (x < y) ? x : y;
00239   }
00240   inline double fsign(double x, double y) {
00241     return ((y >= 0) ? fabs(x) : -fabs(x));
00242   }
00243 
00244   inline long get_ran_x_0(void) const {
00245     return ran_x[0];
00246   }
00247 
00248   static double ppchi2(double p, double v);
00249 
00250   // #define mod_diff(x,y) (((x)-(y))&(MM-1))
00251   // subtraction mod MM
00252   inline long mod_diff(const long x, const long y) const {
00253     return ((x - y) & (MM - 1));
00254   }
00255 
00256   // #define mod_sum(x,y) (((x)+(y))-(int)((x)+(y)))
00257   inline double mod_sum(const double x, const double y) const {
00258     return (x + y) - static_cast<int>(x + y);
00259   }
00260 
00261   // #define is_odd(x)  ((s)&1)
00262   inline bool is_odd(const long s) const {
00263     return (s & 1);
00264   }
00265 
00266   long ran_arr_cycle(void);
00267   double ranf_arr_cycle(void);
00268 
00269   double fixup(double x);
00270 
00271   static const int QUALITY = 1009;
00272   static const int KK = 100;  // the long lag
00273   static const int LL = 37;   // the short lag
00274   static const int MM = (1L << 30);
00275   static const int TT = 70;
00276 
00277   bool ready;                 // true if normal deviate ready
00278   double y_norm;              // stored normal deviate
00279 
00280   double (lot::*do_uniform)(void);
00281   double (lot::*uniform_no_zero_generator)(void);
00282   int pos;
00283   std::vector<long> ran_arr_buf;
00284   std::vector<double> ranf_arr_buf;
00285   std::vector<long> ran_x;
00286   std::vector<double> ran_u;
00287   long* ran_arr_ptr;
00288   double* ranf_arr_ptr;
00289   long ran_arr_sentinel;
00290   double ranf_arr_sentinel;
00291 
00292   // for Mersenne twister
00293   // Period parameters
00294   static const int MT_N = 624;
00295   static const int MT_M = 397;
00296 
00297   std::vector<unsigned long> mt; // the array for the state vector
00298   int mti; // mti==MT_N+1 means mt[MT_N] is not initialized
00299 
00300   int rngType_;
00301 
00302   inline double sqr(const double x) {
00303     return x*x;
00304   }
00305 
00306   long ix0, ix;
00307 
00308   double e;
00309   double prev_alpha;
00310   double c1;
00311   double c2;
00312   double c3;
00313   double c4;
00314   double c5;
00315 
00316 };
00317 
00318 #endif
00319 
00320 // Local Variables: //
00321 // mode: c++ //
00322 // End: //

Generated on Tue Mar 27 16:03:38 2007 for mcmc by  doxygen 1.5.1