casa
$Rev:20696$
|
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