gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Doc improvements in random.h
0 1 0
default
1 file changed with 14 insertions and 2 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -495,317 +495,329 @@
495 495
  /// get a random number from a range of a floating point type you
496 496
  /// can use one form of the \c operator() or the \c real() member
497 497
  /// function. If you want to get random number from the {0, 1, ...,
498 498
  /// n-1} integer range use the \c operator[] or the \c integer()
499 499
  /// method. And to get random number from the whole range of an
500 500
  /// integer type you can use the argumentless \c integer() or \c
501 501
  /// uinteger() functions. After all you can get random bool with
502 502
  /// equal chance of true and false or given probability of true
503 503
  /// result with the \c boolean() member functions.
504 504
  ///
505 505
  ///\code
506 506
  /// // The commented code is identical to the other
507 507
  /// double a = rnd();                     // [0.0, 1.0)
508 508
  /// // double a = rnd.real();             // [0.0, 1.0)
509 509
  /// double b = rnd(100.0);                // [0.0, 100.0)
510 510
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
511 511
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
512 512
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
513 513
  /// int d = rnd[100000];                  // 0..99999
514 514
  /// // int d = rnd.integer(100000);       // 0..99999
515 515
  /// int e = rnd[6] + 1;                   // 1..6
516 516
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
517 517
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
518 518
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
519 519
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
520 520
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
521 521
  ///\endcode
522 522
  ///
523 523
  /// LEMON provides a global instance of the random number
524 524
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
525 525
  /// good programming convenience to use this global generator to get
526 526
  /// random numbers.
527 527
  class Random {
528 528
  private:
529 529

	
530 530
    // Architecture word
531 531
    typedef unsigned long Word;
532 532
    
533 533
    _random_bits::RandomCore<Word> core;
534 534
    _random_bits::BoolProducer<Word> bool_producer;
535 535
    
536 536

	
537 537
  public:
538 538

	
539 539
    ///\name Initialization
540 540
    ///
541 541
    /// @{
542 542

	
543
    ///\name Initialization
544
    ///
545
    /// @{
546

	
543 547
    /// \brief Default constructor
544 548
    ///
545 549
    /// Constructor with constant seeding.
546 550
    Random() { core.initState(); }
547 551

	
548 552
    /// \brief Constructor with seed
549 553
    ///
550 554
    /// Constructor with seed. The current number type will be converted
551 555
    /// to the architecture word type.
552 556
    template <typename Number>
553 557
    Random(Number seed) { 
554 558
      _random_bits::Initializer<Number, Word>::init(core, seed);
555 559
    }
556 560

	
557 561
    /// \brief Constructor with array seeding
558 562
    ///
559 563
    /// Constructor with array seeding. The given range should contain
560 564
    /// any number type and the numbers will be converted to the
561 565
    /// architecture word type.
562 566
    template <typename Iterator>
563 567
    Random(Iterator begin, Iterator end) { 
564 568
      typedef typename std::iterator_traits<Iterator>::value_type Number;
565 569
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
566 570
    }
567 571

	
568 572
    /// \brief Copy constructor
569 573
    ///
570 574
    /// Copy constructor. The generated sequence will be identical to
571 575
    /// the other sequence. It can be used to save the current state
572 576
    /// of the generator and later use it to generate the same
573 577
    /// sequence.
574 578
    Random(const Random& other) {
575 579
      core.copyState(other.core);
576 580
    }
577 581

	
578 582
    /// \brief Assign operator
579 583
    ///
580 584
    /// Assign operator. The generated sequence will be identical to
581 585
    /// the other sequence. It can be used to save the current state
582 586
    /// of the generator and later use it to generate the same
583 587
    /// sequence.
584 588
    Random& operator=(const Random& other) {
585 589
      if (&other != this) {
586 590
        core.copyState(other.core);
587 591
      }
588 592
      return *this;
589 593
    }
590 594

	
591 595
    /// \brief Seeding random sequence
592 596
    ///
593 597
    /// Seeding the random sequence. The current number type will be
594 598
    /// converted to the architecture word type.
595 599
    template <typename Number>
596 600
    void seed(Number seed) { 
597 601
      _random_bits::Initializer<Number, Word>::init(core, seed);
598 602
    }
599 603

	
600 604
    /// \brief Seeding random sequence
601 605
    ///
602 606
    /// Seeding the random sequence. The given range should contain
603 607
    /// any number type and the numbers will be converted to the
604 608
    /// architecture word type.
605 609
    template <typename Iterator>
606 610
    void seed(Iterator begin, Iterator end) { 
607 611
      typedef typename std::iterator_traits<Iterator>::value_type Number;
608 612
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
609 613
    }
610 614

	
611 615
    /// \brief Seeding from file or from process id and time
612 616
    ///
613 617
    /// By default, this function calls the \c seedFromFile() member
614
    /// function with the <tt>/dev/urandom</tt> file. If it is not success,
618
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
615 619
    /// it uses the \c seedFromTime().
616 620
    /// \return Currently always true.
617 621
    bool seed() {
618 622
#ifndef WIN32
619 623
      if (seedFromFile("/dev/urandom", 0)) return true;
620 624
#endif
621 625
      if (seedFromTime()) return true;
622 626
      return false;
623 627
    }
624 628
    
625 629
    /// \brief Seeding from file
626 630
    ///
627 631
    /// Seeding the random sequence from file. The linux kernel has two
628 632
    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
629 633
    /// could give good seed values for pseudo random generators (The
630 634
    /// difference between two devices is that the <tt>random</tt> may
631 635
    /// block the reading operation while the kernel can give good
632 636
    /// source of randomness, while the <tt>urandom</tt> does not
633 637
    /// block the input, but it could give back bytes with worse
634 638
    /// entropy).
635 639
    /// \param file The source file
636 640
    /// \param offset The offset, from the file read.
637
    /// \return True when the seeding is success.
641
    /// \return True when the seeding successes.
638 642
#ifndef WIN32
639 643
    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) 
