gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Minor doc improvements
0 1 0
default
1 file changed with 9 insertions and 23 deletions:
↑ Collapse diff ↑
Ignore white space 48 line context
... ...
@@ -519,52 +519,48 @@
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

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

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

	
561 557
    /// \brief Constructor with array seeding
562 558
    ///
563 559
    /// Constructor with array seeding. The given range should contain
564 560
    /// any number type and the numbers will be converted to the
565 561
    /// architecture word type.
566 562
    template <typename Iterator>
567 563
    Random(Iterator begin, Iterator end) {
568 564
      typedef typename std::iterator_traits<Iterator>::value_type Number;
569 565
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
570 566
    }
... ...
@@ -687,54 +683,48 @@
687 683
    Number real() {
688 684
      return _random_bits::RealConversion<Number, Word>::convert(core);
689 685
    }
690 686

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

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

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

	
711
    /// @}
712

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

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

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

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

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

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

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

	
774
    /// @}
775

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

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

	
792 780
    int integer() {
793 781
      return integer<int>();
794 782
    }
795 783

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

	
805 793
    /// @}
806 794

	
807 795
    ///\name Non-uniform distributions
808 796
    ///
809

	
810 797
    ///@{
811 798

	
812
    /// \brief Returns a random bool
799
    /// \brief Returns a random bool with given probability of true result.
813 800
    ///
814 801
    /// It returns a random bool with given probability of true result.
815 802
    bool boolean(double p) {
816 803
      return operator()() < p;
817 804
    }
818 805

	
819
    /// Standard Gauss distribution
806
    /// Standard normal (Gauss) distribution
820 807

	
821
    /// Standard Gauss distribution.
808
    /// Standard normal (Gauss) distribution.
822 809
    /// \note The Cartesian form of the Box-Muller
823 810
    /// transformation is used to generate a random normal distribution.
824 811
    double gauss()
825 812
    {
826 813
      double V1,V2,S;
827 814
      do {
828 815
        V1=2*real<double>()-1;
829 816
        V2=2*real<double>()-1;
830 817
        S=V1*V1+V2*V2;
831 818
      } while(S>=1);
832 819
      return std::sqrt(-2*std::log(S)/S)*V1;
833 820
    }
834
    /// Gauss distribution with given mean and standard deviation
821
    /// Normal (Gauss) distribution with given mean and standard deviation
835 822

	
836
    /// Gauss distribution with given mean and standard deviation.
823
    /// Normal (Gauss) distribution with given mean and standard deviation.
837 824
    /// \sa gauss()
838 825
    double gauss(double mean,double std_dev)
839 826
    {
840 827
      return gauss()*std_dev+mean;
841 828
    }
842 829

	
843 830
    /// Lognormal distribution
844 831

	
845 832
    /// Lognormal distribution. The parameters are the mean and the standard
846 833
    /// deviation of <tt>exp(X)</tt>.
847 834
    ///
848 835
    double lognormal(double n_mean,double n_std_dev)
849 836
    {
850 837
      return std::exp(gauss(n_mean,n_std_dev));
851 838
    }
852 839
    /// Lognormal distribution
853 840

	
854 841
    /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
855 842
    /// the mean and the standard deviation of <tt>exp(X)</tt>.
856 843
    ///
857 844
    double lognormal(const std::pair<double,double> &params)
858 845
    {
859 846
      return std::exp(gauss(params.first,params.second));
860 847
    }
861 848
    /// Compute the lognormal parameters from mean and standard deviation
862 849

	
863 850
    /// This function computes the lognormal parameters from mean and
864 851
    /// standard deviation. The return value can direcly be passed to
865 852
    /// lognormal().
866 853
    std::pair<double,double> lognormalParamsFromMD(double mean,
867
						   double std_dev)
854
                                                   double std_dev)
868 855
    {
869 856
      double fr=std_dev/mean;
870 857
      fr*=fr;
871 858
      double lg=std::log(1+fr);
872 859
      return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
873 860
    }
