    // Copyright (C) 2003  Davis E. King (davis@dlib.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #undef DLIB_RAND_KERNEl_ABSTRACT_
    #ifdef DLIB_RAND_KERNEl_ABSTRACT_

    #include <string>
    #include <complex>
    #include "../uintn.h"

    namespace dlib
    {

        class rand
        {

            /*!
                INITIAL VALUE
                    get_seed() == ""

                WHAT THIS OBJECT REPRESENTS
                    This object represents a pseudorandom number generator.
            !*/

            public:

                rand(
                );
                /*!
                    ensures
                        - #*this is properly initialized
                    throws
                        - std::bad_alloc
                !*/

                rand (
                    time_t seed_value
                );
                /*!
                    ensures
                        - #*this is properly initialized
                        - #get_seed() == cast_to_string(seed_value)
                        - This version of the constructor is equivalent to using
                          the default constructor and then calling set_seed(cast_to_string(seed_value))
                    throws
                        - std::bad_alloc
                !*/

                rand (
                    const std::string& seed_value
                );
                /*!
                    ensures
                        - #*this is properly initialized
                        - #get_seed() == seed_value
                        - This version of the constructor is equivalent to using
                          the default constructor and then calling set_seed(seed_value)
                    throws
                        - std::bad_alloc
                !*/

                virtual ~rand(
                );
                /*!
                    ensures
                        - all memory associated with *this has been released
                !*/

                void clear(
                );
                /*!
                    ensures
                        - #*this has its initial value
                    throws
                        - std::bad_alloc
                            if this exception is thrown then *this is unusable
                            until clear() is called and succeeds
                !*/

                const std::string& get_seed (
                );
                /*!
                    ensures
                        - returns the string currently being used as the random seed.
                !*/

                void set_seed (
                    const std::string& value
                );
                /*!
                    ensures
                        - #get_seed() == value
                !*/

                unsigned char get_random_8bit_number (
                );
                /*!
                    ensures
                        - returns a pseudorandom number in the range 0 to 255
                !*/

                uint16 get_random_16bit_number (
                );
                /*!
                    ensures
                        - returns a pseudorandom number in the range 0 to 2^16-1
                !*/

                uint32 get_random_32bit_number (
                );
                /*!
                    ensures
                        - returns a pseudorandom number in the range 0 to 2^32-1
                !*/

                uint64 get_random_64bit_number (
                );
                /*!
                    ensures
                        - returns a pseudorandom number in the range 0 to 2^64-1
                !*/

                float get_random_float (
                );
                /*!
                    ensures
                        - returns a random float number N where:  0.0 <= N < 1.0.
                !*/

                double get_random_double (
                );
                /*!
                    ensures
                        - returns a random double number N where:  0.0 <= N < 1.0.
                !*/

                double get_double_in_range (
                    double begin,
                    double end
                );
                /*!
                    requires
                        - begin <= end
                    ensures
                        - if (begin < end) then
                            - returns a random double number N where:  begin <= N < end.
                        - else
                            - returns begin
                !*/

                long long get_integer_in_range(
                    long long begin,
                    long long end
                );
                /*!
                    requires
                        - begin <= end
                    ensures
                        - returns a random integer N selected from the range: begin <= N < end
                          The integer is selected uniformly at random.  If begin==end then
                          begin is returned.
                !*/

                long long get_integer(
                    long long end
                );
                /*!
                    requires
                        - 0 <= end
                    ensures
                        - returns get_integer_in_range(0,end)
                !*/

                double get_random_gaussian (
                );
                /*!
                    ensures
                        - returns a random number sampled from a Gaussian distribution
                          with mean 0 and standard deviation 1.
                !*/

                std::complex<double> get_random_complex_gaussian (
                );
                /*!
                    ensures
                        - returns a random complex number sampled from a Gaussian distribution
                          with mean 0 and standard deviation 1.
                !*/

                double get_random_exponential (
                    double lambda
                );
                /*!
                    ensures
                        - returns a random number sampled from an exponential distribution
                          with rate parameter lambda
                !*/

                double get_random_weibull (
                    double lambda,
                    double k,
                    double gamma
                );
                /*!
                    ensures
                        - returns a random number sampled from a Weibull distribution
                          with shape parameter k, scale parameter lambda and
                          threshold parameter gamma.
                !*/

                double get_random_beta (
                    double alpha,
                    double beta,
                )
                /*!
                    requires
                        - alpha > 0
                        - beta > 0
                    ensures
                        - returns a random number sampled from a Beta distribution
                          with shape parameters alpha and beta.
                !*/

                void swap (
                    rand& item
                );
                /*!
                    ensures
                        - swaps *this and item
                !*/

        };

        inline void swap (
            rand& a,
            rand& b
        ) { a.swap(b); }
        /*!
            provides a global swap function
        !*/

        void serialize (
            const rand& item,
            std::ostream& out
        );
        /*!
            provides serialization support
        !*/

        void deserialize (
            rand& item,
            std::istream& in
        );
        /*!
            provides deserialization support
        !*/
    }

    #endif // DLIB_RAND_KERNEl_ABSTRACT_