640 644
#else
641 645
    bool seedFromFile(const std::string& file = "", int offset = 0) 
642 646
#endif
643 647
    {
644 648
      std::ifstream rs(file.c_str());
645 649
      const int size = 4;
646 650
      Word buf[size];
647 651
      if (offset != 0 && !rs.seekg(offset)) return false;
648 652
      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
649 653
      seed(buf, buf + size);
650 654
      return true;
651 655
    }
652 656

	
653 657
    /// \brief Seding from process id and time
654 658
    ///
655 659
    /// Seding from process id and time. This function uses the
656 660
    /// current process id and the current time for initialize the
657 661
    /// random sequence.
658 662
    /// \return Currently always true.
659 663
    bool seedFromTime() { 	
660 664
#ifndef WIN32
661 665
      timeval tv;
662 666
      gettimeofday(&tv, 0);
663 667
      seed(getpid() + tv.tv_sec + tv.tv_usec);
664 668
#else
665 669
      FILETIME time;
666 670
      GetSystemTimeAsFileTime(&time);
667 671
      seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
668 672
#endif
669 673
      return true;
670 674
    }
671 675

	
672 676
    /// @}
673 677

	
674 678
    ///\name Uniform distributions
675 679
    ///
676 680
    /// @{
677 681

	
678 682
    /// \brief Returns a random real number from the range [0, 1)
679 683
    ///
680 684
    /// It returns a random real number from the range [0, 1). The
681 685
    /// default Number type is \c double.
682 686
    template <typename Number>
683 687
    Number real() {
684 688
      return _random_bits::RealConversion<Number, Word>::convert(core);
685 689
    }
686 690

	
687 691
    double real() {
688 692
      return real<double>();
689 693
    }
690 694

	
691 695
    /// \brief Returns a random real number the range [0, b)
692 696
    ///
693 697
    /// It returns a random real number from the range [0, b).
694 698
    template <typename Number>
695 699
    Number real(Number b) { 
696 700
      return real<Number>() * b; 
697 701
    }
698 702

	
699 703
    /// \brief Returns a random real number from the range [a, b)
700 704
    ///
701 705
    /// It returns a random real number from the range [a, b).