874 861
    /// Lognormal distribution with given mean and standard deviation
875
    
862

	
876 863
    /// Lognormal distribution with given mean and standard deviation.
877 864
    ///
878 865
    double lognormalMD(double mean,double std_dev)
879 866
    {
880 867
      return lognormal(lognormalParamsFromMD(mean,std_dev));
881 868
    }
882
    
869

	
883 870
    /// Exponential distribution with given mean
884 871

	
885 872
    /// This function generates an exponential distribution random number
886 873
    /// with mean <tt>1/lambda</tt>.
887 874
    ///
888 875
    double exponential(double lambda=1.0)
889 876
    {
890 877
      return -std::log(1.0-real<double>())/lambda;
891 878
    }
892 879

	
893 880
    /// Gamma distribution with given integer shape
894 881

	
895 882
    /// This function generates a gamma distribution random number.
896 883
    ///
897 884
    ///\param k shape parameter (<tt>k>0</tt> integer)
898 885
    double gamma(int k)
899 886
    {
900 887
      double s = 0;
901 888
      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
902 889
      return s;
903 890
    }
904 891

	
905 892
    /// Gamma distribution with given shape and scale parameter
906 893

	
... ...
@@ -962,66 +949,65 @@
962 949
    /// parameter \c lambda.
963 950
    ///
964 951
    /// The probability mass function of this distribusion is
965 952
    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
966 953
    /// \note The algorithm is taken from the book of Donald E. Knuth titled
967 954
    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
968 955
    /// return value.
969 956

	
970 957
    int poisson(double lambda)
971 958
    {
972 959
      const double l = std::exp(-lambda);
973 960
      int k=0;
974 961
      double p = 1.0;
975 962
      do {
976 963
        k++;
977 964
        p*=real<double>();
978 965
      } while (p>=l);
979 966
      return k-1;
980 967
    }
981 968

	
982 969
    ///@}
983 970

	
984 971
    ///\name Two dimensional distributions
985 972
    ///
986

	
987 973
    ///@{
988 974

	
989 975
    /// Uniform distribution on the full unit circle
990 976

	
991 977
    /// Uniform distribution on the full unit circle.
992 978
    ///
993 979
    dim2::Point<double> disc()
994 980
    {
995 981
      double V1,V2;
996 982
      do {
997 983
        V1=2*real<double>()-1;
998 984
        V2=2*real<double>()-1;
999 985

	
1000 986
      } while(V1*V1+V2*V2>=1);
1001 987
      return dim2::Point<double>(V1,V2);
1002 988
    }
1003
    /// A kind of two dimensional Gauss distribution
989
    /// A kind of two dimensional normal (Gauss) distribution
1004 990

	
1005 991
    /// This function provides a turning symmetric two-dimensional distribution.
1006 992
    /// Both coordinates are of standard normal distribution, but they are not
1007 993
    /// independent.
1008 994
    ///
1009 995
    /// \note The coordinates are the two random variables provided by
1010 996
    /// the Box-Muller method.
1011 997
    dim2::Point<double> gauss2()
1012 998
    {
1013 999
      double V1,V2,S;
1014 1000
      do {
1015 1001
        V1=2*real<double>()-1;
1016 1002
        V2=2*real<double>()-1;
1017 1003
        S=V1*V1+V2*V2;
1018 1004
      } while(S>=1);
1019 1005
      double W=std::sqrt(-2*std::log(S)/S);
1020 1006
      return dim2::Point<double>(W*V1,W*V2);
1021 1007
    }
1022 1008
    /// A kind of two dimensional exponential distribution
1023 1009

	
1024 1010
    /// This function provides a turning symmetric two-dimensional distribution.
1025 1011
    /// The x-coordinate is of conditionally exponential distribution
1026 1012
    /// with the condition that x is positive and y=0. If x is negative and
1027 1013
    /// y=0 then, -x is of exponential distribution. The same is true for the
0 comments (0 inline)