gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Bugfix in Random (#173) - operator()s always return a double now - the faulty real<Num>(Num) and real<Num>(Num,Num) have been removed
0 1 0
default
1 file changed with 4 insertions and 22 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -599,235 +599,217 @@
599 599
    template <typename Number>
600 600
    void seed(Number seed) {
601 601
      _random_bits::Initializer<Number, Word>::init(core, seed);
602 602
    }
603 603

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

	
615 615
    /// \brief Seeding from file or from process id and time
616 616
    ///
617 617
    /// By default, this function calls the \c seedFromFile() member
618 618
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
619 619
    /// it uses the \c seedFromTime().
620 620
    /// \return Currently always true.
621 621
    bool seed() {
622 622
#ifndef WIN32
623 623
      if (seedFromFile("/dev/urandom", 0)) return true;
624 624
#endif
625 625
      if (seedFromTime()) return true;
626 626
      return false;
627 627
    }
628 628

	
629 629
    /// \brief Seeding from file
630 630
    ///
631 631
    /// Seeding the random sequence from file. The linux kernel has two
632 632
    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
633 633
    /// could give good seed values for pseudo random generators (The
634 634
    /// difference between two devices is that the <tt>random</tt> may
635 635
    /// block the reading operation while the kernel can give good
636 636
    /// source of randomness, while the <tt>urandom</tt> does not
637 637
    /// block the input, but it could give back bytes with worse
638 638
    /// entropy).
639 639
    /// \param file The source file
640 640
    /// \param offset The offset, from the file read.
641 641
    /// \return True when the seeding successes.
642 642
#ifndef WIN32
643 643
    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
644 644
#else
645 645
    bool seedFromFile(const std::string& file = "", int offset = 0)
646 646
#endif
647 647
    {
648 648
      std::ifstream rs(file.c_str());
649 649
      const int size = 4;
650 650
      Word buf[size];
651 651
      if (offset != 0 && !rs.seekg(offset)) return false;
652 652
      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
653 653
      seed(buf, buf + size);
654 654
      return true;
655 655
    }
656 656

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

	
676 676
    /// @}
677 677

	
678 678
    ///\name Uniform distributions
679 679
    ///
680 680
    /// @{
681 681

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

	
691 691
    double real() {
692 692
      return real<double>();
693 693
    }
694 694

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

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

	
711 695
    /// @}
712 696

	
713 697
    ///\name Uniform distributions
714 698
    ///
715 699
    /// @{
716 700

	
717 701
    /// \brief Returns a random real number from the range [0, 1)
718 702
    ///
719 703
    /// It returns a random double from the range [0, 1).
720 704
    double operator()() {
721 705
      return real<double>();
722 706
    }
723 707

	
724 708
    /// \brief Returns a random real number from the range [0, b)
725 709
    ///
726 710
    /// It returns a random real number from the range [0, b).
727
    template <typename Number>
728
    Number operator()(Number b) {
729
      return real<Number>() * b;
711
    double operator()(double b) {
712
      return real<double>() * b;
730 713
    }
731 714

	
732 715
    /// \brief Returns a random real number from the range [a, b)
733 716
    ///
734 717
    /// It returns a random real number from the range [a, b).
735
    template <typename Number>
736
    Number operator()(Number a, Number b) {
737
      return real<Number>() * (b - a) + a;
718
    double operator()(double a, double b) {
719
      return real<double>() * (b - a) + a;
738 720
    }
739 721

	
740 722
    /// \brief Returns a random integer from a range
741 723
    ///
742 724
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
743 725
    template <typename Number>
744 726
    Number integer(Number b) {
745 727
      return _random_bits::Mapping<Number, Word>::map(core, b);
746 728
    }
747 729

	
748 730
    /// \brief Returns a random integer from a range
749 731
    ///
750 732
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
751 733
    template <typename Number>
752 734
    Number integer(Number a, Number b) {
753 735
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
754 736
    }
755 737

	
756 738
    /// \brief Returns a random integer from a range
757 739
    ///
758 740
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
759 741
    template <typename Number>
760 742
    Number operator[](Number b) {
761 743
      return _random_bits::Mapping<Number, Word>::map(core, b);
762 744
    }
763 745

	
764 746
    /// \brief Returns a random non-negative integer
765 747
    ///
766 748
    /// It returns a random non-negative integer uniformly from the
767 749
    /// whole range of the current \c Number type. The default result
768 750
    /// type of this function is <tt>unsigned int</tt>.
769 751
    template <typename Number>
770 752
    Number uinteger() {
771 753
      return _random_bits::IntConversion<Number, Word>::convert(core);
772 754
    }
773 755

	
774 756
    /// @}
775 757

	
776 758
    unsigned int uinteger() {
777 759
      return uinteger<unsigned int>();
778 760
    }
779 761

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

	
792 774
    int integer() {
793 775
      return integer<int>();
794 776
    }
795 777

	
796 778
    /// \brief Returns a random bool
797 779
    ///
798 780
    /// It returns a random bool. The generator holds a buffer for
799 781
    /// random bits. Every time when it become empty the generator makes
800 782
    /// a new random word and fill the buffer up.
801 783
    bool boolean() {
802 784
      return bool_producer.convert(core);
803 785
    }
804 786

	
805 787
    /// @}
806 788

	
807 789
    ///\name Non-uniform distributions
808 790
    ///
809 791

	
810 792
    ///@{
811 793

	
812 794
    /// \brief Returns a random bool
813 795
    ///
814 796
    /// It returns a random bool with given probability of true result.
815 797
    bool boolean(double p) {
816 798
      return operator()() < p;
817 799
    }
818 800

	
819 801
    /// Standard Gauss distribution
820 802

	
821 803
    /// Standard Gauss distribution.
822 804
    /// \note The Cartesian form of the Box-Muller
823 805
    /// transformation is used to generate a random normal distribution.
824 806
    double gauss()
825 807
    {
826 808
      double V1,V2,S;
827 809
      do {
828 810
        V1=2*real<double>()-1;
829 811
        V2=2*real<double>()-1;
830 812
        S=V1*V1+V2*V2;
831 813
      } while(S>=1);
832 814
      return std::sqrt(-2*std::log(S)/S)*V1;
833 815
    }
0 comments (0 inline)