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