casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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: Random.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
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 // <synopsis>
01049 // The <src>LogNormal</src> class implements the logaraithmic normal
01050 // distribution.  The <src>mean</src> and <src>variance</src> are the
01051 // parameters of the distribution. The <src>operator()</src> functions returns
01052 // a value from this distribution
01053 
01054 // It is assumed that the supplied variance is positive and an AipsError
01055 // exception is thrown if this is not true.  The remaining members allow you to
01056 // read and set the parameters.
01057 // </synopsis>
01058 
01059 // <example>
01060 // </example>
01061 //
01062 // <thrown>
01063 // <li> AipsError: if bad values for the arguments are given, as specified
01064 //      above.
01065 // </thrown>
01066 //
01067 // <todo asof="2000/05/09">
01068 //   <li> Nothing I hope!
01069 // </todo>
01070 
01071 class LogNormal: public Normal {
01072 public:
01073   // Construct a random number generator for a log-normal distribution. The
01074   // first argument is a class that produces random bits. This pointer is NOT
01075   // taken over by this class and the user is responsible for deleting it. The
01076   // second and third arguments define the parameters for this distribution as
01077   // described in the synopsis.
01078   LogNormal(RNG* gen, Double mean=1.0, Double variance=1.0);
01079 
01080   // The destructor is trivial
01081   virtual ~LogNormal();
01082 
01083   // Returns a value from the log-normal distribution.
01084   virtual Double operator()();
01085 
01086   // Functions that allow you to query and change the parameters of the
01087   // log-normal distribution.
01088   // <group>
01089   virtual Double mean() const;
01090   virtual void mean(Double x);
01091   virtual Double variance() const;
01092   virtual void variance(Double x);
01093   // </group>
01094 
01095   // These function allow you to manipulate the parameters (mean & variance)
01096   // described above through the base class. The Vectors must always be of
01097   // length two.
01098   // <group>
01099   virtual void setParameters(const Vector<Double>& parms);
01100   virtual Vector<Double> parameters() const;
01101   virtual Bool checkParameters(const Vector<Double>& parms) const;
01102   // </group>
01103 
01104 private:
01105   void setState();
01106   Double itsLogMean;
01107   Double itsLogVar;
01108 };
01109 
01110 inline Double LogNormal::mean() const {
01111   return itsLogMean;
01112 }
01113 
01114 inline Double LogNormal::variance() const {
01115   return itsLogVar;
01116 }
01117 
01118 // <summary>Negative exponential distribution</summary>
01119 
01120 // <synopsis>
01121 // The <src>NegativeExpntl</src> class implements a negative exponential
01122 // distribution.  The <src>mean</src> parameter, is the only parameter of this
01123 // distribution.  The <src>operator()</src> functions returns a value from this
01124 // distribution. The remaining members allow you to inspect and change the
01125 // mean.
01126 // </synopsis>
01127 
01128 // <example>
01129 // </example>
01130 //
01131 // <thrown>
01132 // <li> No exceptions are thrown by this class.
01133 // </thrown>
01134 //
01135 // <todo asof="2000/05/09">
01136 //   <li> Nothing I hope!
01137 // </todo>
01138 
01139 class NegativeExpntl: public Random {
01140 public:
01141   // Construct a random number generator for a negative exponential
01142   // distribution. The first argument is a class that produces random
01143   // bits. This pointer is NOT taken over by this class and the user is
01144   // responsible for deleting it. The second argument defines the parameters
01145   // for this distribution as described in the synopsis.
01146   NegativeExpntl(RNG* gen, Double mean=1.0);
01147 
01148   // The destructor is trivial
01149   virtual ~NegativeExpntl();
01150 
01151   // Returns a value from the negative exponential distribution.
01152   virtual Double operator()();
01153 
01154   // Functions that allow you to query and change the parameters of the
01155   // negative exponential distribution.
01156   // <group>
01157   Double mean() const;
01158   void mean(Double x);
01159   // </group>
01160   
01161   // These function allow you to manipulate the parameters (mean)
01162   // described above through the base class. The Vectors must always be of
01163   // length one.
01164   // <group>
01165   virtual void setParameters(const Vector<Double>& parms);
01166   virtual Vector<Double> parameters() const;
01167   virtual Bool checkParameters(const Vector<Double>& parms) const;
01168   // </group>
01169 
01170 private:
01171   Double itsMean;
01172 };
01173 
01174 inline Double NegativeExpntl::mean() const {
01175   return itsMean; 
01176 }
01177 
01178 // <summary> Poisson distribution </summary>
01179 // <synopsis>
01180 // The <src>Poisson</src> class implements a Poisson distribution.  The
01181 // <src>mean</src> parameter, is the only parameter of this distribution.  The
01182 // <src>operator()</src> functions returns a value from this distribution. The
01183 // remaining members allow you to inspect and change the mean.
01184 
01185 // It is assumed that the supplied mean is non-negative and an AipsError
01186 // exception is thrown if this is not true.  The remaining members allow you to
01187 // read and set the parameters.
01188 // </synopsis>
01189 
01190 // <example>
01191 // </example>
01192 //
01193 // <thrown>
01194 // <li> No exceptions are thrown by this class.
01195 // </thrown>
01196 //
01197 // <todo asof="2000/05/09">
01198 //   <li> Nothing I hope!
01199 // </todo>
01200 
01201 class Poisson: public Random {
01202 public:
01203   // Construct a random number generator for a Poisson distribution. The first
01204   // argument is a class that produces random bits. This pointer is NOT taken
01205   // over by this class and the user is responsible for deleting it. The second
01206   // argument defines the parameters for this distribution as described in the
01207   // synopsis.
01208   Poisson(RNG* gen, Double mean=0.0);
01209   
01210   // The destructor is trivial
01211   virtual ~Poisson();
01212 
01213   // Returns a value from the Poisson distribution. The returned value is a
01214   // non-negative integer and using the asInt function bypasses the conversion
01215   // to a floating point number.
01216   // <group>
01217   virtual Double operator()();
01218   uInt asInt();
01219   // </group>
01220   
01221   // Functions that allow you to query and change the parameters of the
01222   // Poisson distribution.
01223   // <group>
01224   Double mean() const;
01225   void mean(Double x);
01226   // </group>
01227   
01228   // These function allow you to manipulate the parameters (mean)
01229   // described above through the base class. The Vectors must always be of
01230   // length one.
01231   // <group>
01232   virtual void setParameters(const Vector<Double>& parms);
01233   virtual Vector<Double> parameters() const;
01234   virtual Bool checkParameters(const Vector<Double>& parms) const;
01235   // </group>
01236 
01237 private:
01238   Double itsMean;
01239 };
01240 
01241 inline Double Poisson::mean() const { 
01242   return itsMean;
01243 }
01244 
01245 // <summary>Uniform distribution</summary>
01246 
01247 // <synopsis>
01248 // The <src>Uniform</src> class implements a uniform random variable over the
01249 // copen interval ranging from <src>[low..high)</src>.  The <src>low</src>
01250 // parameter is the lowest possible return value and the <src>high</src>
01251 // parameter can never be returned.  The <src>operator()</src> functions
01252 // returns a value from this distribution.
01253 
01254 // It is assumed that low limit is less than the high limit and an AipsError
01255 // exception is thrown if this is not true.  The remaining members allow you to
01256 // read and set the parameters.
01257 
01258 // </synopsis>
01259 
01260 // <example>
01261 // </example>
01262 //
01263 // <thrown>
01264 // <li> AipsError: if bad values for the arguments are given, as specified
01265 //      above.
01266 // </thrown>
01267 //
01268 // <todo asof="2000/05/09">
01269 //   <li> Nothing I hope!
01270 // </todo>
01271 
01272 class Uniform: public Random {
01273 public:
01274   // Construct a random number generator for a uniform distribution. The first
01275   // argument is a class that produces random bits. This pointer is NOT taken
01276   // over by this class and the user is responsible for deleting it. The
01277   // remaining arguments define the parameters for this distribution as
01278   // described in the synopsis.
01279   Uniform(RNG* gen, Double low=-1.0, Double high=1.0);
01280 
01281   // The destructor is trivial
01282   virtual ~Uniform();
01283 
01284   // Returns a value from the uniform distribution. 
01285   virtual Double operator()();
01286   
01287   // Functions that allow you to query and change the parameters of the
01288   // uniform distribution.  
01289   // <group>
01290   Double low() const;
01291   void low(Double x);
01292   Double high() const;
01293   void high(Double x);
01294   void range(Double low, Double high);
01295   // </group>
01296 
01297   // These function allow you to manipulate the parameters (low & high)
01298   // described above through the base class. The Vectors must always be of
01299   // length two.
01300   // <group>
01301   virtual void setParameters(const Vector<Double>& parms);
01302   virtual Vector<Double> parameters() const;
01303   virtual Bool checkParameters(const Vector<Double>& parms) const;
01304   // </group>
01305 
01306 private:
01307   static Double calcDelta(Double low, Double high);
01308   Double itsLow;
01309   Double itsHigh;
01310   Double itsDelta;
01311 };
01312 
01313 inline Double Uniform::low() const {
01314   return itsLow;
01315 }
01316 
01317 inline Double Uniform::high() const {
01318   return itsHigh;
01319 }
01320 
01321 // <summary>Weibull distribution</summary>
01322 
01323 // <synopsis> 
01324 
01325 // The <src>Weibull</src> class implements a weibull distribution with
01326 // parameters <src>alpha</src> and <src>beta</src>.  The first parameter to the
01327 // class constructor is <src>alpha</src>, and the second parameter is
01328 // <src>beta</src>.  It is assumed that the alpha parameter is not zero and an
01329 // AipsError exception is thrown if this is not true.  The remaining members
01330 // allow you to read and set the parameters.
01331 // </synopsis>
01332 
01333 // <example>
01334 // </example>
01335 //
01336 // <thrown>
01337 // <li> AipsError: if bad values for the arguments are given, as specified
01338 //      above.
01339 // </thrown>
01340 //
01341 // <todo asof="2000/05/09">
01342 //   <li> Nothing I hope!
01343 // </todo>
01344 
01345 class Weibull: public Random {
01346 public:
01347   // Construct a random number generator for a uniform distribution. The first
01348   // argument is a class that produces random bits. This pointer is NOT taken
01349   // over by this class and the user is responsible for deleting it. The
01350   // remaining arguments define the parameters for this distribution as
01351   // described in the synopsis.
01352   Weibull(RNG* gen, Double alpha=1.0, Double beta=1.0);
01353   
01354   // The destructor is trivial
01355   virtual ~Weibull();
01356 
01357   // Returns a value from the Weiball distribution. 
01358   virtual Double operator()();
01359   
01360   // Functions that allow you to query and change the parameters of the
01361   // Weiball distribution.  
01362   // <group>
01363   Double alpha() const;
01364   void alpha(Double x);
01365   Double beta() const;
01366   void beta(Double x);
01367   // </group>
01368 
01369   // These function allow you to manipulate the parameters (alpha & beta)
01370   // described above through the base class. The Vectors must always be of
01371   // length two.
01372   // <group>
01373   virtual void setParameters(const Vector<Double>& parms);
01374   virtual Vector<Double> parameters() const;
01375   virtual Bool checkParameters(const Vector<Double>& parms) const;
01376   // </group>
01377 
01378 private:
01379   void setState();
01380   Double itsAlpha;
01381   Double itsBeta;
01382   Double itsInvAlpha;
01383 };
01384 
01385 inline Double Weibull::alpha() const {
01386   return itsAlpha;
01387 }
01388 
01389 inline Double Weibull::beta() const {
01390   return itsBeta; 
01391 }
01392 
01393 
01394 } //# NAMESPACE CASA - END
01395 
01396 #endif