1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2006 Georgia Tech Research Corporation 4 * Copyright (c) 2011 Mathieu Lacage 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation; 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 * Authors: Rajib Bhattacharjea<raj.b@gatech.edu> 20 * Hadi Arbabi<marbabi@cs.odu.edu> 21 * Mathieu Lacage <mathieu.lacage@gmail.com> 22 * 23 * Modified by Mitch Watrous <watrous@u.washington.edu> 24 * 25 */ 26 #ifndef RANDOM_VARIABLE_STREAM_H 27 #define RANDOM_VARIABLE_STREAM_H 28 29 #include "type-id.h" 30 #include "object.h" 31 #include "attribute-helper.h" 32 #include <stdint.h> 33 34 /** 35 * \file 36 * \ingroup randomvariable 37 * ns3::RandomVariableStream declaration, and related classes. 38 */ 39 40 namespace ns3 { 41 42 /** 43 * \ingroup core 44 * \defgroup randomvariable Random Variables 45 * 46 * \brief ns-3 random numbers are provided via instances of 47 * ns3::RandomVariableStream. 48 * 49 * - By default, ns-3 simulations use a fixed seed; if there is any 50 * randomness in the simulation, each run of the program will yield 51 * identical results unless the seed and/or run number is changed. 52 * - In ns-3.3 and earlier, ns-3 simulations used a random seed by default; 53 * this marks a change in policy starting with ns-3.4. 54 * - In ns-3.14 and earlier, ns-3 simulations used a different wrapper 55 * class called ns3::RandomVariable. This implementation is documented 56 * above under Legacy Random Variables. As of ns-3.15, this class has 57 * been replaced by ns3::RandomVariableStream; the underlying 58 * pseudo-random number generator has not changed. 59 * - To obtain randomness across multiple simulation runs, you must 60 * either set the seed differently or set the run number differently. 61 * To set a seed, call ns3::RngSeedManager::SetSeed() at the beginning 62 * of the program; to set a run number with the same seed, call 63 * ns3::RngSeedManager::SetRun() at the beginning of the program. 64 * - Each RandomVariableStream used in ns-3 has a virtual random number 65 * generator associated with it; all random variables use either 66 * a fixed or random seed based on the use of the global seed. 67 * - If you intend to perform multiple runs of the same scenario, 68 * with different random numbers, please be sure to read the manual 69 * section on how to perform independent replications. 70 */ 71 72 class RngStream; 73 74 /** 75 * \ingroup randomvariable 76 * \brief The basic uniform Random Number Generator (RNG). 77 * 78 * \note The underlying random number generation method used 79 * by ns-3 is the RngStream code by Pierre L'Ecuyer at 80 * the University of Montreal. 81 * 82 * ns-3 has a rich set of random number generators that allow stream 83 * numbers to be set deterministically if desired. Class 84 * RandomVariableStream defines the base class functionality required 85 * for all such random number generators. 86 * 87 * By default, the underlying generator is seeded all the time with 88 * the same seed value and run number coming from the ns3::GlobalValue 89 * \ref GlobalValueRngSeed "RngSeed" and \ref GlobalValueRngRun 90 * "RngRun". Also by default, the stream number value for the 91 * underlying RngStream is automatically allocated. 92 * 93 * Instances can be configured to return "antithetic" values. 94 * See the documentation for the specific distributions to see 95 * how this modifies the returned values. 96 */ 97 class RandomVariableStream : public Object 98 { 99 public: 100 /** 101 * \brief Register this type. 102 * \return The object TypeId. 103 */ 104 static TypeId GetTypeId (void); 105 /** 106 * \brief Default constructor. 107 */ 108 RandomVariableStream (); 109 /** 110 * \brief Destructor. 111 */ 112 virtual ~RandomVariableStream (); 113 114 /** 115 * \brief Specifies the stream number for the RngStream. 116 * \param [in] stream The stream number for the RngStream. 117 * -1 means "allocate a stream number automatically". 118 */ 119 void SetStream (int64_t stream); 120 121 /** 122 * \brief Returns the stream number for the RngStream. 123 * \return The stream number for the RngStream. 124 * -1 means this stream was allocated automatically. 125 */ 126 int64_t GetStream (void) const; 127 128 /** 129 * \brief Specify whether antithetic values should be generated. 130 * \param [in] isAntithetic If \c true antithetic value will be generated. 131 */ 132 void SetAntithetic (bool isAntithetic); 133 134 /** 135 * \brief Check if antithetic values will be generated. 136 * \return \c true if antithetic values will be generated. 137 */ 138 bool IsAntithetic (void) const; 139 140 /** 141 * \brief Get the next random value as a double drawn from the distribution. 142 * \return A floating point random value. 143 */ 144 virtual double GetValue (void) = 0; 145 146 /** 147 * \brief Get the next random value as an integer drawn from the distribution. 148 * \return An integer random value. 149 */ 150 virtual uint32_t GetInteger (void) = 0; 151 152 protected: 153 /** 154 * \brief Get the pointer to the underlying RngStream. 155 * \return The underlying RngStream 156 */ 157 RngStream * Peek (void) const; 158 159 private: 160 /** 161 * Copy constructor. These objects are not copyable. 162 * 163 * \param [in] o The RandomVariableStream to copy in construction. 164 * \internal 165 * Theoretically, it is possible to give them good copy semantics 166 * but not enough time to iron out the details. 167 */ 168 RandomVariableStream (const RandomVariableStream &o); 169 /** 170 * Assignment operator. These objects can't be copied by assignment. 171 * 172 * \param [in] o The RandomVariableStream to copy. 173 * \return lvalue RandomVariableStream. 174 * 175 * \internal 176 * Theoretically, it is possible to give them good copy semantics 177 * but not enough time to iron out the details. 178 */ 179 RandomVariableStream &operator = (const RandomVariableStream &o); 180 181 /** Pointer to the underlying RngStream. */ 182 RngStream *m_rng; 183 184 /** Indicates if antithetic values should be generated by this RNG stream. */ 185 bool m_isAntithetic; 186 187 /** The stream number for the RngStream. */ 188 int64_t m_stream; 189 190 }; // class RandomVariableStream 191 192 193 /** 194 * \ingroup randomvariable 195 * \brief The uniform distribution Random Number Generator (RNG). 196 * 197 * This class supports the creation of objects that return random numbers 198 * from a fixed uniform distribution. It also supports the generation of 199 * single random numbers from various uniform distributions. 200 * 201 * The output range is \f$[min, max)\f$ for floating point values, 202 * (\c max <i>excluded</i>), and \f$[min, max]\f$ (\c max <i>included</i>) 203 * for integral values. 204 * 205 * \par Example 206 * 207 * Here is an example of how to use this class: 208 * \code 209 * double min = 0.0; 210 * double max = 10.0; 211 * 212 * Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> (); 213 * x->SetAttribute ("Min", DoubleValue (min)); 214 * x->SetAttribute ("Max", DoubleValue (max)); 215 * 216 * // The values returned by a uniformly distributed random 217 * // variable should always be within the range 218 * // 219 * // [min, max) . 220 * // 221 * double value = x->GetValue (); 222 * \endcode 223 * 224 * \par Antithetic Values. 225 * 226 * Normally this RNG returns values \f$x\f$ in the interval \f$[min,max)\f$. 227 * If an instance of this RNG is configured to return antithetic values, 228 * the actual value returned is calculated as follows: 229 * 230 * - Compute the initial random value \f$x\f$ as normal. 231 * - Compute the distance from the maximum, \f$y = max - x\f$ 232 * - Return \f$x' = min + y = min + (max - x)\f$: 233 */ 234 class UniformRandomVariable : public RandomVariableStream 235 { 236 public: 237 /** 238 * \brief Register this type. 239 * \return The object TypeId. 240 */ 241 static TypeId GetTypeId (void); 242 243 /** 244 * \brief Creates a uniform distribution RNG with the default range. 245 */ 246 UniformRandomVariable (); 247 248 /** 249 * \brief Get the lower bound on randoms returned by GetValue(void). 250 * \return The lower bound on values from GetValue(void). 251 */ 252 double GetMin (void) const; 253 254 /** 255 * \brief Get the upper bound on values returned by GetValue(void). 256 * \return The upper bound on values from GetValue(void). 257 */ 258 double GetMax (void) const; 259 260 /** 261 * \brief Get the next random value, as a double in the specified range 262 * \f$[min, max)\f$. 263 * 264 * \note The upper limit is excluded from the output range. 265 * 266 * \param [in] min Low end of the range (included). 267 * \param [in] max High end of the range (excluded). 268 * \return A floating point random value. 269 */ 270 double GetValue (double min, double max); 271 272 /** 273 * \brief Get the next random value, as an unsigned integer in the 274 * specified range \f$[min, max]\f$. 275 * 276 * \note The upper limit is included in the output range. 277 * 278 * \param [in] min Low end of the range. 279 * \param [in] max High end of the range. 280 * \return A random unsigned integer value. 281 */ 282 uint32_t GetInteger (uint32_t min, uint32_t max); 283 284 // Inherited from RandomVariableStream 285 /** 286 * \brief Get the next random value as a double drawn from the distribution. 287 * \return A floating point random value. 288 * \note The upper limit is excluded from the output range. 289 */ 290 virtual double GetValue (void); 291 /** 292 * \brief Get the next random value as an integer drawn from the distribution. 293 * \return An integer random value. 294 * \note The upper limit is included in the output range. 295 */ 296 virtual uint32_t GetInteger (void); 297 298 private: 299 /** The lower bound on values that can be returned by this RNG stream. */ 300 double m_min; 301 302 /** The upper bound on values that can be returned by this RNG stream. */ 303 double m_max; 304 305 }; // class UniformRandomVariable 306 307 308 /** 309 * \ingroup randomvariable 310 * \brief The Random Number Generator (RNG) that returns a constant. 311 * 312 * This RNG returns the same value for every sample. 313 * 314 * \par Antithetic Values. 315 * 316 * This RNG ignores the antithetic setting. 317 */ 318 class ConstantRandomVariable : public RandomVariableStream 319 { 320 public: 321 /** 322 * \brief Register this type. 323 * \return The object TypeId. 324 */ 325 static TypeId GetTypeId (void); 326 327 /** 328 * \brief Creates a constant RNG with the default constant value. 329 */ 330 ConstantRandomVariable (); 331 332 /** 333 * \brief Get the constant value returned by this RNG stream. 334 * \return The constant value. 335 */ 336 double GetConstant (void) const; 337 338 /** 339 * \brief Get the next random value, as a double equal to the argument. 340 * \param [in] constant The value to return. 341 * \return The floating point argument. 342 */ 343 double GetValue (double constant); 344 /** 345 * \brief Get the next random value, as an integer equal to the argument. 346 * \param [in] constant The value to return. 347 * \return The integer argument. 348 */ 349 uint32_t GetInteger (uint32_t constant); 350 351 // Inherited from RandomVariableStream 352 /* \note This RNG always returns the same value. */ 353 virtual double GetValue (void); 354 /* \note This RNG always returns the same value. */ 355 virtual uint32_t GetInteger (void); 356 357 private: 358 /** The constant value returned by this RNG stream. */ 359 double m_constant; 360 361 }; // class ConstantRandomVariable 362 363 364 /** 365 * \ingroup randomvariable 366 * \brief The Random Number Generator (RNG) that returns a pattern of 367 * sequential values. 368 * 369 * This RNG has four configuration attributes: 370 * 371 * - An increment, \c Increment. 372 * - A consecutive repeat numer, \c Consecutive. 373 * - The minimum value, \c Min. 374 * - The maximum value, \c Max. 375 * 376 * The RNG starts at the \c Min value. Each return value is 377 * repeated \c Consecutive times, before advancing by the \c Increment. 378 * When the \c Increment would cause the value to equal or exceed 379 * \c Max it is reset to \c Min first. 380 * 381 * For example, if an instance is configured with: 382 * 383 * Attribute | Value 384 * :---------- | -----: 385 * Min | 2 386 * Max | 13 387 * Increment | 4 388 * Consecutive | 3 389 * 390 * The sequence will repeat this pattern: 2 2 2 6 6 6 10 10 10. 391 * 392 * Notice that \c Max will be a strict upper bound on the values: 393 * all values in the sequence will be less than \c Max. 394 * 395 * \par Antithetic Values. 396 * 397 * This RNG ignores the antithetic setting. 398 */ 399 class SequentialRandomVariable : public RandomVariableStream 400 { 401 public: 402 /** 403 * \brief Register this type. 404 * \return The object TypeId. 405 */ 406 static TypeId GetTypeId (void); 407 408 /** 409 * \brief Creates a sequential RNG with the default values 410 * for the sequence parameters. 411 */ 412 SequentialRandomVariable (); 413 414 /** 415 * \brief Get the first value of the sequence. 416 * \return The first value of the sequence. 417 */ 418 double GetMin (void) const; 419 420 /** 421 * \brief Get the limit of the sequence, which is (at least) 422 * one more than the last value of the sequence. 423 * \return The limit of the sequence. 424 */ 425 double GetMax (void) const; 426 427 /** 428 * \brief Get the increment for the sequence. 429 * \return The increment between distinct values for the sequence. 430 */ 431 Ptr<RandomVariableStream> GetIncrement (void) const; 432 433 /** 434 * \brief Get the number of times each distinct value of the sequence 435 * is repeated before incrementing to the next value. 436 * \return The number of times each value is repeated. 437 */ 438 uint32_t GetConsecutive (void) const; 439 440 // Inherited from RandomVariableStream 441 virtual double GetValue (void); 442 virtual uint32_t GetInteger (void); 443 444 private: 445 /** The first value of the sequence. */ 446 double m_min; 447 448 /** Strict upper bound on the sequence. */ 449 double m_max; 450 451 /** Increment between distinct values. */ 452 Ptr<RandomVariableStream> m_increment; 453 454 /** The number of times each distinct value is repeated. */ 455 uint32_t m_consecutive; 456 457 /** The current sequence value. */ 458 double m_current; 459 460 /** The number of times the current distinct value has been repeated. */ 461 uint32_t m_currentConsecutive; 462 463 /** Indicates if the current sequence value has been properly initialized. */ 464 bool m_isCurrentSet; 465 466 }; // class SequentialRandomVariable 467 468 469 /** 470 * \ingroup randomvariable 471 * \brief The exponential distribution Random Number Generator (RNG). 472 * 473 * This class supports the creation of objects that return random numbers 474 * from a fixed exponential distribution. It also supports the generation of 475 * single random numbers from various exponential distributions. 476 * 477 * The probability density function of an exponential variable 478 * is defined as: 479 * \f[ 480 * P(x) dx = \alpha e^{-\alpha x} dx, \quad x \in [0, +\infty) 481 * \f] 482 * over the interval \f$[0, +\infty)\f$, where \f$ \alpha = \frac{1}{Mean} \f$ 483 * and \c Mean is a configurable attribute. 484 * 485 * The normal RNG value \f$x\f$ is calculated by 486 * 487 * \f[ 488 * x = - 1/\alpha \log(u) 489 * \f] 490 * 491 * where \f$u\f$ is a uniform random variable on \f$[0,1)\f$. 492 * 493 * \par Bounded Distribution 494 * 495 * Since exponential distributions can theoretically return unbounded 496 * values, it is sometimes useful to specify a fixed upper limit. The 497 * bounded version is defined over the interval \f$[0,b]\f$ as: 498 * 499 * \f[ 500 * P(x; b) dx = \alpha e^{-\alpha x} dx \quad x \in [0,b] 501 * \f] 502 * 503 * where the \c Bound \f$b\f$ is a configurable attribute. 504 * 505 * Note that in this case the true mean of the distribution is smaller 506 * than the nominal mean value: 507 * 508 * \f[ 509 * <X: P(x; b)> = 1/\alpha - b/(e^{\alpha \, b} -1) 510 * \f] 511 * 512 * \par Example 513 * 514 * Here is an example of how to use this class: 515 * \code 516 * double mean = 3.14; 517 * double bound = 0.0; 518 * 519 * Ptr<ExponentialRandomVariable> x = CreateObject<ExponentialRandomVariable> (); 520 * x->SetAttribute ("Mean", DoubleValue (mean)); 521 * x->SetAttribute ("Bound", DoubleValue (bound)); 522 * 523 * // The expected value for the mean of the values returned by an 524 * // exponentially distributed random variable is equal to mean. 525 * double value = x->GetValue (); 526 * \endcode 527 * 528 * \par Antithetic Values. 529 * 530 * The antithetic value is calculated from 531 * 532 * \f[ 533 * x' = - mean * \log(1 - u), 534 * \f] 535 * 536 * where again \f$u\f$ is a uniform random variable on \f$[0,1)\f$. 537 */ 538 class ExponentialRandomVariable : public RandomVariableStream 539 { 540 public: 541 /** 542 * \brief Register this type. 543 * \return The object TypeId. 544 */ 545 static TypeId GetTypeId (void); 546 547 /** 548 * \brief Creates an exponential distribution RNG with the default 549 * values for the mean and upper bound. 550 */ 551 ExponentialRandomVariable (); 552 553 /** 554 * \brief Get the configured mean value of this RNG. 555 * 556 * \note This will not be the actual mean if the distribution is 557 * truncated by a bound. 558 * \return The configured mean value. 559 */ 560 double GetMean (void) const; 561 562 /** 563 * \brief Get the configured upper bound of this RNG. 564 * \return The upper bound. 565 */ 566 double GetBound (void) const; 567 568 /** 569 * \brief Get the next random value, as a double from 570 * the exponential distribution with the specified mean and upper bound. 571 * \param [in] mean Mean value of the unbounded exponential distribution. 572 * \param [in] bound Upper bound on values returned. 573 * \return A floating point random value. 574 */ 575 double GetValue (double mean, double bound); 576 577 /** 578 * \brief Get the next random value, as an unsigned integer from 579 * the exponential distribution with the specified mean and upper bound. 580 * \param [in] mean Mean value of the unbounded exponential distribution. 581 * \param [in] bound Upper bound on values returned. 582 * \return A random unsigned integer value. 583 */ 584 uint32_t GetInteger (uint32_t mean, uint32_t bound); 585 586 // Inherited from RandomVariableStream 587 virtual double GetValue (void); 588 virtual uint32_t GetInteger (void); 589 590 private: 591 /** The mean value of the unbounded exponential distribution. */ 592 double m_mean; 593 594 /** The upper bound on values that can be returned by this RNG stream. */ 595 double m_bound; 596 597 }; // class ExponentialRandomVariable 598 599 600 /** 601 * \ingroup randomvariable 602 * \brief The Pareto distribution Random Number Generator (RNG). 603 * 604 * This class supports the creation of objects that return random numbers 605 * from a fixed Pareto distribution. It also supports the generation of 606 * single random numbers from various Pareto distributions. 607 * 608 * The probability density function of a Pareto variable is defined 609 * over the range [\f$x_m\f$,\f$+\infty\f$) as: \f$ k \frac{x_m^k}{x^{k+1}}\f$ 610 * where \f$x_m > 0\f$ is called the scale parameter and \f$ k > 0\f$ 611 * is called the Pareto index or shape. 612 * 613 * The parameter \f$ x_m \f$ can be inferred from the mean and the parameter \f$ k \f$ 614 * with the equation \f$ x_m = mean \frac{k-1}{k}, k > 1\f$. 615 * 616 * Since Pareto distributions can theoretically return unbounded values, 617 * it is sometimes useful to specify a fixed upper limit. Note however 618 * when the upper limit is specified, the true mean of the distribution 619 * is slightly smaller than the mean value specified. 620 * 621 * Here is an example of how to use this class: 622 * \code 623 * double scale = 5.0; 624 * double shape = 2.0; 625 * 626 * Ptr<ParetoRandomVariable> x = CreateObject<ParetoRandomVariable> (); 627 * x->SetAttribute ("Scale", DoubleValue (scale)); 628 * x->SetAttribute ("Shape", DoubleValue (shape)); 629 * 630 * // The expected value for the mean of the values returned by a 631 * // Pareto distributed random variable is 632 * // 633 * // shape * scale 634 * // E[value] = --------------- , 635 * // shape - 1 636 * 637 * double value = x->GetValue (); 638 * \endcode 639 */ 640 class ParetoRandomVariable : public RandomVariableStream 641 { 642 public: 643 /** 644 * \brief Register this type. 645 * \return The object TypeId. 646 */ 647 static TypeId GetTypeId (void); 648 649 /** 650 * \brief Creates a Pareto distribution RNG with the default 651 * values for the mean, the shape, and upper bound. 652 */ 653 ParetoRandomVariable (); 654 655 /** 656 * \brief Returns the scale parameter for the Pareto distribution returned by this RNG stream. 657 * \return The scale parameter for the Pareto distribution returned by this RNG stream. 658 */ 659 double GetScale (void) const; 660 661 /** 662 * \brief Returns the shape parameter for the Pareto distribution returned by this RNG stream. 663 * \return The shape parameter for the Pareto distribution returned by this RNG stream. 664 */ 665 double GetShape (void) const; 666 667 /** 668 * \brief Returns the upper bound on values that can be returned by this RNG stream. 669 * \return The upper bound on values that can be returned by this RNG stream. 670 */ 671 double GetBound (void) const; 672 673 /** 674 * \brief Returns a random double from a Pareto distribution with the specified scale, shape, and upper bound. 675 * \param [in] scale Mean parameter for the Pareto distribution. 676 * \param [in] shape Shape parameter for the Pareto distribution. 677 * \param [in] bound Upper bound on values returned. 678 * \return A floating point random value. 679 * 680 * Note that antithetic values are being generated if 681 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 682 * over [0,1] and 683 * 684 * \f[ 685 * x = \frac{scale}{u^{\frac{1}{shape}}} 686 * \f] 687 * 688 * is a value that would be returned normally. 689 * 690 * The value returned in the antithetic case, \f$x'\f$, is 691 * calculated as 692 * 693 * \f[ 694 * x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} , 695 * \f] 696 * 697 * which now involves the distance \f$u\f$ is from 1 in the denominator. 698 */ 699 double GetValue (double scale, double shape, double bound); 700 701 /** 702 * \brief Returns a random unsigned integer from a Pareto distribution with the specified mean, shape, and upper bound. 703 * \param [in] scale Scale parameter for the Pareto distribution. 704 * \param [in] shape Shape parameter for the Pareto distribution. 705 * \param [in] bound Upper bound on values returned. 706 * \return A random unsigned integer value. 707 * 708 * Note that antithetic values are being generated if 709 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 710 * over [0,1] and 711 * 712 * \f[ 713 * x = \frac{scale}{u^{\frac{1}{shape}}} 714 * \f] 715 * 716 * is a value that would be returned normally. 717 * 718 * The value returned in the antithetic case, \f$x'\f$, is 719 * calculated as 720 * 721 * \f[ 722 * x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} , 723 * \f] 724 * 725 * which now involves the distance \f$u\f$ is from 1 in the denominator. 726 */ 727 uint32_t GetInteger (uint32_t scale, uint32_t shape, uint32_t bound); 728 729 /** 730 * \brief Returns a random double from a Pareto distribution with the current mean, shape, and upper bound. 731 * \return A floating point random value. 732 * 733 * Note that antithetic values are being generated if 734 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 735 * over [0,1] and 736 * 737 * \f[ 738 * x = \frac{scale}{u^{\frac{1}{shape}}} 739 * \f] 740 * 741 * is a value that would be returned normally, where 742 * 743 * \f[ 744 * scale = mean * (shape - 1.0) / shape . 745 * \f] 746 * 747 * The value returned in the antithetic case, \f$x'\f$, is 748 * calculated as 749 * 750 * \f[ 751 * x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} , 752 * \f] 753 * 754 * which now involves the distance \f$u\f$ is from 1 in the denominator. 755 * 756 * Note that we have to re-implement this method here because the method is 757 * overloaded above for the three-argument variant and the c++ name resolution 758 * rules don't work well with overloads split between parent and child 759 * classes. 760 */ 761 virtual double GetValue (void); 762 763 /** 764 * \brief Returns a random unsigned integer from a Pareto distribution with the current mean, shape, and upper bound. 765 * \return A random unsigned integer value. 766 * 767 * Note that antithetic values are being generated if 768 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 769 * over [0,1] and 770 * 771 * \f[ 772 * x = \frac{scale}{u^{\frac{1}{shape}}} 773 * \f] 774 * 775 * is a value that would be returned normally. 776 * 777 * The value returned in the antithetic case, \f$x'\f$, is 778 * calculated as 779 * 780 * \f[ 781 * x' = \frac{scale}{{(1 - u)}^{\frac{1}{shape}}} , 782 * \f] 783 * 784 * which now involves the distance \f$u\f$ is from 1 in the denominator. 785 */ 786 virtual uint32_t GetInteger (void); 787 788 private: 789 /** The scale parameter for the Pareto distribution returned by this RNG stream. */ 790 double m_scale; 791 792 /** The shape parameter for the Pareto distribution returned by this RNG stream. */ 793 double m_shape; 794 795 /** The upper bound on values that can be returned by this RNG stream. */ 796 double m_bound; 797 798 }; // class ParetoRandomVariable 799 800 801 /** 802 * \ingroup randomvariable 803 * \brief The Weibull distribution Random Number Generator (RNG) that allows stream numbers to be set deterministically. 804 * 805 * This class supports the creation of objects that return random numbers 806 * from a fixed Weibull distribution. It also supports the generation of 807 * single random numbers from various Weibull distributions. 808 * 809 * The probability density function is defined over the interval [0, \f$+\infty\f$] 810 * as: \f$ \frac{k}{\lambda}\left(\frac{x}{\lambda}\right)^{k-1}e^{-\left(\frac{x}{\lambda}\right)^k} \f$ 811 * where \f$ k > 0\f$ is the shape parameter and \f$ \lambda > 0\f$ is the scale parameter. The 812 * specified mean is related to the scale and shape parameters by the following relation: 813 * \f$ mean = \lambda\Gamma\left(1+\frac{1}{k}\right) \f$ where \f$ \Gamma \f$ is the Gamma function. 814 * 815 * Since Weibull distributions can theoretically return unbounded values, 816 * it is sometimes useful to specify a fixed upper limit. Note however 817 * when the upper limit is specified, the true mean of the distribution 818 * is slightly smaller than the mean value specified. 819 * 820 * Here is an example of how to use this class: 821 * \code 822 * double scale = 5.0; 823 * double shape = 1.0; 824 * 825 * Ptr<WeibullRandomVariable> x = CreateObject<WeibullRandomVariable> (); 826 * x->SetAttribute ("Scale", DoubleValue (scale)); 827 * x->SetAttribute ("Shape", DoubleValue (shape)); 828 * 829 * // The expected value for the mean of the values returned by a 830 * // Weibull distributed random variable is 831 * // 832 * // E[value] = scale * Gamma(1 + 1 / shape) , 833 * // 834 * // where Gamma() is the Gamma function. Note that 835 * // 836 * // Gamma(n) = (n - 1)! 837 * // 838 * // if n is a positive integer. 839 * // 840 * // For this example, 841 * // 842 * // Gamma(1 + 1 / shape) = Gamma(1 + 1 / 1) 843 * // = Gamma(2) 844 * // = (2 - 1)! 845 * // = 1 846 * // 847 * // which means 848 * // 849 * // E[value] = scale . 850 * // 851 * double value = x->GetValue (); 852 * \endcode 853 */ 854 class WeibullRandomVariable : public RandomVariableStream 855 { 856 public: 857 /** 858 * \brief Register this type. 859 * \return The object TypeId. 860 */ 861 static TypeId GetTypeId (void); 862 863 /** 864 * \brief Creates a Weibull distribution RNG with the default 865 * values for the scale, shape, and upper bound. 866 */ 867 WeibullRandomVariable (); 868 869 /** 870 * \brief Returns the scale parameter for the Weibull distribution returned by this RNG stream. 871 * \return The scale parameter for the Weibull distribution returned by this RNG stream. 872 */ 873 double GetScale (void) const; 874 875 /** 876 * \brief Returns the shape parameter for the Weibull distribution returned by this RNG stream. 877 * \return The shape parameter for the Weibull distribution returned by this RNG stream. 878 */ 879 double GetShape (void) const; 880 881 /** 882 * \brief Returns the upper bound on values that can be returned by this RNG stream. 883 * \return The upper bound on values that can be returned by this RNG stream. 884 */ 885 double GetBound (void) const; 886 887 /** 888 * \brief Returns a random double from a Weibull distribution with the specified scale, shape, and upper bound. 889 * \param [in] scale Scale parameter for the Weibull distribution. 890 * \param [in] shape Shape parameter for the Weibull distribution. 891 * \param [in] bound Upper bound on values returned. 892 * \return A floating point random value. 893 * 894 * Note that antithetic values are being generated if 895 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 896 * over [0,1] and 897 * 898 * \f[ 899 * x = scale * {(-\log(u))}^{\frac{1}{shape}} 900 * \f] 901 * 902 * is a value that would be returned normally, then \f$(1 - u\f$) is 903 * the distance that \f$u\f$ would be from \f$1\f$. The value 904 * returned in the antithetic case, \f$x'\f$, is calculated as 905 * 906 * \f[ 907 * x' = scale * {(-\log(1 - u))}^{\frac{1}{shape}} , 908 * \f] 909 * 910 * which now involves the log of the distance \f$u\f$ is from 1. 911 */ 912 double GetValue (double scale, double shape, double bound); 913 914 /** 915 * \brief Returns a random unsigned integer from a Weibull distribution with the specified scale, shape, and upper bound. 916 * \param [in] scale Scale parameter for the Weibull distribution. 917 * \param [in] shape Shape parameter for the Weibull distribution. 918 * \param [in] bound Upper bound on values returned. 919 * \return A random unsigned integer value. 920 * 921 * Note that antithetic values are being generated if 922 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 923 * over [0,1] and 924 * 925 * \f[ 926 * x = scale * {(-\log(u))}^{\frac{1}{shape}} 927 * \f] 928 * 929 * is a value that would be returned normally, then \f$(1 - u\f$) is 930 * the distance that \f$u\f$ would be from \f$1\f$. The value 931 * returned in the antithetic case, \f$x'\f$, is calculated as 932 * 933 * \f[ 934 * x' = scale * {(-\log(1 - u))}^{\frac{1}{shape}} , 935 * \f] 936 * 937 * which now involves the log of the distance \f$u\f$ is from 1. 938 */ 939 uint32_t GetInteger (uint32_t scale, uint32_t shape, uint32_t bound); 940 941 /** 942 * \brief Returns a random double from a Weibull distribution with the current scale, shape, and upper bound. 943 * \return A floating point random value. 944 * 945 * Note that antithetic values are being generated if 946 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 947 * over [0,1] and 948 * 949 * \f[ 950 * x = scale * {(-\log(u))}^{\frac{1}{shape}} 951 * \f] 952 * 953 * is a value that would be returned normally, then \f$(1 - u\f$) is 954 * the distance that \f$u\f$ would be from \f$1\f$. The value 955 * returned in the antithetic case, \f$x'\f$, is calculated as 956 * 957 * \f[ 958 * x' = scale * {(-\log(1 - u))}^{\frac{1}{shape}} , 959 * \f] 960 * 961 * which now involves the log of the distance \f$u\f$ is from 1. 962 * 963 * Note that we have to re-implement this method here because the method is 964 * overloaded above for the three-argument variant and the c++ name resolution 965 * rules don't work well with overloads split between parent and child 966 * classes. 967 */ 968 virtual double GetValue (void); 969 970 /** 971 * \brief Returns a random unsigned integer from a Weibull distribution with the current scale, shape, and upper bound. 972 * \return A random unsigned integer value. 973 * 974 * Note that antithetic values are being generated if 975 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 976 * over [0,1] and 977 * 978 * \f[ 979 * x = scale * {(-\log(u))}^{\frac{1}{shape}} 980 * \f] 981 * 982 * is a value that would be returned normally, then \f$(1 - u\f$) is 983 * the distance that \f$u\f$ would be from \f$1\f$. The value 984 * returned in the antithetic case, \f$x'\f$, is calculated as 985 * 986 * \f[ 987 * x' = scale * {(-\log(1 - u))}^{\frac{1}{shape}} , 988 * \f] 989 * 990 * which now involves the log of the distance \f$u\f$ is from 1. 991 */ 992 virtual uint32_t GetInteger (void); 993 994 private: 995 /** The scale parameter for the Weibull distribution returned by this RNG stream. */ 996 double m_scale; 997 998 /** The shape parameter for the Weibull distribution returned by this RNG stream. */ 999 double m_shape; 1000 1001 /** The upper bound on values that can be returned by this RNG stream. */ 1002 double m_bound; 1003 1004 }; // class WeibullRandomVariable 1005 1006 1007 /** 1008 * \ingroup randomvariable 1009 * \brief The normal (Gaussian) distribution Random Number Generator 1010 * (RNG) that allows stream numbers to be set deterministically. 1011 * 1012 * This class supports the creation of objects that return random numbers 1013 * from a fixed normal distribution. It also supports the generation of 1014 * single random numbers from various normal distributions. 1015 * 1016 * The density probability function is defined over the interval (\f$-\infty\f$,\f$+\infty\f$) 1017 * as: \f$ \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{s\sigma^2}}\f$ 1018 * where \f$ mean = \mu \f$ and \f$ variance = \sigma^2 \f$ 1019 * 1020 * Since normal distributions can theoretically return unbounded 1021 * values, it is sometimes useful to specify a fixed bound. The 1022 * NormalRandomVariable is bounded symmetrically about the mean by 1023 * this bound, i.e. its values are confined to the interval 1024 * [\f$mean-bound\f$,\f$mean+bound\f$]. 1025 * 1026 * Here is an example of how to use this class: 1027 * \code 1028 * double mean = 5.0; 1029 * double variance = 2.0; 1030 * 1031 * Ptr<NormalRandomVariable> x = CreateObject<NormalRandomVariable> (); 1032 * x->SetAttribute ("Mean", DoubleValue (mean)); 1033 * x->SetAttribute ("Variance", DoubleValue (variance)); 1034 * 1035 * // The expected value for the mean of the values returned by a 1036 * // normally distributed random variable is equal to mean. 1037 * double value = x->GetValue (); 1038 * \endcode 1039 */ 1040 class NormalRandomVariable : public RandomVariableStream 1041 { 1042 public: 1043 /** Large constant to bound the range. */ 1044 static const double INFINITE_VALUE; 1045 1046 /** 1047 * \brief Register this type. 1048 * \return The object TypeId. 1049 */ 1050 static TypeId GetTypeId (void); 1051 1052 /** 1053 * \brief Creates a normal distribution RNG with the default 1054 * values for the mean, variance, and bound. 1055 */ 1056 NormalRandomVariable (); 1057 1058 /** 1059 * \brief Returns the mean value for the normal distribution returned by this RNG stream. 1060 * \return The mean value for the normal distribution returned by this RNG stream. 1061 */ 1062 double GetMean (void) const; 1063 1064 /** 1065 * \brief Returns the variance value for the normal distribution returned by this RNG stream. 1066 * \return The variance value for the normal distribution returned by this RNG stream. 1067 */ 1068 double GetVariance (void) const; 1069 1070 /** 1071 * \brief Returns the bound on values that can be returned by this RNG stream. 1072 * \return The bound on values that can be returned by this RNG stream. 1073 */ 1074 double GetBound (void) const; 1075 1076 /** 1077 * \brief Returns a random double from a normal distribution with the specified mean, variance, and bound. 1078 * \param [in] mean Mean value for the normal distribution. 1079 * \param [in] variance Variance value for the normal distribution. 1080 * \param [in] bound Bound on values returned. 1081 * \return A floating point random value. 1082 * 1083 * Note that antithetic values are being generated if m_isAntithetic 1084 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1085 * over [0,1], then the values that would be returned normally, \f$x1\f$ and \f$x2\f$, are calculated as follows: 1086 * 1087 * \f{eqnarray*}{ 1088 * v1 & = & 2 * u1 - 1 \\ 1089 * v2 & = & 2 * u2 - 1 \\ 1090 * w & = & v1 * v1 + v2 * v2 \\ 1091 * y & = & \sqrt{\frac{-2 * \log(w)}{w}} \\ 1092 * x1 & = & mean + v1 * y * \sqrt{variance} \\ 1093 * x2 & = & mean + v2 * y * \sqrt{variance} . 1094 * \f} 1095 * 1096 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1097 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1098 * The antithetic values returned, \f$x1'\f$ and \f$x2'\f$, are 1099 * calculated as follows: 1100 * 1101 * \f{eqnarray*}{ 1102 * v1' & = & 2 * (1 - u1) - 1 \\ 1103 * v2' & = & 2 * (1 - u2) - 1 \\ 1104 * w' & = & v1' * v1' + v2' * v2' \\ 1105 * y' & = & \sqrt{\frac{-2 * \log(w')}{w'}} \\ 1106 * x1' & = & mean + v1' * y' * \sqrt{variance} \\ 1107 * x2' & = & mean + v2' * y' * \sqrt{variance} , 1108 * \f} 1109 * 1110 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1111 */ 1112 double GetValue (double mean, double variance, double bound = NormalRandomVariable::INFINITE_VALUE); 1113 1114 /** 1115 * \brief Returns a random unsigned integer from a normal distribution with the specified mean, variance, and bound. 1116 * \param [in] mean Mean value for the normal distribution. 1117 * \param [in] variance Variance value for the normal distribution. 1118 * \param [in] bound Bound on values returned. 1119 * \return A random unsigned integer value. 1120 * 1121 * Note that antithetic values are being generated if m_isAntithetic 1122 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1123 * over [0,1], then the values that would be returned normally, \f$x1\f$ and \f$x2\f$, are calculated as follows: 1124 * 1125 * \f{eqnarray*}{ 1126 * v1 & = & 2 * u1 - 1 \\ 1127 * v2 & = & 2 * u2 - 1 \\ 1128 * w & = & v1 * v1 + v2 * v2 \\ 1129 * y & = & \sqrt{\frac{-2 * \log(w)}{w}} \\ 1130 * x1 & = & mean + v1 * y * \sqrt{variance} \\ 1131 * x2 & = & mean + v2 * y * \sqrt{variance} . 1132 * \f} 1133 * 1134 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1135 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1136 * The antithetic values returned, \f$x1'\f$ and \f$x2'\f$, are 1137 * calculated as follows: 1138 * 1139 * \f{eqnarray*}{ 1140 * v1' & = & 2 * (1 - u1) - 1 \\ 1141 * v2' & = & 2 * (1 - u2) - 1 \\ 1142 * w' & = & v1' * v1' + v2' * v2' \\ 1143 * y' & = & \sqrt{\frac{-2 * \log(w')}{w'}} \\ 1144 * x1' & = & mean + v1' * y' * \sqrt{variance} \\ 1145 * x2' & = & mean + v2' * y' * \sqrt{variance} , 1146 * \f} 1147 * 1148 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1149 */ 1150 uint32_t GetInteger (uint32_t mean, uint32_t variance, uint32_t bound); 1151 1152 /** 1153 * \brief Returns a random double from a normal distribution with the current mean, variance, and bound. 1154 * \return A floating point random value. 1155 * 1156 * Note that antithetic values are being generated if m_isAntithetic 1157 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1158 * over [0,1], then the values that would be returned normally, \f$x1\f$ and \f$x2\f$, are calculated as follows: 1159 * 1160 * \f{eqnarray*}{ 1161 * v1 & = & 2 * u1 - 1 \\ 1162 * v2 & = & 2 * u2 - 1 \\ 1163 * w & = & v1 * v1 + v2 * v2 \\ 1164 * y & = & \sqrt{\frac{-2 * \log(w)}{w}} \\ 1165 * x1 & = & mean + v1 * y * \sqrt{variance} \\ 1166 * x2 & = & mean + v2 * y * \sqrt{variance} . 1167 * \f} 1168 * 1169 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1170 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1171 * The antithetic values returned, \f$x1'\f$ and \f$x2'\f$, are 1172 * calculated as follows: 1173 * 1174 * \f{eqnarray*}{ 1175 * v1' & = & 2 * (1 - u1) - 1 \\ 1176 * v2' & = & 2 * (1 - u2) - 1 \\ 1177 * w' & = & v1' * v1' + v2' * v2' \\ 1178 * y' & = & \sqrt{\frac{-2 * \log(w')}{w'}} \\ 1179 * x1' & = & mean + v1' * y' * \sqrt{variance} \\ 1180 * x2' & = & mean + v2' * y' * \sqrt{variance} , 1181 * \f} 1182 * 1183 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1184 * 1185 * Note that we have to re-implement this method here because the method is 1186 * overloaded above for the three-argument variant and the c++ name resolution 1187 * rules don't work well with overloads split between parent and child 1188 * classes. 1189 */ 1190 virtual double GetValue (void); 1191 1192 /** 1193 * \brief Returns a random unsigned integer from a normal distribution with the current mean, variance, and bound. 1194 * \return A random unsigned integer value. 1195 * 1196 * Note that antithetic values are being generated if m_isAntithetic 1197 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1198 * over [0,1], then the values that would be returned normally, \f$x1\f$ and \f$x2\f$, are calculated as follows: 1199 * 1200 * \f{eqnarray*}{ 1201 * v1 & = & 2 * u1 - 1 \\ 1202 * v2 & = & 2 * u2 - 1 \\ 1203 * w & = & v1 * v1 + v2 * v2 \\ 1204 * y & = & \sqrt{\frac{-2 * \log(w)}{w}} \\ 1205 * x1 & = & mean + v1 * y * \sqrt{variance} \\ 1206 * x2 & = & mean + v2 * y * \sqrt{variance} . 1207 * \f} 1208 * 1209 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1210 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1211 * The antithetic values returned, \f$x1'\f$ and \f$x2'\f$, are 1212 * calculated as follows: 1213 * 1214 * \f{eqnarray*}{ 1215 * v1' & = & 2 * (1 - u1) - 1 \\ 1216 * v2' & = & 2 * (1 - u2) - 1 \\ 1217 * w' & = & v1' * v1' + v2' * v2' \\ 1218 * y' & = & \sqrt{\frac{-2 * \log(w')}{w'}} \\ 1219 * x1' & = & mean + v1' * y' * \sqrt{variance} \\ 1220 * x2' & = & mean + v2' * y' * \sqrt{variance} , 1221 * \f} 1222 * 1223 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1224 */ 1225 virtual uint32_t GetInteger (void); 1226 1227 private: 1228 /** The mean value for the normal distribution returned by this RNG stream. */ 1229 double m_mean; 1230 1231 /** The variance value for the normal distribution returned by this RNG stream. */ 1232 double m_variance; 1233 1234 /** The bound on values that can be returned by this RNG stream. */ 1235 double m_bound; 1236 1237 /** True if the next value is valid. */ 1238 bool m_nextValid; 1239 1240 /** The algorithm produces two values at a time. Cache parameters for possible reuse.*/ 1241 double m_v2; 1242 /** The algorithm produces two values at a time. Cache parameters for possible reuse.*/ 1243 double m_y; 1244 1245 }; // class NormalRandomVariable 1246 1247 1248 /** 1249 * \ingroup randomvariable 1250 * \brief The log-normal distribution Random Number Generator 1251 * (RNG) that allows stream numbers to be set deterministically. 1252 * 1253 * This class supports the creation of objects that return random numbers 1254 * from a fixed log-normal distribution. It also supports the generation of 1255 * single random numbers from various log-normal distributions. 1256 * 1257 * LogNormalRandomVariable defines a random variable with a log-normal 1258 * distribution. If one takes the natural logarithm of random 1259 * variable following the log-normal distribution, the obtained values 1260 * follow a normal distribution. 1261 * 1262 * The probability density function is defined over the interval [0,\f$+\infty\f$) as: 1263 * \f$ \frac{1}{x\sigma\sqrt{2\pi}} e^{-\frac{(ln(x) - \mu)^2}{2\sigma^2}}\f$ 1264 * where \f$ mean = e^{\mu+\frac{\sigma^2}{2}} \f$ and 1265 * \f$ variance = (e^{\sigma^2}-1)e^{2\mu+\sigma^2}\f$ 1266 * 1267 * The \f$ \mu \f$ and \f$ \sigma \f$ parameters can be calculated instead if 1268 * the mean and variance are known with the following equations: 1269 * \f$ \mu = ln(mean) - \frac{1}{2}ln\left(1+\frac{variance}{mean^2}\right)\f$, and, 1270 * \f$ \sigma = \sqrt{ln\left(1+\frac{variance}{mean^2}\right)}\f$ 1271 * 1272 * Here is an example of how to use this class: 1273 * \code 1274 * double mu = 5.0; 1275 * double sigma = 2.0; 1276 * 1277 * Ptr<LogNormalRandomVariable> x = CreateObject<LogNormalRandomVariable> (); 1278 * x->SetAttribute ("Mu", DoubleValue (mu)); 1279 * x->SetAttribute ("Sigma", DoubleValue (sigma)); 1280 * 1281 * // The expected value for the mean of the values returned by a 1282 * // log-normally distributed random variable is equal to 1283 * // 1284 * // 2 1285 * // mu + sigma / 2 1286 * // E[value] = e . 1287 * // 1288 * double value = x->GetValue (); 1289 * \endcode 1290 */ 1291 class LogNormalRandomVariable : public RandomVariableStream 1292 { 1293 public: 1294 /** 1295 * \brief Register this type. 1296 * \return The object TypeId. 1297 */ 1298 static TypeId GetTypeId (void); 1299 1300 /** 1301 * \brief Creates a log-normal distribution RNG with the default 1302 * values for mu and sigma. 1303 */ 1304 LogNormalRandomVariable (); 1305 1306 /** 1307 * \brief Returns the mu value for the log-normal distribution returned by this RNG stream. 1308 * \return The mu value for the log-normal distribution returned by this RNG stream. 1309 */ 1310 double GetMu (void) const; 1311 1312 /** 1313 * \brief Returns the sigma value for the log-normal distribution returned by this RNG stream. 1314 * \return The sigma value for the log-normal distribution returned by this RNG stream. 1315 */ 1316 double GetSigma (void) const; 1317 1318 /** 1319 * \brief Returns a random double from a log-normal distribution with the specified mu and sigma. 1320 * \param [in] mu Mu value for the log-normal distribution. 1321 * \param [in] sigma Sigma value for the log-normal distribution. 1322 * \return A floating point random value. 1323 * 1324 * Note that antithetic values are being generated if m_isAntithetic 1325 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1326 * over [0,1], then the value that would be returned normally, \f$x\f$, is calculated as follows: 1327 * 1328 * \f{eqnarray*}{ 1329 * v1 & = & -1 + 2 * u1 \\ 1330 * v2 & = & -1 + 2 * u2 \\ 1331 * r2 & = & v1 * v1 + v2 * v2 \\ 1332 * normal & = & v1 * \sqrt{\frac{-2.0 * \log{r2}}{r2}} \\ 1333 * x & = & \exp{sigma * normal + mu} . 1334 * \f} 1335 * 1336 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1337 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1338 * The antithetic value returned, \f$x'\f$, is calculated as 1339 * follows: 1340 * 1341 * \f{eqnarray*}{ 1342 * v1' & = & -1 + 2 * (1 - u1) \\ 1343 * v2' & = & -1 + 2 * (1 - u2) \\ 1344 * r2' & = & v1' * v1' + v2' * v2' \\ 1345 * normal' & = & v1' * \sqrt{\frac{-2.0 * \log{r2'}}{r2'}} \\ 1346 * x' & = & \exp{sigma * normal' + mu} . 1347 * \f} 1348 * 1349 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1350 */ 1351 double GetValue (double mu, double sigma); 1352 1353 /** 1354 * \brief Returns a random unsigned integer from a log-normal distribution with the specified mu and sigma. 1355 * \param [in] mu Mu value for the log-normal distribution. 1356 * \param [in] sigma Sigma value for the log-normal distribution. 1357 * \return A random unsigned integer value. 1358 * 1359 * Note that antithetic values are being generated if m_isAntithetic 1360 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1361 * over [0,1], then the value that would be returned normally, \f$x\f$, is calculated as follows: 1362 * 1363 * \f{eqnarray*}{ 1364 * v1 & = & -1 + 2 * u1 \\ 1365 * v2 & = & -1 + 2 * u2 \\ 1366 * r2 & = & v1 * v1 + v2 * v2 \\ 1367 * normal & = & v1 * \sqrt{\frac{-2.0 * \log{r2}}{r2}} \\ 1368 * x & = & \exp{sigma * normal + mu} . 1369 * \f} 1370 * 1371 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1372 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1373 * The antithetic value returned, \f$x'\f$, is calculated as 1374 * follows: 1375 * 1376 * \f{eqnarray*}{ 1377 * v1' & = & -1 + 2 * (1 - u1) \\ 1378 * v2' & = & -1 + 2 * (1 - u2) \\ 1379 * r2' & = & v1' * v1' + v2' * v2' \\ 1380 * normal' & = & v1' * \sqrt{\frac{-2.0 * \log{r2'}}{r2'}} \\ 1381 * x' & = & \exp{sigma * normal' + mu} . 1382 * \f} 1383 * 1384 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1385 */ 1386 uint32_t GetInteger (uint32_t mu, uint32_t sigma); 1387 1388 /** 1389 * \brief Returns a random double from a log-normal distribution with the current mu and sigma. 1390 * \return A floating point random value. 1391 * 1392 * Note that antithetic values are being generated if m_isAntithetic 1393 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1394 * over [0,1], then the value that would be returned normally, \f$x\f$, is calculated as follows: 1395 * 1396 * \f{eqnarray*}{ 1397 * v1 & = & -1 + 2 * u1 \\ 1398 * v2 & = & -1 + 2 * u2 \\ 1399 * r2 & = & v1 * v1 + v2 * v2 \\ 1400 * normal & = & v1 * \sqrt{\frac{-2.0 * \log{r2}}{r2}} \\ 1401 * x & = & \exp{sigma * normal + mu} . 1402 * \f} 1403 * 1404 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1405 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1406 * The antithetic value returned, \f$x'\f$, is calculated as 1407 * follows: 1408 * 1409 * \f{eqnarray*}{ 1410 * v1' & = & -1 + 2 * (1 - u1) \\ 1411 * v2' & = & -1 + 2 * (1 - u2) \\ 1412 * r2' & = & v1' * v1' + v2' * v2' \\ 1413 * normal' & = & v1' * \sqrt{\frac{-2.0 * \log{r2'}}{r2'}} \\ 1414 * x' & = & \exp{sigma * normal' + mu} . 1415 * \f} 1416 * 1417 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1418 * 1419 * Note that we have to re-implement this method here because the method is 1420 * overloaded above for the two-argument variant and the c++ name resolution 1421 * rules don't work well with overloads split between parent and child 1422 * classes. 1423 */ 1424 virtual double GetValue (void); 1425 1426 /** 1427 * \brief Returns a random unsigned integer from a log-normal distribution with the current mu and sigma. 1428 * \return A random unsigned integer value. 1429 * 1430 * Note that antithetic values are being generated if m_isAntithetic 1431 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1432 * over [0,1], then the value that would be returned normally, \f$x\f$, is calculated as follows: 1433 * 1434 * \f{eqnarray*}{ 1435 * v1 & = & -1 + 2 * u1 \\ 1436 * v2 & = & -1 + 2 * u2 \\ 1437 * r2 & = & v1 * v1 + v2 * v2 \\ 1438 * normal & = & v1 * \sqrt{\frac{-2.0 * \log{r2}}{r2}} \\ 1439 * x & = & \exp{sigma * normal + mu} . 1440 * \f} 1441 * 1442 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1443 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1444 * The antithetic value returned, \f$x'\f$, is calculated as 1445 * follows: 1446 * 1447 * \f{eqnarray*}{ 1448 * v1' & = & -1 + 2 * (1 - u1) \\ 1449 * v2' & = & -1 + 2 * (1 - u2) \\ 1450 * r2' & = & v1' * v1' + v2' * v2' \\ 1451 * normal' & = & v1' * \sqrt{\frac{-2.0 * \log{r2'}}{r2'}} \\ 1452 * x' & = & \exp{sigma * normal' + mu} . 1453 * \f} 1454 * 1455 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1456 */ 1457 virtual uint32_t GetInteger (void); 1458 1459 private: 1460 /** The mu value for the log-normal distribution returned by this RNG stream. */ 1461 double m_mu; 1462 1463 /** The sigma value for the log-normal distribution returned by this RNG stream. */ 1464 double m_sigma; 1465 1466 }; // class LogNormalRandomVariable 1467 1468 1469 /** 1470 * \ingroup randomvariable 1471 * \brief The gamma distribution Random Number Generator (RNG) that 1472 * allows stream numbers to be set deterministically. 1473 * 1474 * This class supports the creation of objects that return random numbers 1475 * from a fixed gamma distribution. It also supports the generation of 1476 * single random numbers from various gamma distributions. 1477 * 1478 * The probability density function is defined over the interval [0,\f$+\infty\f$) as: 1479 * \f$ x^{\alpha-1} \frac{e^{-\frac{x}{\beta}}}{\beta^\alpha \Gamma(\alpha)}\f$ 1480 * where \f$ mean = \alpha\beta \f$ and 1481 * \f$ variance = \alpha \beta^2\f$ 1482 * 1483 * Here is an example of how to use this class: 1484 * \code 1485 * double alpha = 5.0; 1486 * double beta = 2.0; 1487 * 1488 * Ptr<GammaRandomVariable> x = CreateObject<GammaRandomVariable> (); 1489 * x->SetAttribute ("Alpha", DoubleValue (alpha)); 1490 * x->SetAttribute ("Beta", DoubleValue (beta)); 1491 * 1492 * // The expected value for the mean of the values returned by a 1493 * // gammaly distributed random variable is equal to 1494 * // 1495 * // E[value] = alpha * beta . 1496 * // 1497 * double value = x->GetValue (); 1498 * \endcode 1499 */ 1500 class GammaRandomVariable : public RandomVariableStream 1501 { 1502 public: 1503 /** 1504 * \brief Register this type. 1505 * \return The object TypeId. 1506 */ 1507 static TypeId GetTypeId (void); 1508 1509 /** 1510 * \brief Creates a gamma distribution RNG with the default values 1511 * for alpha and beta. 1512 */ 1513 GammaRandomVariable (); 1514 1515 /** 1516 * \brief Returns the alpha value for the gamma distribution returned by this RNG stream. 1517 * \return The alpha value for the gamma distribution returned by this RNG stream. 1518 */ 1519 double GetAlpha (void) const; 1520 1521 /** 1522 * \brief Returns the beta value for the gamma distribution returned by this RNG stream. 1523 * \return The beta value for the gamma distribution returned by this RNG stream. 1524 */ 1525 double GetBeta (void) const; 1526 1527 /** 1528 * \brief Returns a random double from a gamma distribution with the specified alpha and beta. 1529 * \param [in] alpha Alpha value for the gamma distribution. 1530 * \param [in] beta Beta value for the gamma distribution. 1531 * \return A floating point random value. 1532 * 1533 * Note that antithetic values are being generated if m_isAntithetic 1534 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1535 * and \f$x\f$ is a value that would be returned normally, then 1536 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1537 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1538 * which is the distance \f$u\f$ is from the 1. 1539 */ 1540 double GetValue (double alpha, double beta); 1541 1542 /** 1543 * \brief Returns a random unsigned integer from a gamma distribution with the specified alpha and beta. 1544 * \param [in] alpha Alpha value for the gamma distribution. 1545 * \param [in] beta Beta value for the gamma distribution. 1546 * \return A random unsigned integer value. 1547 * 1548 * Note that antithetic values are being generated if m_isAntithetic 1549 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1550 * and \f$x\f$ is a value that would be returned normally, then 1551 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1552 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1553 * which is the distance \f$u\f$ is from the 1. 1554 */ 1555 uint32_t GetInteger (uint32_t alpha, uint32_t beta); 1556 1557 /** 1558 * \brief Returns a random double from a gamma distribution with the current alpha and beta. 1559 * \return A floating point random value. 1560 * 1561 * Note that antithetic values are being generated if m_isAntithetic 1562 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1563 * and \f$x\f$ is a value that would be returned normally, then 1564 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1565 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1566 * which is the distance \f$u\f$ is from the 1. 1567 * 1568 * Note that we have to re-implement this method here because the method is 1569 * overloaded above for the two-argument variant and the c++ name resolution 1570 * rules don't work well with overloads split between parent and child 1571 * classes. 1572 */ 1573 virtual double GetValue (void); 1574 1575 /** 1576 * \brief Returns a random unsigned integer from a gamma distribution with the current alpha and beta. 1577 * \return A random unsigned integer value. 1578 * 1579 * Note that antithetic values are being generated if m_isAntithetic 1580 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1581 * and \f$x\f$ is a value that would be returned normally, then 1582 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1583 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1584 * which is the distance \f$u\f$ is from the 1. 1585 */ 1586 virtual uint32_t GetInteger (void); 1587 1588 private: 1589 /** 1590 * \brief Returns a random double from a normal distribution with the specified mean, variance, and bound. 1591 * \param [in] mean Mean value for the normal distribution. 1592 * \param [in] variance Variance value for the normal distribution. 1593 * \param [in] bound Bound on values returned. 1594 * \return A floating point random value. 1595 * 1596 * Note that antithetic values are being generated if m_isAntithetic 1597 * is equal to true. If \f$u1\f$ and \f$u2\f$ are uniform variables 1598 * over [0,1], then the values that would be returned normally, \f$x1\f$ and \f$x2\f$, are calculated as follows: 1599 * 1600 * \f{eqnarray*}{ 1601 * v1 & = & 2 * u1 - 1 \\ 1602 * v2 & = & 2 * u2 - 1 \\ 1603 * w & = & v1 * v1 + v2 * v2 \\ 1604 * y & = & \sqrt{\frac{-2 * \log(w)}{w}} \\ 1605 * x1 & = & mean + v1 * y * \sqrt{variance} \\ 1606 * x2 & = & mean + v2 * y * \sqrt{variance} . 1607 * \f} 1608 * 1609 * For the antithetic case, \f$(1 - u1\f$) and \f$(1 - u2\f$) are 1610 * the distances that \f$u1\f$ and \f$u2\f$ would be from \f$1\f$. 1611 * The antithetic values returned, \f$x1'\f$ and \f$x2'\f$, are 1612 * calculated as follows: 1613 * 1614 * \f{eqnarray*}{ 1615 * v1' & = & 2 * (1 - u1) - 1 \\ 1616 * v2' & = & 2 * (1 - u2) - 1 \\ 1617 * w' & = & v1' * v1' + v2' * v2' \\ 1618 * y' & = & \sqrt{\frac{-2 * \log(w')}{w'}} \\ 1619 * x1' & = & mean + v1' * y' * \sqrt{variance} \\ 1620 * x2' & = & mean + v2' * y' * \sqrt{variance} , 1621 * \f} 1622 * 1623 * which now involves the distances \f$u1\f$ and \f$u2\f$ are from 1. 1624 */ 1625 double GetNormalValue (double mean, double variance, double bound); 1626 1627 /** The alpha value for the gamma distribution returned by this RNG stream. */ 1628 double m_alpha; 1629 1630 /** The beta value for the gamma distribution returned by this RNG stream. */ 1631 double m_beta; 1632 1633 /** True if the next normal value is valid. */ 1634 bool m_nextValid; 1635 1636 /** The algorithm produces two values at a time. Cache parameters for possible reuse.*/ 1637 double m_v2; 1638 /** The algorithm produces two values at a time. Cache parameters for possible reuse.*/ 1639 double m_y; 1640 1641 }; // class GammaRandomVariable 1642 1643 1644 /** 1645 * \ingroup randomvariable 1646 * \brief The Erlang distribution Random Number Generator (RNG) that 1647 * allows stream numbers to be set deterministically. 1648 * 1649 * This class supports the creation of objects that return random numbers 1650 * from a fixed Erlang distribution. It also supports the generation of 1651 * single random numbers from various Erlang distributions. 1652 * 1653 * The Erlang distribution is a special case of the Gamma distribution where k 1654 * (= alpha) is a non-negative integer. Erlang distributed variables can be 1655 * generated using a much faster algorithm than gamma variables. 1656 * 1657 * The probability density function is defined over the interval [0,\f$+\infty\f$) as: 1658 * \f$ \frac{x^{k-1} e^{-\frac{x}{\lambda}}}{\lambda^k (k-1)!}\f$ 1659 * where \f$ mean = k \lambda \f$ and 1660 * \f$ variance = k \lambda^2\f$ 1661 * 1662 * Here is an example of how to use this class: 1663 * \code 1664 * uint32_t k = 5; 1665 * double lambda = 2.0; 1666 * 1667 * Ptr<ErlangRandomVariable> x = CreateObject<ErlangRandomVariable> (); 1668 * x->SetAttribute ("K", IntegerValue (k)); 1669 * x->SetAttribute ("Lambda", DoubleValue (lambda)); 1670 * 1671 * // The expected value for the mean of the values returned by a 1672 * // Erlangly distributed random variable is equal to 1673 * // 1674 * // E[value] = k * lambda . 1675 * // 1676 * double value = x->GetValue (); 1677 * \endcode 1678 */ 1679 class ErlangRandomVariable : public RandomVariableStream 1680 { 1681 public: 1682 /** 1683 * \brief Register this type. 1684 * \return The object TypeId. 1685 */ 1686 static TypeId GetTypeId (void); 1687 1688 /** 1689 * \brief Creates an Erlang distribution RNG with the default values 1690 * for k and lambda. 1691 */ 1692 ErlangRandomVariable (); 1693 1694 /** 1695 * \brief Returns the k value for the Erlang distribution returned by this RNG stream. 1696 * \return The k value for the Erlang distribution returned by this RNG stream. 1697 */ 1698 uint32_t GetK (void) const; 1699 1700 /** 1701 * \brief Returns the lambda value for the Erlang distribution returned by this RNG stream. 1702 * \return The lambda value for the Erlang distribution returned by this RNG stream. 1703 */ 1704 double GetLambda (void) const; 1705 1706 /** 1707 * \brief Returns a random double from an Erlang distribution with the specified k and lambda. 1708 * \param [in] k K value for the Erlang distribution. 1709 * \param [in] lambda Lambda value for the Erlang distribution. 1710 * \return A floating point random value. 1711 * 1712 * Note that antithetic values are being generated if m_isAntithetic 1713 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1714 * and \f$x\f$ is a value that would be returned normally, then 1715 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1716 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1717 * which is the distance \f$u\f$ is from the 1. 1718 */ 1719 double GetValue (uint32_t k, double lambda); 1720 1721 /** 1722 * \brief Returns a random unsigned integer from an Erlang distribution with the specified k and lambda. 1723 * \param [in] k K value for the Erlang distribution. 1724 * \param [in] lambda Lambda value for the Erlang distribution. 1725 * \return A random unsigned integer value. 1726 * 1727 * Note that antithetic values are being generated if m_isAntithetic 1728 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1729 * and \f$x\f$ is a value that would be returned normally, then 1730 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1731 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1732 * which is the distance \f$u\f$ is from the 1. 1733 */ 1734 uint32_t GetInteger (uint32_t k, uint32_t lambda); 1735 1736 /** 1737 * \brief Returns a random double from an Erlang distribution with the current k and lambda. 1738 * \return A floating point random value. 1739 * 1740 * Note that antithetic values are being generated if m_isAntithetic 1741 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1742 * and \f$x\f$ is a value that would be returned normally, then 1743 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1744 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1745 * which is the distance \f$u\f$ is from the 1. 1746 * 1747 * Note that we have to re-implement this method here because the method is 1748 * overloaded above for the two-argument variant and the c++ name resolution 1749 * rules don't work well with overloads split between parent and child 1750 * classes. 1751 */ 1752 virtual double GetValue (void); 1753 1754 /** 1755 * \brief Returns a random unsigned integer from an Erlang distribution with the current k and lambda. 1756 * \return A random unsigned integer value. 1757 * 1758 * Note that antithetic values are being generated if m_isAntithetic 1759 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 1760 * and \f$x\f$ is a value that would be returned normally, then 1761 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 1762 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 1763 * which is the distance \f$u\f$ is from the 1. 1764 */ 1765 virtual uint32_t GetInteger (void); 1766 1767 private: 1768 /** 1769 * \brief Returns a random double from an exponential distribution with the specified mean and upper bound. 1770 * \param [in] mean Mean value of the random variables. 1771 * \param [in] bound Upper bound on values returned. 1772 * \return A floating point random value. 1773 * 1774 * Note that antithetic values are being generated if 1775 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 1776 * over [0,1] and 1777 * 1778 * \f[ 1779 * x = - mean * \log(u) 1780 * \f] 1781 * 1782 * is a value that would be returned normally, then \f$(1 - u\f$) is 1783 * the distance that \f$u\f$ would be from \f$1\f$. The value 1784 * returned in the antithetic case, \f$x'\f$, is calculated as 1785 * 1786 * \f[ 1787 * x' = - mean * \log(1 - u), 1788 * \f] 1789 * 1790 * which now involves the log of the distance \f$u\f$ is from the 1. 1791 */ 1792 double GetExponentialValue (double mean, double bound); 1793 1794 /** The k value for the Erlang distribution returned by this RNG stream. */ 1795 uint32_t m_k; 1796 1797 /** The lambda value for the Erlang distribution returned by this RNG stream. */ 1798 double m_lambda; 1799 1800 }; // class ErlangRandomVariable 1801 1802 1803 /** 1804 * \ingroup randomvariable 1805 * \brief The triangular distribution Random Number Generator (RNG) that 1806 * allows stream numbers to be set deterministically. 1807 * 1808 * This class supports the creation of objects that return random numbers 1809 * from a fixed triangular distribution. It also supports the generation of 1810 * single random numbers from various triangular distributions. 1811 * 1812 * This distribution is a triangular distribution. The probability density 1813 * is in the shape of a triangle. 1814 * 1815 * Here is an example of how to use this class: 1816 * \code 1817 * double mean = 5.0; 1818 * double min = 2.0; 1819 * double max = 10.0; 1820 * 1821 * Ptr<TriangularRandomVariable> x = CreateObject<TriangularRandomVariable> (); 1822 * x->SetAttribute ("Mean", DoubleValue (mean)); 1823 * x->SetAttribute ("Min", DoubleValue (min)); 1824 * x->SetAttribute ("Max", DoubleValue (max)); 1825 * 1826 * // The expected value for the mean of the values returned by a 1827 * // triangularly distributed random variable is equal to mean. 1828 * double value = x->GetValue (); 1829 * \endcode 1830 */ 1831 class TriangularRandomVariable : public RandomVariableStream 1832 { 1833 public: 1834 /** 1835 * \brief Register this type. 1836 * \return The object TypeId. 1837 */ 1838 static TypeId GetTypeId (void); 1839 1840 /** 1841 * \brief Creates a triangular distribution RNG with the default 1842 * values for the mean, lower bound, and upper bound. 1843 */ 1844 TriangularRandomVariable (); 1845 1846 /** 1847 * \brief Returns the mean value for the triangular distribution returned by this RNG stream. 1848 * \return The mean value for the triangular distribution returned by this RNG stream. 1849 */ 1850 double GetMean (void) const; 1851 1852 /** 1853 * \brief Returns the lower bound for the triangular distribution returned by this RNG stream. 1854 * \return The lower bound for the triangular distribution returned by this RNG stream. 1855 */ 1856 double GetMin (void) const; 1857 1858 /** 1859 * \brief Returns the upper bound on values that can be returned by this RNG stream. 1860 * \return The upper bound on values that can be returned by this RNG stream. 1861 */ 1862 double GetMax (void) const; 1863 1864 /** 1865 * \brief Returns a random double from a triangular distribution with the specified mean, min, and max. 1866 * \param [in] mean Mean value for the triangular distribution. 1867 * \param [in] min Low end of the range. 1868 * \param [in] max High end of the range. 1869 * \return A floating point random value. 1870 * 1871 * Note that antithetic values are being generated if 1872 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 1873 * over [0,1] and 1874 * 1875 * \f[ 1876 * x = \left\{ \begin{array}{rl} 1877 * min + \sqrt{u * (max - min) * (mode - min)} &\mbox{ if $u <= (mode - min)/(max - min)$} \\ 1878 * max - \sqrt{ (1 - u) * (max - min) * (max - mode) } &\mbox{ otherwise} 1879 * \end{array} \right. 1880 * \f] 1881 * 1882 * is a value that would be returned normally, where the mode or 1883 * peak of the triangle is calculated as 1884 * 1885 * \f[ 1886 * mode = 3.0 * mean - min - max . 1887 * \f] 1888 * 1889 * Then, \f$(1 - u\f$) is the distance that \f$u\f$ would be from 1890 * \f$1\f$. The value returned in the antithetic case, \f$x'\f$, is 1891 * calculated as 1892 * 1893 * \f[ 1894 * x' = \left\{ \begin{array}{rl} 1895 * min + \sqrt{(1 - u) * (max - min) * (mode - min)} &\mbox{ if $(1 - u) <= (mode - min)/(max - min)$} \\ 1896 * max - \sqrt{ u * (max - min) * (max - mode) } &\mbox{ otherwise} 1897 * \end{array} \right. 1898 * \f] 1899 * 1900 * which now involves the distance \f$u\f$ is from the 1. 1901 */ 1902 double GetValue (double mean, double min, double max); 1903 1904 /** 1905 * \brief Returns a random unsigned integer from a triangular distribution with the specified mean, min, and max. 1906 * \param [in] mean Mean value for the triangular distribution. 1907 * \param [in] min Low end of the range. 1908 * \param [in] max High end of the range. 1909 * \return A random unsigned integer value. 1910 * 1911 * Note that antithetic values are being generated if 1912 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 1913 * over [0,1] and 1914 * 1915 * \f[ 1916 * x = \left\{ \begin{array}{rl} 1917 * min + \sqrt{u * (max - min) * (mode - min)} &\mbox{ if $u <= (mode - min)/(max - min)$} \\ 1918 * max - \sqrt{ (1 - u) * (max - min) * (max - mode) } &\mbox{ otherwise} 1919 * \end{array} \right. 1920 * \f] 1921 * 1922 * is a value that would be returned normally, where the mode or 1923 * peak of the triangle is calculated as 1924 * 1925 * \f[ 1926 * mode = 3.0 * mean - min - max . 1927 * \f] 1928 * 1929 * Then, \f$(1 - u\f$) is the distance that \f$u\f$ would be from 1930 * \f$1\f$. The value returned in the antithetic case, \f$x'\f$, is 1931 * calculated as 1932 * 1933 * \f[ 1934 * x' = \left\{ \begin{array}{rl} 1935 * min + \sqrt{(1 - u) * (max - min) * (mode - min)} &\mbox{ if $(1 - u) <= (mode - min)/(max - min)$} \\ 1936 * max - \sqrt{ u * (max - min) * (max - mode) } &\mbox{ otherwise} 1937 * \end{array} \right. 1938 * \f] 1939 * 1940 * which now involves the distance \f$u\f$ is from the 1. 1941 */ 1942 uint32_t GetInteger (uint32_t mean, uint32_t min, uint32_t max); 1943 1944 /** 1945 * \brief Returns a random double from a triangular distribution with the current mean, min, and max. 1946 * \return A floating point random value. 1947 * 1948 * Note that antithetic values are being generated if 1949 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 1950 * over [0,1] and 1951 * 1952 * \f[ 1953 * x = \left\{ \begin{array}{rl} 1954 * min + \sqrt{u * (max - min) * (mode - min)} &\mbox{ if $u <= (mode - min)/(max - min)$} \\ 1955 * max - \sqrt{ (1 - u) * (max - min) * (max - mode) } &\mbox{ otherwise} 1956 * \end{array} \right. 1957 * \f] 1958 * 1959 * is a value that would be returned normally, where the mode or 1960 * peak of the triangle is calculated as 1961 * 1962 * \f[ 1963 * mode = 3.0 * mean - min - max . 1964 * \f] 1965 * 1966 * Then, \f$(1 - u\f$) is the distance that \f$u\f$ would be from 1967 * \f$1\f$. The value returned in the antithetic case, \f$x'\f$, is 1968 * calculated as 1969 * 1970 * \f[ 1971 * x' = \left\{ \begin{array}{rl} 1972 * min + \sqrt{(1 - u) * (max - min) * (mode - min)} &\mbox{ if $(1 - u) <= (mode - min)/(max - min)$} \\ 1973 * max - \sqrt{ u * (max - min) * (max - mode) } &\mbox{ otherwise} 1974 * \end{array} \right. 1975 * \f] 1976 * 1977 * which now involves the distance \f$u\f$ is from the 1. 1978 * 1979 * Note that we have to re-implement this method here because the method is 1980 * overloaded above for the three-argument variant and the c++ name resolution 1981 * rules don't work well with overloads split between parent and child 1982 * classes. 1983 */ 1984 virtual double GetValue (void); 1985 1986 /** 1987 * \brief Returns a random unsigned integer from a triangular distribution with the current mean, min, and max. 1988 * \return A random unsigned integer value. 1989 * 1990 * Note that antithetic values are being generated if 1991 * m_isAntithetic is equal to true. If \f$u\f$ is a uniform variable 1992 * over [0,1] and 1993 * 1994 * \f[ 1995 * x = \left\{ \begin{array}{rl} 1996 * min + \sqrt{u * (max - min) * (mode - min)} &\mbox{ if $u <= (mode - min)/(max - min)$} \\ 1997 * max - \sqrt{ (1 - u) * (max - min) * (max - mode) } &\mbox{ otherwise} 1998 * \end{array} \right. 1999 * \f] 2000 * 2001 * is a value that would be returned normally, where the mode or 2002 * peak of the triangle is calculated as 2003 * 2004 * \f[ 2005 * mode = 3.0 * mean - min - max . 2006 * \f] 2007 * 2008 * Then, \f$(1 - u\f$) is the distance that \f$u\f$ would be from 2009 * \f$1\f$. The value returned in the antithetic case, \f$x'\f$, is 2010 * calculated as 2011 * 2012 * \f[ 2013 * x' = \left\{ \begin{array}{rl} 2014 * min + \sqrt{(1 - u) * (max - min) * (mode - min)} &\mbox{ if $(1 - u) <= (mode - min)/(max - min)$} \\ 2015 * max - \sqrt{ u * (max - min) * (max - mode) } &\mbox{ otherwise} 2016 * \end{array} \right. 2017 * \f] 2018 * 2019 * which now involves the distance \f$u\f$ is from the 1. 2020 */ 2021 virtual uint32_t GetInteger (void); 2022 2023 private: 2024 /** The mean value for the triangular distribution returned by this RNG stream. */ 2025 double m_mean; 2026 2027 /** The lower bound on values that can be returned by this RNG stream. */ 2028 double m_min; 2029 2030 /** The upper bound on values that can be returned by this RNG stream. */ 2031 double m_max; 2032 2033 }; // class TriangularRandomVariable 2034 2035 2036 /** 2037 * \ingroup randomvariable 2038 * \brief The Zipf distribution Random Number Generator (RNG) that 2039 * allows stream numbers to be set deterministically. 2040 * 2041 * This class supports the creation of objects that return random numbers 2042 * from a fixed Zipf distribution. It also supports the generation of 2043 * single random numbers from various Zipf distributions. 2044 * 2045 * The Zipf's law states that given some corpus of natural language 2046 * utterances, the frequency of any word is inversely proportional 2047 * to its rank in the frequency table. 2048 * 2049 * Zipf's distribution has two parameters, alpha and N, where: 2050 * \f$ \alpha > 0 \f$ (real) and \f$ N \in \{1,2,3 \dots\}\f$ (integer). 2051 * Probability Mass Function is \f$ f(k; \alpha, N) = k^{-\alpha}/ H_{N,\alpha} \f$ 2052 * where \f$ H_{N,\alpha} = \sum_{m=1}^N m^{-\alpha} \f$ 2053 * 2054 * Here is an example of how to use this class: 2055 * \code 2056 * uint32_t n = 1; 2057 * double alpha = 2.0; 2058 * 2059 * Ptr<ZipfRandomVariable> x = CreateObject<ZipfRandomVariable> (); 2060 * x->SetAttribute ("N", IntegerValue (n)); 2061 * x->SetAttribute ("Alpha", DoubleValue (alpha)); 2062 * 2063 * // The expected value for the mean of the values returned by a 2064 * // Zipfly distributed random variable is equal to 2065 * // 2066 * // H 2067 * // N, alpha - 1 2068 * // E[value] = --------------- 2069 * // H 2070 * // N, alpha 2071 * // 2072 * // where 2073 * // 2074 * // N 2075 * // --- 2076 * // \ -alpha 2077 * // H = / m . 2078 * // N, alpha --- 2079 * // m=1 2080 * // 2081 * // For this test, 2082 * // 2083 * // -(alpha - 1) 2084 * // 1 2085 * // E[value] = --------------- 2086 * // -alpha 2087 * // 1 2088 * // 2089 * // = 1 . 2090 * // 2091 * double value = x->GetValue (); 2092 * \endcode 2093 */ 2094 class ZipfRandomVariable : public RandomVariableStream 2095 { 2096 public: 2097 /** 2098 * \brief Register this type. 2099 * \return The object TypeId. 2100 */ 2101 static TypeId GetTypeId (void); 2102 2103 /** 2104 * \brief Creates a Zipf distribution RNG with the default values 2105 * for n and alpha. 2106 */ 2107 ZipfRandomVariable (); 2108 2109 /** 2110 * \brief Returns the n value for the Zipf distribution returned by this RNG stream. 2111 * \return The n value for the Zipf distribution returned by this RNG stream. 2112 */ 2113 uint32_t GetN (void) const; 2114 2115 /** 2116 * \brief Returns the alpha value for the Zipf distribution returned by this RNG stream. 2117 * \return The alpha value for the Zipf distribution returned by this RNG stream. 2118 */ 2119 double GetAlpha (void) const; 2120 2121 /** 2122 * \brief Returns a random double from a Zipf distribution with the specified n and alpha. 2123 * \param [in] n N value for the Zipf distribution. 2124 * \param [in] alpha Alpha value for the Zipf distribution. 2125 * \return A floating point random value. 2126 * 2127 * Note that antithetic values are being generated if m_isAntithetic 2128 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2129 * and \f$x\f$ is a value that would be returned normally, then 2130 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2131 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2132 * which is the distance \f$u\f$ is from the 1. 2133 */ 2134 double GetValue (uint32_t n, double alpha); 2135 2136 /** 2137 * \brief Returns a random unsigned integer from a Zipf distribution with the specified n and alpha. 2138 * \param [in] n N value for the Zipf distribution. 2139 * \param [in] alpha Alpha value for the Zipf distribution. 2140 * \return A random unsigned integer value. 2141 * 2142 * Note that antithetic values are being generated if m_isAntithetic 2143 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2144 * and \f$x\f$ is a value that would be returned normally, then 2145 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2146 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2147 * which is the distance \f$u\f$ is from the 1. 2148 */ 2149 uint32_t GetInteger (uint32_t n, uint32_t alpha); 2150 2151 /** 2152 * \brief Returns a random double from a Zipf distribution with the current n and alpha. 2153 * \return A floating point random value. 2154 * 2155 * Note that antithetic values are being generated if m_isAntithetic 2156 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2157 * and \f$x\f$ is a value that would be returned normally, then 2158 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2159 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2160 * which is the distance \f$u\f$ is from the 1. 2161 * 2162 * Note that we have to re-implement this method here because the method is 2163 * overloaded above for the two-argument variant and the c++ name resolution 2164 * rules don't work well with overloads split between parent and child 2165 * classes. 2166 */ 2167 virtual double GetValue (void); 2168 2169 /** 2170 * \brief Returns a random unsigned integer from a Zipf distribution with the current n and alpha. 2171 * \return A random unsigned integer value. 2172 * 2173 * Note that antithetic values are being generated if m_isAntithetic 2174 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2175 * and \f$x\f$ is a value that would be returned normally, then 2176 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2177 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2178 * which is the distance \f$u\f$ is from the 1. 2179 */ 2180 virtual uint32_t GetInteger (void); 2181 2182 private: 2183 /** The n value for the Zipf distribution returned by this RNG stream. */ 2184 uint32_t m_n; 2185 2186 /** The alpha value for the Zipf distribution returned by this RNG stream. */ 2187 double m_alpha; 2188 2189 /** The normalization constant. */ 2190 double m_c; 2191 2192 }; // class ZipfRandomVariable 2193 2194 2195 /** 2196 * \ingroup randomvariable 2197 * \brief The zeta distribution Random Number Generator (RNG) that 2198 * allows stream numbers to be set deterministically. 2199 * 2200 * This class supports the creation of objects that return random numbers 2201 * from a fixed zeta distribution. It also supports the generation of 2202 * single random numbers from various zeta distributions. 2203 * 2204 * The Zeta distribution is closely related to Zipf distribution when 2205 * N goes to infinity. 2206 * 2207 * Zeta distribution has one parameter, alpha, \f$ \alpha > 1 \f$ (real). 2208 * Probability Mass Function is \f$ f(k; \alpha) = k^{-\alpha}/\zeta(\alpha) \f$ 2209 * where \f$ \zeta(\alpha) \f$ is the Riemann zeta function ( \f$ \sum_{n=1}^\infty n^{-\alpha} ) \f$ 2210 * 2211 * Here is an example of how to use this class: 2212 * \code 2213 * double alpha = 2.0; 2214 * 2215 * Ptr<ZetaRandomVariable> x = CreateObject<ZetaRandomVariable> (); 2216 * x->SetAttribute ("Alpha", DoubleValue (alpha)); 2217 * 2218 * // The expected value for the mean of the values returned by a 2219 * // zetaly distributed random variable is equal to 2220 * // 2221 * // zeta(alpha - 1) 2222 * // E[value] = --------------- for alpha > 2 , 2223 * // zeta(alpha) 2224 * // 2225 * // where zeta(alpha) is the Riemann zeta function. 2226 * // 2227 * // There are no simple analytic forms for the Riemann zeta 2228 * // function, which is the reason the known mean of the values 2229 * // cannot be calculated in this example. 2230 * // 2231 * double value = x->GetValue (); 2232 * \endcode 2233 */ 2234 class ZetaRandomVariable : public RandomVariableStream 2235 { 2236 public: 2237 /** 2238 * \brief Register this type. 2239 * \return The object TypeId. 2240 */ 2241 static TypeId GetTypeId (void); 2242 2243 /** 2244 * \brief Creates a zeta distribution RNG with the default value for 2245 * alpha. 2246 */ 2247 ZetaRandomVariable (); 2248 2249 /** 2250 * \brief Returns the alpha value for the zeta distribution returned by this RNG stream. 2251 * \return The alpha value for the zeta distribution returned by this RNG stream. 2252 */ 2253 double GetAlpha (void) const; 2254 2255 /** 2256 * \brief Returns a random double from a zeta distribution with the specified alpha. 2257 * \param [in] alpha Alpha value for the zeta distribution. 2258 * \return A floating point random value. 2259 * 2260 * Note that antithetic values are being generated if m_isAntithetic 2261 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2262 * and \f$x\f$ is a value that would be returned normally, then 2263 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2264 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2265 * which is the distance \f$u\f$ is from the 1. 2266 */ 2267 double GetValue (double alpha); 2268 2269 /** 2270 * \brief Returns a random unsigned integer from a zeta distribution with the specified alpha. 2271 * \param [in] alpha Alpha value for the zeta distribution. 2272 * \return A random unsigned integer value. 2273 * 2274 * Note that antithetic values are being generated if m_isAntithetic 2275 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2276 * and \f$x\f$ is a value that would be returned normally, then 2277 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2278 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2279 * which is the distance \f$u\f$ is from the 1. 2280 */ 2281 uint32_t GetInteger (uint32_t alpha); 2282 2283 /** 2284 * \brief Returns a random double from a zeta distribution with the current alpha. 2285 * \return A floating point random value. 2286 * 2287 * Note that antithetic values are being generated if m_isAntithetic 2288 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2289 * and \f$x\f$ is a value that would be returned normally, then 2290 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2291 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2292 * which is the distance \f$u\f$ is from the 1. 2293 * 2294 * Note that we have to re-implement this method here because the method is 2295 * overloaded above for the two-argument variant and the c++ name resolution 2296 * rules don't work well with overloads split between parent and child 2297 * classes. 2298 */ 2299 virtual double GetValue (void); 2300 2301 /** 2302 * \brief Returns a random unsigned integer from a zeta distribution with the current alpha. 2303 * \return A random unsigned integer value. 2304 * 2305 * Note that antithetic values are being generated if m_isAntithetic 2306 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2307 * and \f$x\f$ is a value that would be returned normally, then 2308 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2309 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2310 * which is the distance \f$u\f$ is from the 1. 2311 */ 2312 virtual uint32_t GetInteger (void); 2313 2314 private: 2315 /** The alpha value for the zeta distribution returned by this RNG stream. */ 2316 double m_alpha; 2317 2318 /** Just for calculus simplifications. */ 2319 double m_b; 2320 2321 }; // class ZetaRandomVariable 2322 2323 2324 /** 2325 * \ingroup randomvariable 2326 * \brief The Random Number Generator (RNG) that returns a predetermined sequence. 2327 * 2328 * Defines a random variable that has a specified, predetermined 2329 * sequence. This would be useful when trying to force the RNG to 2330 * return a known sequence, perhaps to compare ns-3 to some other 2331 * simulator 2332 * 2333 * Creates a generator that returns successive elements of the values 2334 * array on successive calls to RandomVariableStream::GetValue. Note 2335 * that the values in the array are copied and stored by the generator 2336 * (deep-copy). Also note that the sequence repeats if more values 2337 * are requested than are present in the array. 2338 * 2339 * Here is an example of how to use this class: 2340 * \code 2341 * Ptr<DeterministicRandomVariable> s = CreateObject<DeterministicRandomVariable> (); 2342 * 2343 * // The following array should give the sequence 2344 * // 2345 * // 4, 4, 7, 7, 10, 10 . 2346 * // 2347 * double array [] = { 4, 4, 7, 7, 10, 10}; 2348 * uint64_t count = 6; 2349 * s->SetValueArray (array, count); 2350 * 2351 * double value = x->GetValue (); 2352 * \endcode 2353 */ 2354 class DeterministicRandomVariable : public RandomVariableStream 2355 { 2356 public: 2357 /** 2358 * \brief Register this type. 2359 * \return The object TypeId. 2360 */ 2361 static TypeId GetTypeId (void); 2362 2363 /** 2364 * \brief Creates a deterministic RNG that will have a predetermined 2365 * sequence of values. 2366 */ 2367 DeterministicRandomVariable (); 2368 virtual ~DeterministicRandomVariable (); 2369 2370 /** 2371 * \brief Sets the array of values that holds the predetermined sequence. 2372 * \param [in] values Array of random values to return in sequence. 2373 * \param [in] length Number of values in the array. 2374 * 2375 * Note that the values in the array are copied and stored 2376 * (deep-copy). 2377 */ 2378 void SetValueArray (double* values, std::size_t length); 2379 2380 /** 2381 * \brief Returns the next value in the sequence. 2382 * \return The floating point next value in the sequence. 2383 */ 2384 virtual double GetValue (void); 2385 2386 /** 2387 * \brief Returns the next value in the sequence. 2388 * \return The integer next value in the sequence. 2389 */ 2390 virtual uint32_t GetInteger (void); 2391 2392 private: 2393 /** Size of the array of values. */ 2394 std::size_t m_count; 2395 2396 /** Position of the next value in the array of values. */ 2397 std::size_t m_next; 2398 2399 /** Array of values to return in sequence. */ 2400 double* m_data; 2401 2402 }; // class DeterministicRandomVariable 2403 2404 2405 /** 2406 * \ingroup randomvariable 2407 * \brief The Random Number Generator (RNG) that has a specified 2408 * empirical distribution. 2409 * 2410 * Defines a random variable that has a specified, empirical 2411 * distribution. The cumulative probability distribution function (CDF) 2412 * is specified by a 2413 * series of calls to the CDF() member function, specifying a 2414 * value and the probability that the distribution is less than 2415 * the specified value. When random values are requested, 2416 * a uniform random variable `r` is used to select a probability, 2417 * and the return value is chosen from the largest input value with CDF 2418 * less than the random value. The method is known 2419 * as inverse transform sampling: 2420 * (http://en.wikipedia.org/wiki/Inverse_transform_sampling). 2421 * 2422 * This generator has two modes: *sampling* and *interpolating*. 2423 * In *sampling* mode this random variable generator 2424 * treats the CDF as an exact histogram and returns 2425 * one of the histogram inputs exactly. This is appropriate 2426 * when the configured CDF represents the exact probability 2427 * distribution, for a categorical variable, for example. 2428 * 2429 * In *interpolating* mode this random variable generator linearly 2430 * interpolates between the CDF values defining the histogram bins. 2431 * This is appropriate when the configured CDF is an approximation 2432 * to a continuous underlying probability distribution. 2433 * 2434 * For historical reasons the default is interpolating. 2435 * To switch modes use the \c Interpolate Attribute, or call SetInterpolate(). 2436 * You can change modes at any time. 2437 * 2438 * If you find yourself switching frequently it could be simpler to 2439 * set the mode to sampling, then use the GetValue() function for 2440 * sampled values, and Interpolate() function for interpolated values. 2441 * 2442 * The CDF need not start with a probability of zero, 2443 * nor end with a probability of 1.0. If the selected uniform 2444 * random value `r` is less than the first CDF point, that point 2445 * is selected. If `r` is greater than the last CDF point the last 2446 * point is selected. In either case the interpolating mode will *not* 2447 * interpolate (since there is no value beyond `r` to work with), but 2448 * simply return the extremal CDF value, as in sampling. 2449 * 2450 * Here is an example of how to use this class: 2451 * 2452 * // Create the RNG with a non-uniform distribution between 0 and 10. 2453 * // in sampling mode. 2454 * Ptr<EmpiricalRandomVariable> x = CreateObject<EmpiricalRandomVariable> (); 2455 * x->SetInterpolate (false); 2456 * x->CDF ( 0.0, 0.0); 2457 * x->CDF ( 5.0, 0.25); 2458 * x->CDF (10.0, 1.0); 2459 * 2460 * double value = x->GetValue (); 2461 * 2462 * The expected values and probabilities returned by GetValue are 2463 * 2464 * Value | Probability 2465 * ----: | ----------: 2466 * 0.0 | 0 2467 * 5.0 | 25% 2468 * 10.0 | 75% 2469 * 2470 * The only two values ever returned are 5 and 10, with unequal probability. 2471 * 2472 * If instead you want linear interpolation between the points of the CDF 2473 * use the Interpolate() function: 2474 * 2475 * double interp = x->Interpolate (); 2476 * 2477 * This will return continuous values on the range [0,1). 2478 * 2479 * See empirical-random-variable-example.cc for an example. 2480 */ 2481 class EmpiricalRandomVariable : public RandomVariableStream 2482 { 2483 public: 2484 /** 2485 * \brief Register this type. 2486 * \return The object TypeId. 2487 */ 2488 static TypeId GetTypeId (void); 2489 2490 /** 2491 * \brief Creates an empirical RNG that has a specified, empirical 2492 * distribution, and configured for interpolating mode. 2493 */ 2494 EmpiricalRandomVariable (void); 2495 2496 /** 2497 * \brief Specifies a point in the empirical distribution 2498 * \note These *MUST* be inserted in ascending order of \p c 2499 * 2500 * \param [in] v The function value for this point 2501 * \param [in] c Probability that the function is less than or equal to \p v 2502 */ 2503 void CDF (double v, double c); // Value, prob <= Value 2504 2505 /** 2506 * \brief Returns the next value in the empirical distribution. 2507 * \return The floating point next value in the empirical distribution. 2508 * 2509 * Note that this does not interpolate the CDF, but treats it as a 2510 * stepwise continuous function. 2511 * 2512 * Also note that antithetic values are being generated if m_isAntithetic 2513 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2514 * and \f$x\f$ is a value that would be returned normally, then 2515 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2516 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2517 * which is the distance \f$u\f$ is from the 1. 2518 */ 2519 virtual double GetValue (void); 2520 2521 /** 2522 * \brief Returns the next value in the empirical distribution. 2523 * \return The integer next value in the empirical distribution. 2524 * 2525 * Note that this does not interpolate the CDF, but treats it as a 2526 * stepwise continuous function. 2527 * Also note that antithetic values are being generated if m_isAntithetic 2528 * is equal to true. If \f$u\f$ is a uniform variable over [0,1] 2529 * and \f$x\f$ is a value that would be returned normally, then 2530 * \f$(1 - u\f$) is the distance that \f$u\f$ would be from \f$1\f$. 2531 * The value returned in the antithetic case, \f$x'\f$, uses (1-u), 2532 * which is the distance \f$u\f$ is from the 1. 2533 */ 2534 virtual uint32_t GetInteger (void); 2535 2536 /** 2537 * \brief Returns the next value in the empirical distribution using 2538 * linear interpolation. 2539 * \return The floating point next value in the empirical distribution 2540 * using linear interpolation. 2541 */ 2542 virtual double Interpolate (void); 2543 2544 /** 2545 * \brief Switch the mode between sampling the CDF and interpolating. 2546 * The default mode is sampling. 2547 * \param [in] interpolate If \c true set to interpolation, otherwise sampling. 2548 * \returns The previous interpolate flag value. 2549 */ 2550 bool SetInterpolate (bool interpolate); 2551 2552 private: 2553 /** \brief Helper to hold one point of the CDF. */ 2554 class ValueCDF 2555 { 2556 public: 2557 /** \brief Constructor. */ 2558 ValueCDF (void); 2559 /** 2560 * \brief Construct from values. 2561 * 2562 * \param [in] v The argument value. 2563 * \param [in] c The CDF at the argument value \pname{v} 2564 */ 2565 ValueCDF (double v, double c); 2566 2567 /** The argument value. */ 2568 double value; 2569 /** The CDF at \pname{value} */ 2570 double cdf; 2571 }; // class ValueCDF 2572 2573 /** 2574 * \brief Check that the CDF is valid. 2575 * 2576 * A valid CDF has 2577 * 2578 * - Strictly increasing arguments, and 2579 * - Strictly increasing CDF. 2580 * 2581 * It is a fatal error to fail validation. 2582 */ 2583 void Validate (void); 2584 /** 2585 * \brief Do the initial rng draw and check against the extrema. 2586 * 2587 * If the extrema apply, \c value will have the extremal value 2588 * and the return will be \c true. 2589 * 2590 * If the extrema do not apply \c value will have the URNG value 2591 * and the return will be \c false. 2592 * 2593 * \param [out] value The extremal value, or the URNG. 2594 * \returns \c true if \p value is the extremal result, 2595 * or \c false if \p value is the URNG value. 2596 */ 2597 bool PreSample (double & value); 2598 /** 2599 * \brief Sample the CDF as a histogram (without interpolation). 2600 * \param [in] r The CDF value at which to sample the CDF. 2601 * \return The bin value corresponding to \c r. 2602 */ 2603 double DoSampleCDF (double r); 2604 /** 2605 * \brief Linear interpolation between two points on the CDF to estimate 2606 * the value at \p r. 2607 * 2608 * \param [in] r The argument value to interpolate to. 2609 * \returns The interpolated CDF at \pname{r} 2610 */ 2611 double DoInterpolate (double r); 2612 2613 /** 2614 * \brief Comparison operator, for use by std::upper_bound 2615 * \param a [in] the first value 2616 * \param b [in] the second value 2617 * \returns \c true if \c a.cdf < \c b.cdf 2618 */ 2619 friend 2620 bool operator < (ValueCDF a, ValueCDF b); 2621 2622 /** \c true once the CDF has been validated. */ 2623 bool m_validated; 2624 /** The vector of CDF points. */ 2625 std::vector<ValueCDF> m_emp; 2626 /** 2627 * If \c true GetValue will interpolate, 2628 * otherwise treat CDF as normal histogram. 2629 */ 2630 bool m_interpolate; 2631 2632 }; // class EmpiricalRandomVariable 2633 2634 2635 } // namespace ns3 2636 2637 #endif /* RANDOM_VARIABLE_STREAM_H */ 2638