Random.h

Go to the documentation of this file.
00001 //# Random.h: Random number classes
00002 //# Copyright (C) 1992,1993,1994,1995,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 
00028 #ifndef CASA_RANDOM_H
00029 #define CASA_RANDOM_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/BasicMath/Math.h>
00033 namespace casa { //# NAMESPACE CASA - BEGIN
00034 
00035 class String;
00036 template<class T> class Vector;
00037 
00038 // <summary>Base class for random number generators</summary>
00039 //
00040 // <use visibility=export>
00041 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00042 // </reviewed>
00043 //
00044 // <prerequisite>
00045 //   <li> A knowledge of C++, in particular inheritance
00046 //   <li> College level mathematics
00047 // </prerequisite>
00048 //
00049 // <etymology>
00050 // RNG stands for "Random Number Generator"
00051 // </etymology>
00052 //
00053 // <synopsis>
00054 // <h4>General Structure of the Classes</h4>
00055 // 
00056 
00057 // The two base classes <linkto class=RNG>RNG</linkto> and 
00058 // <linkto class=Random>Random</linkto> are used together to generate a variety
00059 // of random number distributions.  A distinction must be made between
00060 // <em>random number generators</em>, implemented by class derived from
00061 // <src>RNG</src>, and <em>random number distributions</em>.  A random number
00062 // generator produces a series of randomly ordered bits.  These bits can be
00063 // used directly, or cast to another representation, such as a floating point
00064 // value.  A random number generator should produce a <em>uniform</em>
00065 // distribution.  A random number distribution, on the other hand, uses the
00066 // randomly generated bits of a generator to produce numbers from a
00067 // distribution with specific properties.  Each instance of <src>Random</src>
00068 // uses an instance of class <src>RNG</src> to provide the raw, uniform
00069 // distribution used to produce the specific distribution.  Several instances
00070 // of <src>Random</src> classes can share the same instance of <src>RNG</src>,
00071 // or each instance can use its own copy.
00072 
00073 // <h4> RNG </h4>
00074 // 
00075 
00076 // Random distributions are constructed from classes derived from
00077 // <src>RNG</src>, the actual random number generators.  The <src>RNG</src>
00078 // class contains no data; it only serves to define the interface to random
00079 // number generators.  The <src>RNG::asuInt</src> member returns a 32-bit
00080 // unsigned integer of random bits.  Applications that require a number of
00081 // random bits can use this directly.  More often, these random bits are
00082 // transformed to a uniformly distributed floating point number using either
00083 // <src>asFloat</src> or <src>asDouble</src>.  These functions return differing
00084 // precisions and the <src>asDouble</src> function will use two different
00085 // random 32-bit integers to get a legal <src>double</src>, while
00086 // <src>asFloat</src> will use a single integer.  These members are used by
00087 // classes derived fro the <src>Random</src> base class to implement a variety
00088 // of random number distributions.
00089 //
00090 // Currently, the following subclasses are provided:
00091 // <ul>
00092 // <li> <linkto class=MLCG>MLCG</linkto>: 
00093 //      Multiplicative Linear Congruential Generator.
00094 //      A reasonable generator for most purposes.
00095 // <li> <linkto class=ACG>ACG</linkto>: Additive Number Generator. 
00096 //      A high quality generator that uses more memory and computation time.
00097 // </ul>
00098 // 
00099 // <note role=warning> This class assumes that IEEE floating point
00100 // representation is used for the floating point numbers and that the integer
00101 // and unsigned integer type is exactly 32 bits long.
00102 // </note>
00103 // </synopsis>
00104 //
00105 // <example>
00106 // </example>
00107 //
00108 // <motivation>
00109 // Random numbers are used everywhere, particularly in simulations.
00110 // </motivation>
00111 //
00112 // <thrown>
00113 // <li> AipsError: If a programming error or unexpected numeric size is
00114 // detected. Should not occur in normal usage.
00115 // </thrown>
00116 //
00117 // <todo asof="2000/05/09">
00118 //   <li> Nothing I hope!
00119 // </todo>
00120 
00121 class RNG {
00122 public:
00123   // A virtual destructor is needed to ensure that the destructor of derived
00124   // classes gets used.
00125   virtual ~RNG();
00126 
00127   // Resets the random number generator. After calling this function the random
00128   // numbers generated will be the same as if the object had just been
00129   // constructed.
00130   virtual void reset() = 0;
00131 
00132   // Return the 32-random bits as an unsigned integer
00133   virtual uInt asuInt() = 0;
00134 
00135   // Return random bits converted to either a Float or a Double. The returned
00136   // value x is in the range 1.0 > x >= 0.0 
00137   // <group>
00138   Float asFloat();
00139   Double asDouble();
00140   // </group>
00141 };
00142 
00143 // <summary>Additive number generator</summary>
00144 //
00145 // <use visibility=export>
00146 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00147 // </reviewed>
00148 //
00149 // <prerequisite>
00150 //   <li> A knowledge of C++, in particular inheritance
00151 //   <li> College level mathematics
00152 // </prerequisite>
00153 //
00154 // <etymology>
00155 // ACG stands for "Additive Congruential Generator"
00156 // </etymology>
00157 //
00158 // <synopsis>
00159 // This class implements the additive number generator as presented in Volume
00160 // II of The Art of Computer Programming by Knuth. I have coded the algorithm
00161 // and have added the extensions by Andres Nowatzyk of CMU to randomize the
00162 // result of algorithm M a bit by using an LCG & a spatial permutation table.
00163 //
00164 // The version presented uses the same constants for the LCG that Andres uses
00165 // (chosen by trial & error). The spatial permutation table is the same size
00166 // (it is based on word size). This is for 32-bit words.
00167 //
00168 // The <src>auxillary table</src> used by the LCG table varies in size, and is
00169 // chosen to be the the smallest power of two which is larger than twice the
00170 // size of the state table.
00171 //
00172 // Class <src>ACG</src> is a variant of a Linear Congruential Generator
00173 // (Algorithm M) described in Knuth, "Art of Computer Programming, Vol III".
00174 // This result is permuted with a Fibonacci Additive Congruential Generator to
00175 // get good independence between samples.  This is a very high quality random
00176 // number generator, although it requires a fair amount of memory for each
00177 // instance of the generator.
00178 // 
00179 // The constructor takes two parameters: the seed and the size.  The seed can
00180 // be any number. The performance of the generator depends on having a
00181 // distribution of bits through the seed.  If you choose a number in the range
00182 // of 0 to 31, a seed with more bits is chosen. Other values are
00183 // deterministically modified to give a better distribution of bits.  This
00184 // provides a good random number generator while still allowing a sequence to
00185 // be repeated given the same initial seed.
00186 // 
00187 // The <src>size</src> parameter determines the size of two tables used in the
00188 // generator. The first table is used in the Additive Generator; see the
00189 // algorithm in Knuth for more information. In general, this table contains
00190 // <src>size</src> integers. The default value, used in the algorithm in Knuth,
00191 // gives a table of 55 integers (220 bytes). The table size affects the period
00192 // of the generators; smaller values give shorter periods and larger tables
00193 // give longer periods. The smallest table size is 7 integers, and the longest
00194 // is 98. The <src>size</src> parameter also determines the size of the table
00195 // used for the Linear Congruential Generator. This value is chosen implicitly
00196 // based on the size of the Additive Congruential Generator table. It is two
00197 // powers of two larger than the power of two that is larger than
00198 // <src>size</src>.  For example, if <src>size</src> is 7, the ACG table
00199 // contains 7 integers and the LCG table contains 128 integers. Thus, the
00200 // default size (55) requires 55 + 256 integers, or 1244 bytes. The largest
00201 // table requires 2440 bytes and the smallest table requires 100 bytes.
00202 // Applications that require a large number of generators or applications that
00203 // are not so fussy about the quality of the generator may elect to use the
00204 // <src>MLCG</src> generator.
00205 //
00206 // <note role=warning> This class assumes that the integer and unsigned integer
00207 // type is exactly 32 bits long.
00208 // </note> 
00209 // </synopsis>
00210 //
00211 // <example>
00212 // </example>
00213 //
00214 // <thrown>
00215 // <li> AipsError: If a programming error or unexpected numeric size is
00216 // detected. Should not occur in normal usage.
00217 // </thrown>
00218 //
00219 // <todo asof="2000/05/09">
00220 //   <li> Nothing I hope!
00221 // </todo>
00222 
00223 class ACG : public RNG {
00224 
00225 public:
00226   // The constructor allows you to specify seeds. The seed should be a big
00227   // random number and size must be between 7 and 98. See the synopsis for more
00228   // details.
00229   explicit ACG(uInt seed = 0, Int size = 55);
00230 
00231   // The destructor cleans up memory allocated by this class
00232   virtual ~ACG();
00233 
00234   // Resets the random number generator. After calling this function the random
00235   // numbers generated will be the same as if the object had just been
00236   // constructed.
00237   virtual void reset();
00238 
00239   // Return the 32-random bits as an unsigned integer
00240   virtual uInt asuInt();
00241 
00242 private:
00243   uInt itsInitSeed;     //# used to reset the generator
00244   Int itsInitTblEntry;
00245   
00246   uInt* itsStatePtr;
00247   uInt* itsAuxStatePtr;
00248   Short itsStateSize;
00249   Short itsAuxSize;
00250   uInt lcgRecurr;
00251   Short itsJ;
00252   Short itsK;
00253 };
00254 
00255 // <summary> Multiplicative linear congruential generator </summary>
00256 
00257 // <use visibility=export>
00258 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00259 // </reviewed>
00260 //
00261 // <prerequisite>
00262 //   <li> A knowledge of C++, in particular inheritance
00263 //   <li> College level mathematics
00264 // </prerequisite>
00265 //
00266 // <etymology>
00267 // MLCG stands for "Multiplicative Linear Congruential Generator"
00268 // </etymology>
00269 //
00270 
00271 // <synopsis>
00272 // The <src>MLCG</src> class implements a <em>Multiplicative Linear
00273 // Congruential Generator</em>. In particular, it is an implementation of the
00274 // double MLCG described in <em>Efficient and Portable Combined Random Number
00275 // Generators</em> by Pierre L'Ecuyer, appearing in <em>Communications of the
00276 // ACM, Vol. 31. No. 6</em>. This generator has a fairly long period, and has
00277 // been statistically analyzed to show that it gives good inter-sample
00278 // independence.
00279 // 
00280 
00281 // The constructor has two parameters, both of which are seeds for the
00282 // generator. As in the <src>ACG</src> generator, both seeds are modified to
00283 // give a "better" distribution of seed digits. Thus, you can safely use values
00284 // such as <src>0</src> or <src>1</src> for the seeds.  The <src>MLCG</src>
00285 // generator used much less state than the <src>ACG</src> generator; only two
00286 // integers (8 bytes) are needed for each generator.
00287 
00288 // <note role=warning> This class assumes that the integer and unsigned integer
00289 // type is exactly 32 bits long.
00290 // </note> 
00291 // </synopsis>
00292 
00293 // <example>
00294 // </example>
00295 //
00296 // <thrown>
00297 // <li> AipsError: If a programming error or unexpected numeric size is
00298 // detected. Should not occur in normal usage.
00299 // </thrown>
00300 //
00301 // <todo asof="2000/05/09">
00302 //   <li> Nothing I hope!
00303 // </todo>
00304 
00305 class MLCG : public RNG {
00306 public:
00307   // The constructor allows you to specify seeds.
00308   explicit MLCG(Int seed1 = 0, Int seed2 = 1);
00309   
00310   // The destructor is trivial 
00311   virtual ~MLCG();
00312 
00313   // Return the 32-random bits as an unsigned integer
00314   virtual uInt asuInt();
00315   
00316   // Resets the random number generator. After calling this function the random
00317   // numbers generated will be the same as if the object had just been
00318   // constructed.
00319   virtual void reset();
00320 
00321   // Functions that allow the user to retrieve or change the seed integers. The
00322   // seeds returned are not the user supplied values but the values obtained
00323   // after some deterministic modification to produce a more uniform bit
00324   // distribution.
00325   // <group>
00326   Int seed1() const;
00327   void seed1(Int s);
00328   Int seed2() const;
00329   void seed2(Int s);
00330   void reseed(Int s1, Int s2);
00331   // </group>
00332   
00333 private:
00334   Int itsInitSeedOne;
00335   Int itsInitSeedTwo;
00336   Int itsSeedOne;
00337   Int itsSeedTwo;
00338 };
00339 
00340 inline Int MLCG::seed1() const
00341 {
00342   return itsSeedOne;
00343 }
00344 
00345 inline void MLCG::seed1(Int s)
00346 {
00347   itsInitSeedOne = s;
00348   reset();
00349 }
00350 
00351 inline Int MLCG::seed2() const
00352 {
00353   return itsSeedTwo;
00354 }
00355 
00356 inline void MLCG::seed2(Int s)
00357 {
00358   itsInitSeedTwo = s;
00359   reset();
00360 }
00361 
00362 inline void MLCG::reseed(Int s1, Int s2)
00363 {
00364   itsInitSeedOne = s1;
00365   itsInitSeedTwo = s2;
00366   reset();
00367 }
00368 
00369 // <summary>Base class for random number distributions</summary>
00370 
00371 // <use visibility=export>
00372 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00373 // </reviewed>
00374 //
00375 // <prerequisite>
00376 //   <li> A knowledge of C++, in particular inheritance
00377 //   <li> College level mathematics
00378 // </prerequisite>
00379 //
00380 // <synopsis>
00381 // A random number generator may be declared by first constructing a
00382 // <src>RNG</src> object and then a <src>Random</src>. For example,
00383 // <srcblock>
00384 //   ACG gen(10, 20); 
00385 //   NegativeExpntl rnd (1.0, &gen);
00386 // </srcblock>
00387 // declares an additive congruential generator with seed 10 and table size 20,
00388 // that is used to generate exponentially distributed values with mean of 1.0.
00389 // 
00390 // The virtual member <src>Random::operator()</src> is the common way of
00391 // extracting a random number from a particular distribution.  The base class,
00392 // <src>Random</src> does not implement <src>operator()</src>.  This is
00393 // performed by each of the derived classes. Thus, given the above declaration
00394 // of <src>rnd</src>, new random values may be obtained via, for example,
00395 // <src>Double nextExpRand = rnd();</src>
00396 //
00397 // Currently, the following subclasses are provided:
00398 //
00399 // <ul>
00400 //    <li> <linkto class=Binomial>Binomial</linkto>
00401 //    <li> <linkto class=Erlang>Erlang</linkto>
00402 //    <li> <linkto class=Geometric>Geometric</linkto>
00403 //    <li> <linkto class=HyperGeometric>HyperGeometric</linkto>
00404 //    <li> <linkto class=NegativeExpntl>NegativeExpntl</linkto>
00405 //    <li> <linkto class=Normal>Normal</linkto>
00406 //    <li> <linkto class=LogNormal>LogNormal</linkto>
00407 //    <li> <linkto class=Poisson>Poisson</linkto>
00408 //    <li> <linkto class=DiscreteUniform>DiscreteUniform</linkto>
00409 //    <li> <linkto class=Uniform>Uniform</linkto>
00410 //    <li> <linkto class=Weibull>Weibull</linkto>
00411 // </ul>
00412 // </synopsis>
00413 //
00414 // <example>
00415 // </example>
00416 //
00417 // <thrown>
00418 //   <li> No exceptions are thrown directly from this class.
00419 // </thrown>
00420 //
00421 // <todo asof="2000/05/09">
00422 //   <li> Nothing I hope!
00423 // </todo>
00424 
00425 class Random {
00426 public:
00427   
00428   // This enumerator lists all the predefined random number distributions.
00429   enum Types {
00430     // 2 parameters. The binomial distribution models successfully drawing
00431     // items from a pool.  Specify n and p. n is the number of items in the
00432     // pool, and p, is the probability of each item being successfully drawn.
00433     // It is required that n > 0 and 0 <= p <= 1
00434    BINOMIAL,
00435 
00436    // 2 parameters. Model a uniform random variable over the closed
00437    // interval. Specify the values low and high. The low parameter is the
00438    // lowest possible return value and the high parameter is the highest.  It
00439    // is required that low < high.
00440    DISCRETEUNIFORM,
00441 
00442    // 2 parameters, mean and variance.  It is required that the mean is
00443    // non-zero and the variance is positive.
00444    ERLANG, 
00445 
00446    // 1 parameters, the mean.  It is required that 0 <= probability < 1
00447    GEOMETRIC, 
00448 
00449    // 2 parameters, mean and variance.  It is required that the variance is
00450    // positive and that the mean is non-zero and not bigger than the
00451    // square-root of the variance.
00452    HYPERGEOMETRIC,
00453 
00454    // 2 parameters, the mean and variance.  It is required that the variance is
00455    // positive.
00456    NORMAL, 
00457 
00458    // 2 parameters, mean and variance.  It is required that the supplied
00459    // variance is positive and that the mean is non-zero
00460    LOGNORMAL,
00461 
00462    // 1 parameter, the mean.
00463    NEGATIVEEXPONENTIAL,
00464 
00465    // 1 parameter, the mean. It is required that the mean is non-negative
00466    POISSON, 
00467 
00468    // 2 parameters, low and high.  Model a uniform random variable over the
00469    // closed interval. The low parameter is the lowest possible return value
00470    // and the high parameter can never be returned.  It is required that low <
00471    // high.
00472    UNIFORM,
00473 
00474    // 2 parameters, alpha and beta.  It is required that the alpha parameter is
00475    // not zero.
00476    WEIBULL,
00477 
00478    // An non-predefined random number distribution
00479    UNKNOWN,
00480    
00481    // Number of distributions
00482    NUMBER_TYPES};
00483 
00484   // A virtual destructor is needed to ensure that the destructor of derived
00485   // classes gets used. Not that this destructor does NOT delete the pointer to
00486   // the RNG object
00487   virtual ~Random();
00488 
00489   // This function returns a random number from the appropriate distribution.
00490   virtual Double operator()() = 0;
00491   
00492   // Functions that allow you to access and change the class that generates the
00493   // random bits.
00494   // <group>
00495   RNG* generator();
00496   void generator(RNG* p);
00497   // </group>
00498 
00499   // Convert the enumerator to a lower-case string. 
00500   static String asString(Random::Types type);
00501   
00502   // Convert the string to enumerator. The parsing of the string is case
00503   // insensitive. Returns the Random::UNKNOWN value if the string does not
00504   // cotrtrespond to any of the enumerators.
00505   static Random::Types asType(const String& str);
00506 
00507   // Convert the Random::Type enumerator to a specific object (derived from
00508   // Random but upcast to a Random object). Returns a null pointer if the
00509   // object could not be constructed. This will occur is the enumerator is
00510   // UNKNOWN or NUMBER_TYPES or there is insufficient memory. The caller of
00511   // this function is responsible for deleting the pointer.
00512   static Random* construct(Random::Types type, RNG* gen);
00513 
00514   // These function allow you to manipulate the parameters (mean variance etc.)
00515   // of random number distribution. The parameters() function returns the
00516   // current value, the setParameters function allows you to change the
00517   // parameters and the checkParameters function will return False if the
00518   // supplied parameters are not appropriate for the distribution.
00519   // <group>
00520   virtual void setParameters(const Vector<Double>& parms) = 0;
00521   virtual Vector<Double> parameters() const = 0;
00522   virtual Bool checkParameters(const Vector<Double>& parms) const = 0;
00523   // </group>
00524   
00525   // returns the default parameters for the specified distribution. Returns an
00526   // empty Vector if a non-predifined distribution is used.
00527   static Vector<Double> defaultParameters (Random::Types type);
00528   
00529 protected:
00530   //# This class contains pure virtual functions hence the constructor can only
00531   //# sensibly be used by derived classes.
00532   Random(RNG* generator);
00533 
00534   //# The RNG class provides the random bits.
00535   RNG* itsRNG;
00536 };
00537 
00538 inline Random::Random(RNG* gen)
00539 {
00540   itsRNG = gen;
00541 }
00542 
00543 inline RNG* Random::generator()
00544 {
00545   return itsRNG;
00546 }
00547 
00548 inline void Random::generator(RNG* p)
00549 {
00550   itsRNG = p;
00551 }
00552 
00553 
00554 // <summary> Binomial distribution </summary>
00555 
00556 // <synopsis>
00557 // The binomial distribution models successfully drawing items from a pool.
00558 // <src>n</src> is the number of items in the pool, and <src>p</src>, is the
00559 // probability of each item being successfully drawn.  The
00560 // <src>operator()</src> functions returns an integral value indicating the
00561 // number of items actually drawn from the pool. It is possible to get this
00562 // same value as an integer using the asInt function.
00563 
00564 // It is assumed that <src>n > 0</src> and <src>0 <= p <= 1</src> an AipsError
00565 // exception thrown if it is not true.  The remaining members allow you to read
00566 // and set the parameters.
00567 // </synopsis>
00568 
00569 // <example>
00570 // </example>
00571 //
00572 // <thrown>
00573 // <li> AipsError: if bad values for the arguments are given, as specified
00574 //      above.
00575 // </thrown>
00576 //
00577 // <todo asof="2000/05/09">
00578 //   <li> Nothing I hope!
00579 // </todo>
00580 
00581 class Binomial: public Random {
00582 public:
00583   // Construct a random number generator for a binomial distribution. The first
00584   // argument is a class that produces random bits. This pointer is NOT taken
00585   // over by this class and the user is responsible for deleting it. The second
00586   // and third arguments are the parameters are the Binomial distribution as
00587   // described in the synopsis.
00588   Binomial(RNG* gen, uInt n=1, Double p=0.5);
00589 
00590   // The destructor is trivial
00591   virtual ~Binomial();
00592 
00593   // Returns a value from the Binomial distribution. The returned value is a
00594   // non-negative integer and using the asInt function bypasses the conversion
00595   // to a floating point number.  
00596   // <group>
00597   virtual Double operator()();
00598   uInt asInt();
00599   // </group>
00600   
00601   // Functions that allow you to query and change the parameters of the
00602   // binomial distribution.
00603   // <group>
00604   uInt n() const;
00605   void n(uInt newN);
00606   void n(Double newN);
00607   Double p() const;
00608   void p(Double newP);
00609   // </group>
00610   
00611   // These function allow you to manipulate the parameters (n & p) described
00612   // above through the base class. The Vectors must always be of length two.
00613   // <group>
00614   virtual void setParameters(const Vector<Double>& parms);
00615   virtual Vector<Double> parameters() const;
00616   virtual Bool checkParameters(const Vector<Double>& parms) const;
00617   // </group>
00618 
00619 private:
00620   uInt itsN;
00621   Double itsP;
00622 };
00623 
00624 inline uInt Binomial::n() const {
00625   return itsN;
00626 }
00627 
00628 inline Double Binomial::p() const {
00629   return itsP;
00630 }
00631 
00632 // <summary>Discrete uniform distribution</summary>
00633 
00634 // <synopsis>
00635 
00636 // The <src>DiscreteUniform</src> class implements a quantized uniform random
00637 // variable over the closed interval ranging from <src>[low..high]</src>.  The
00638 // <src>low</src> parameter is the lowest possible return value and the
00639 // <src>high</src> parameter is the highest.  The <src>operator()</src>
00640 // functions returns a value from this distribution. It is possible to get this
00641 // same value as an integer using the asInt function.
00642 
00643 // It is assumed that low limit is less than the high limit and an AipsError
00644 // exception thrown if this is not true.  The remaining members allow you to
00645 // read and set the parameters.
00646 
00647 // </synopsis>
00648 
00649 // <example>
00650 // </example>
00651 //
00652 // <thrown>
00653 // <li> AipsError: if bad values for the arguments are given, as specified
00654 //      above.
00655 // </thrown>
00656 //
00657 // <todo asof="2000/05/09">
00658 //   <li> Nothing I hope!
00659 // </todo>
00660 
00661 class DiscreteUniform: public Random {
00662 public:
00663   // Construct a random number generator for a discrete uniform
00664   // distribution. The first argument is a class that produces random
00665   // bits. This pointer is NOT taken over by this class and the user is
00666   // responsible for deleting it. The second and third arguments define the
00667   // range of possible return values for this distribution as described in the
00668   // synopsis.
00669   DiscreteUniform(RNG* gen, Int low=-1, Int high=1);
00670   
00671   // The destructor is trivial
00672   virtual ~DiscreteUniform();
00673 
00674   // Returns a value from the discrete uniform distribution.  The returned
00675   // value is a integer and using the asInt function bypasses the conversion to
00676   // a floating point number.  
00677   // <group>
00678   virtual Double operator()();
00679   Int asInt();
00680   // </group>
00681   
00682   // Functions that allow you to query and change the parameters of the
00683   // discrete uniform distribution.  
00684   // <group>
00685   Int low() const;
00686   void low(Int x);
00687   Int high() const;
00688   void high(Int x);
00689   void range(Int low, Int high);
00690   // </group>
00691   
00692   // These function allow you to manipulate the parameters (low & high)
00693   // described above through the base class. The Vectors must always be of
00694   // length two.
00695   // <group>
00696   virtual void setParameters(const Vector<Double>& parms);
00697   virtual Vector<Double> parameters() const;
00698   virtual Bool checkParameters(const Vector<Double>& parms) const;
00699   // </group>
00700 
00701 private:
00702   static Double calcDelta(Int low, Int high);
00703   Int itsLow;
00704   Int itsHigh;
00705   Double itsDelta;
00706 };
00707 
00708 inline Int DiscreteUniform::low() const {
00709   return itsLow; 
00710 }
00711 
00712 inline Int DiscreteUniform::high() const {
00713   return itsHigh;
00714 }
00715 
00716 // <summary>Erlang distribution</summary>
00717 
00718 // <synopsis>
00719 // The <src>Erlang</src> class implements an Erlang distribution with mean
00720 // <src>mean</src> and variance <src>variance</src>.
00721 
00722 // It is assumed that the mean is non-zero and the variance is positive an
00723 // AipsError exception thrown if this is not true.  The remaining members allow
00724 // you to read and set the parameters.
00725 // </synopsis>
00726 
00727 // <example>
00728 // </example>
00729 //
00730 // <thrown>
00731 // <li> AipsError: if bad values for the arguments are given, as specified
00732 //      above.
00733 // </thrown>
00734 //
00735 // <todo asof="2000/05/09">
00736 //   <li> Nothing I hope!
00737 // </todo>
00738 
00739 class Erlang: public Random {
00740 public:
00741   // Construct a random number generator for an Erlang distribution. The first
00742   // argument is a class that produces random bits. This pointer is NOT taken
00743   // over by this class and the user is responsible for deleting it. The second
00744   // and third arguments define the parameters for this distribution as
00745   // described in the synopsis.
00746   Erlang(RNG* gen, Double mean=1.0, Double variance=1.0);
00747   
00748   // The destructor is trivial
00749   virtual ~Erlang();
00750 
00751   // Returns a value from the Erlang distribution.
00752   virtual Double operator()();
00753   
00754   // Functions that allow you to query and change the parameters of the
00755   // discrete uniform distribution.
00756   // <group>
00757   Double mean() const;
00758   void mean(Double x);
00759   Double variance() const;
00760   void variance(Double x);
00761   // </group>
00762 
00763   // These function allow you to manipulate the parameters (mean & variance)
00764   // described above through the base class. The Vectors must always be of
00765   // length two.
00766   // <group>
00767   virtual void setParameters(const Vector<Double>& parms);
00768   virtual Vector<Double> parameters() const;
00769   virtual Bool checkParameters(const Vector<Double>& parms) const;
00770   // </group>
00771 
00772 private:
00773   void setState();
00774   Double itsMean;
00775   Double itsVariance;
00776   Int itsK;
00777   Double itsA;
00778 };
00779 
00780 inline Erlang::Erlang(RNG* gen, Double mean, Double variance) 
00781   :Random(gen),
00782    itsMean(mean),
00783    itsVariance(variance)
00784 {
00785   setState();
00786 }
00787 
00788 inline Double Erlang::mean() const {
00789   return itsMean;
00790 }
00791 
00792 inline void Erlang::mean(Double x) {
00793   itsMean = x;
00794   setState(); 
00795 }
00796 
00797 inline Double Erlang::variance() const {
00798   return itsVariance;
00799 }
00800 
00801 inline void Erlang::variance(Double x) {
00802   itsVariance = x;
00803   setState();
00804 }
00805 
00806 // <summary> Discrete geometric distribution </summary>
00807 
00808 // <synopsis>
00809 // The <src>Geometric</src> class implements a discrete geometric distribution.
00810 // The <src>probability</src> is the only parameter.  The <src>operator()</src>
00811 // functions returns an non-negative integral value indicating the number of
00812 // uniform random samples actually drawn before one is obtained that is larger
00813 // than the given probability. To get this same value as an integer use the
00814 // asInt function.
00815 //
00816 // It is assumed that the probability is between zero and one 
00817 // <src>(0 <= probability < 1)</src> and and AipsError exception thrown if this
00818 // is not true.  The remaining function allow you to read and set the
00819 // parameters.
00820 // </synopsis>
00821 
00822 // <example>
00823 // </example>
00824 //
00825 // <thrown>
00826 // <li> AipsError: if bad values for the arguments are given, as specified
00827 //      above.
00828 // </thrown>
00829 //
00830 // <todo asof="2000/05/09">
00831 //   <li> Nothing I hope!
00832 // </todo>
00833 
00834 class Geometric: public Random {
00835 public:
00836   // Construct a random number generator for a geometric uniform
00837   // distribution. The first argument is a class that produces random
00838   // bits. This pointer is NOT taken over by this class and the user is
00839   // responsible for deleting it. The second argument defines the range of
00840   // possible return values for this distribution as described in the synopsis.
00841   Geometric(RNG* gen, Double probability=0.5);
00842   
00843   // The destructor is trivial
00844   virtual ~Geometric();
00845 
00846   // Returns a value from the geometric uniform distribution.  The returned
00847   // value is a non-negative integer and using the asInt function bypasses the
00848   // conversion to a floating point number.  
00849   // <group>
00850   virtual Double operator()();
00851   uInt asInt();
00852   // </group>
00853   
00854   // Functions that allow you to query and change the parameters of the
00855   // geometric uniform distribution.  
00856   // <group>
00857   Double probability() const;
00858   void probability(Double x);
00859   // </group>
00860   
00861   // These function allow you to manipulate the parameter (probability)
00862   // described above through the base class. The Vectors must always be of
00863   // length one.
00864   // <group>
00865   virtual void setParameters(const Vector<Double>& parms);
00866   virtual Vector<Double> parameters() const;
00867   virtual Bool checkParameters(const Vector<Double>& parms) const;
00868   // </group>
00869 
00870 private:
00871   Double itsProbability;
00872 };
00873 
00874 inline Double Geometric::probability() const {
00875   return itsProbability;
00876 }
00877 
00878 // <summary> Hypergeometric distribution </summary>
00879 
00880 // <synopsis>
00881 // The <src>HyperGeometric</src> class implements the hypergeometric
00882 // distribution.  The <src>mean</src> and <src>variance</src> are the
00883 // parameters of the distribution.  The <src>operator()</src> functions returns
00884 // a value from this distribution
00885 
00886 // It is assumed the variance is positive and that the mean is non-zero and not
00887 // bigger than the square-root of the variance. An AipsError exception is
00888 // thrown if this is not true.  The remaining members allow you to read and set
00889 // the parameters.
00890 // </synopsis>
00891 
00892 // <example>
00893 // </example>
00894 //
00895 // <thrown>
00896 // <li> AipsError: if bad values for the arguments are given, as specified
00897 //      above.
00898 // </thrown>
00899 //
00900 // <todo asof="2000/05/09">
00901 //   <li> Nothing I hope!
00902 // </todo>
00903 
00904 class HyperGeometric: public Random {
00905 public:
00906   // Construct a random number generator for an hypergeometric
00907   // distribution. The first argument is a class that produces random
00908   // bits. This pointer is NOT taken over by this class and the user is
00909   // responsible for deleting it. The second and third arguments define the
00910   // parameters for this distribution as described in the synopsis.
00911   HyperGeometric(RNG* gen, Double mean=0.5, Double variance=1.0);
00912   
00913   // The destructor is trivial
00914   virtual ~HyperGeometric();
00915 
00916   // Returns a value from the hypergeometric distribution.
00917   virtual Double operator()();
00918   
00919   // Functions that allow you to query and change the parameters of the
00920   // hypergeometric distribution.
00921   // <group>
00922   Double mean() const;
00923   void mean(Double x);
00924   Double variance() const;
00925   void variance(Double x);
00926   // </group>
00927   
00928   // These function allow you to manipulate the parameters (mean & variance)
00929   // described above through the base class. The Vectors must always be of
00930   // length two.
00931   // <group>
00932   virtual void setParameters(const Vector<Double>& parms);
00933   virtual Vector<Double> parameters() const;
00934   virtual Bool checkParameters(const Vector<Double>& parms) const;
00935   // </group>
00936 
00937 private:
00938   void setState();
00939   Double itsMean;
00940   Double itsVariance;
00941   Double itsP;
00942 };
00943 
00944 
00945 inline HyperGeometric::HyperGeometric(RNG* gen, Double mean, Double variance)
00946   :Random(gen),
00947    itsMean(mean),
00948    itsVariance(variance)
00949 {
00950   setState();
00951 }
00952 
00953 inline Double HyperGeometric::mean() const {
00954   return itsMean; 
00955 }
00956 
00957 inline void HyperGeometric::mean(Double x) {
00958   itsMean = x;
00959   setState();
00960 }
00961 
00962 inline Double HyperGeometric::variance() const {
00963   return itsVariance; 
00964 }
00965 
00966 inline void HyperGeometric::variance(Double x) {
00967   itsVariance = x;
00968   setState(); 
00969 }
00970 
00971 // <summary>Normal or Gaussian distribution </summary>
00972 
00973 // <synopsis>
00974 // The <src>Normal</src> class implements the normal or Gaussian distribution.
00975 // The <src>mean</src> and <src>variance</src> are the parameters of the
00976 // distribution.  The <src>operator()</src> functions returns a value from this
00977 // distribution
00978 
00979 // It is assumed that the supplied variance is positive and an AipsError
00980 // exception is thrown if this is not true.  The remaining members allow you to
00981 // read and set the parameters. The <src>LogNormal</src> class is derived from
00982 // this one.
00983 // </synopsis>
00984 
00985 // <example>
00986 // </example>
00987 //
00988 // <thrown>
00989 // <li> AipsError: if bad values for the arguments are given, as specified
00990 //      above.
00991 // </thrown>
00992 //
00993 // <todo asof="2000/05/09">
00994 //   <li> Nothing I hope!
00995 // </todo>
00996 
00997 class Normal: public Random {
00998 public:
00999   // Construct a random number generator for a normal distribution. The first
01000   // argument is a class that produces random bits. This pointer is NOT taken
01001   // over by this class and the user is responsible for deleting it. The second
01002   // and third arguments define the parameters for this distribution as
01003   // described in the synopsis.
01004   Normal(RNG* gen, Double mean=0.0, Double variance=1.0);
01005 
01006   // The destructor is trivial
01007   virtual ~Normal();
01008 
01009   // Returns a value from the normal distribution.
01010   virtual Double operator()();
01011   
01012   // Functions that allow you to query and change the parameters of the
01013   // normal distribution.
01014   // <group>
01015   virtual Double mean() const;
01016   virtual void mean(Double x);
01017   virtual Double variance() const;
01018   virtual void variance(Double x);
01019   // </group>
01020   
01021   // These function allow you to manipulate the parameters (mean & variance)
01022   // described above through the base class. The Vectors must always be of
01023   // length two.
01024   // <group>
01025   virtual void setParameters(const Vector<Double>& parms);
01026   virtual Vector<Double> parameters() const;
01027   virtual Bool checkParameters(const Vector<Double>& parms) const;
01028   // </group>
01029 
01030 private:
01031   Double itsMean;
01032   Double itsVariance;
01033   Double itsStdDev;
01034   Bool itsCached;
01035   Double itsCachedValue;
01036 };
01037 
01038 inline Double Normal::mean() const {
01039   return itsMean;
01040 }
01041 
01042 inline Double Normal::variance() const {
01043   return itsVariance;
01044 }
01045 
01046 // <summary> Logarithmic normal distribution </summary>
01047 
01048