702 706
    template <typename Number>
703 707
    Number real(Number a, Number b) { 
704 708
      return real<Number>() * (b - a) + a; 
705 709
    }
706 710

	
711
    /// @}
712

	
713
    ///\name Uniform distributions
714
    ///
715
    /// @{
716

	
707 717
    /// \brief Returns a random real number from the range [0, 1)
708 718
    ///
709 719
    /// It returns a random double from the range [0, 1).
710 720
    double operator()() {
711 721
      return real<double>();
712 722
    }
713 723

	
714 724
    /// \brief Returns a random real number from the range [0, b)
715 725
    ///
716 726
    /// It returns a random real number from the range [0, b).
717 727
    template <typename Number>
718 728
    Number operator()(Number b) { 
719 729
      return real<Number>() * b; 
720 730
    }
721 731

	
722 732
    /// \brief Returns a random real number from the range [a, b)
723 733
    ///
724 734
    /// It returns a random real number from the range [a, b).
725 735
    template <typename Number>
726 736
    Number operator()(Number a, Number b) { 
727 737
      return real<Number>() * (b - a) + a; 
728 738
    }
729 739

	
730 740
    /// \brief Returns a random integer from a range
731 741
    ///
732 742
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
733 743
    template <typename Number>
734 744
    Number integer(Number b) {
735 745
      return _random_bits::Mapping<Number, Word>::map(core, b);
736 746
    }
737 747

	
738 748
    /// \brief Returns a random integer from a range
739 749
    ///
740 750
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
741 751
    template <typename Number>
742 752
    Number integer(Number a, Number b) {
743 753
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
744 754
    }
745 755

	
746 756
    /// \brief Returns a random integer from a range
747 757
    ///
748 758
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
749 759
    template <typename Number>
750 760
    Number operator[](Number b) {
751 761
      return _random_bits::Mapping<Number, Word>::map(core, b);
752 762
    }
753 763

	
754 764
    /// \brief Returns a random non-negative integer
755 765
    ///
756 766
    /// It returns a random non-negative integer uniformly from the
757 767
    /// whole range of the current \c Number type. The default result
758 768
    /// type of this function is <tt>unsigned int</tt>.
759 769
    template <typename Number>
760 770
    Number uinteger() {
761 771
      return _random_bits::IntConversion<Number, Word>::convert(core);
762 772
    }
763 773

	
774
    /// @}
775

	
764 776
    unsigned int uinteger() {
765 777
      return uinteger<unsigned int>();
766 778
    }
767 779

	
768 780
    /// \brief Returns a random integer
769 781
    ///
770 782
    /// It returns a random integer uniformly from the whole range of
771 783
    /// the current \c Number type. The default result type of this
772 784
    /// function is \c int.
773 785
    template <typename Number>
774 786
    Number integer() {
775 787
      static const int nb = std::numeric_limits<Number>::digits + 
776 788
        (std::numeric_limits<Number>::is_signed ? 1 : 0);
777 789
      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
778 790
    }
779 791

	
780 792
    int integer() {
781 793
      return integer<int>();
782 794
    }
783 795
    
784 796
    /// \brief Returns a random bool
785 797
    ///
786 798
    /// It returns a random bool. The generator holds a buffer for
787 799
    /// random bits. Every time when it become empty the generator makes
788 800
    /// a new random word and fill the buffer up.
789 801
    bool boolean() {
790 802
      return bool_producer.convert(core);
791 803
    }
792 804

	
793 805
    /// @}
794 806

	
795 807
    ///\name Non-uniform distributions
796 808
    ///
797 809
    
798 810
    ///@{
799 811
    
800 812
    /// \brief Returns a random bool
801 813
    ///
802 814
    /// It returns a random bool with given probability of true result.
803 815
    bool boolean(double p) {
804 816
      return operator()() < p;
805 817
    }
806 818

	
807 819
    /// Standard Gauss distribution
808 820

	
809 821
    /// Standard Gauss distribution.
810 822
    /// \note The Cartesian form of the Box-Muller
811 823
    /// transformation is used to generate a random normal distribution.
0 comments (0 inline)