Skip to content
Snippets Groups Projects
Random.H 9.03 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        \\  /    A nd           | www.openfoam.com
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        Copyright (C) 2011-2015 OpenFOAM Foundation
    
        Copyright (C) 2017-2020 OpenCFD Ltd.
    
    -------------------------------------------------------------------------------
    License
        This file is part of OpenFOAM.
    
    
        OpenFOAM is free software: you can redistribute it and/or modify it
        under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.
    
    
        OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
        ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        for more details.
    
        You should have received a copy of the GNU General Public License
    
        along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
    
        Random number generator.
    
    
    
    \*---------------------------------------------------------------------------*/
    
    #ifndef Random_H
    #define Random_H
    
    
    #include "Rand48.H"
    #include "label.H"
    #include "scalar.H"
    #include <random>
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    
    // Forward Declarations
    
    template<class T> class UList;
    
    /*---------------------------------------------------------------------------*\
                               Class Random Declaration
    \*---------------------------------------------------------------------------*/
    
    class Random
    {
    
            //- Initial random number seed
            label seed_;
    
            //- Random number generator on the int32 interval [0,2^31)
    
            //- Uniform distribution on the scalar interval [0,1]
    
            std::uniform_real_distribution<scalar> uniform01_;
    
            //- Is there a gaussian sample cached?
    
            bool hasGaussSample_;
    
            //- The cached gaussian sample value
    
            scalar gaussSample_;
    
    
        // Private Member Functions
    
    
            //- A uniformly distributed floating-point random number [0,1]
            inline scalar scalar01();
    
            // Forward Declarations - generator classes
    
            template<class T> class uniformGeneratorOp;
            template<class T> class gaussianGeneratorOp;
    
    
    
        // Public Static Data
    
            //- The default seed value (name may change in the future)
            static constexpr label defaultSeed = 123456;
    
    
    
            //- Construct with seed value
    
            explicit Random(const label seedValue = defaultSeed);
    
            //- Copy construct with possible reset of seed
            Random(const Random& rnd, const bool reset);
    
            //- The initial random number seed that was used
            inline label seed() const;
    
            //- Reset the random number generator seed.
            inline void reset(const label seedValue);
    
            //- Return a random bit
            inline int bit();
    
            //- Return a sample whose components lie in the range [0,1]
    
            template<class Type>
            Type sample01();
    
            //- Return a sample whose components are normally distributed
    
            //- with zero mean and unity variance N(0,1)
    
            template<class Type>
            Type GaussNormal();
    
            //- Return a sample on the interval [start,end]
    
            template<class Type>
            Type position(const Type& start, const Type& end);
    
            //- Randomise value in the range [0,1]
    
            template<class Type>
            void randomise01(Type& value);
    
            //- Shuffle the values in the list
            template<class Type>
            void shuffle(UList<Type>& values);
    
        // Global random numbers - consistent across all processors
    
            //- Return a sample whose components lie in the range [0,1]
    
            template<class Type>
            Type globalSample01();
    
            //- Return a sample whose components are normally distributed
    
            //- with zero mean and unity variance N(0,1)
    
            template<class Type>
            Type globalGaussNormal();
    
            //- Return a sample on the interval [start,end]
    
            template<class Type>
            Type globalPosition(const Type& start, const Type& end);
    
            //- Randomise value in the range 0-1
            template<class Type>
            void globalRandomise01(Type& value);
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Template specialisations
    
    template<>
    scalar Random::sample01<scalar>();
    
    template<>
    label Random::sample01<label>();
    
    template<>
    scalar Random::GaussNormal<scalar>();
    
    template<>
    label Random::GaussNormal<label>();
    
    template<>
    
    scalar Random::position<scalar>(const scalar& start, const scalar& end);
    
    
    template<>
    label Random::position<label>(const label& start, const label& end);
    
    template<>
    scalar Random::globalSample01<scalar>();
    
    template<>
    label Random::globalSample01<label>();
    
    template<>
    scalar Random::globalGaussNormal<scalar>();
    
    template<>
    label Random::globalGaussNormal<label>();
    
    template<>
    
    scalar Random::globalPosition<scalar>(const scalar& start, const scalar& end);
    
    
    template<>
    label Random::globalPosition<label>(const label& start, const label& end);
    
    
    
    /*---------------------------------------------------------------------------*\
                     Class Random::uniformGeneratorOp Declaration
    \*---------------------------------------------------------------------------*/
    
    //- A generator class returning a uniformly distributed random number
    //- on the given interval.
    //
    //  \sa std::generate()
    template<class T>
    class Random::uniformGeneratorOp
    :
        public Random
    {
    
        // Private Data
    
    
            //- The interval
            const T min_;
            const T max_;
    
    
        // Private Member Functions
    
            //- Generate a random number. Treat as mutable.
            T generate() const
            {
                return const_cast<uniformGeneratorOp&>(*this)
                    .position<T>(min_, max_);
            }
    
    
    public:
    
        // Constructors
    
    
            //- Default construct or with seed value. Uses default [0,1] interval
    
            explicit uniformGeneratorOp(const label seed = Random::defaultSeed)
            :
                uniformGeneratorOp(seed, pTraits<T>::zero, pTraits<T>::one)
            {}
    
            //- Construct with specified interval, using default seed
            uniformGeneratorOp(const T& minval, const T& maxval)
            :
                uniformGeneratorOp(Random::defaultSeed, minval, maxval)
            {}
    
            //- Construct with seed value and specified interval
            uniformGeneratorOp(const label seed, const T& minval, const T& maxval)
            :
                Random(seed),
                min_(minval),
                max_(maxval)
            {}
    
    
        // Member Operators
    
            //- Generate a random number
            T operator()()
            {
                return generate();
            }
    
            //- Ignore parameter and generate a random number, which allows it
            //- to be used as a replacement for general unary operators.
            template<class U>
            T operator()(const U&) const
            {
                return generate();
            }
    };
    
    
    /*---------------------------------------------------------------------------*\
                     Class Random::gaussianGeneratorOp Declaration
    \*---------------------------------------------------------------------------*/
    
    //- A generator class returning a gaussian distributed random number.
    //
    //  \sa std::generate()
    template<class T>
    class Random::gaussianGeneratorOp
    :
        public Random
    {
        // Private Member Functions
    
            //- Generate a random number. Treat as mutable.
            T generate() const
            {
                return const_cast<gaussianGeneratorOp&>(*this)
                    .GaussNormal<T>();
            }
    
    
    public:
    
        // Constructors
    
    
            //- Default construct or with seed value. Uses default [0,1] interval
    
            explicit gaussianGeneratorOp(const label seed = Random::defaultSeed)
            :
                Random(seed)
            {}
    
    
        // Member Operators
    
            //- Generate a random number
            T operator()()
            {
                return generate();
            }
    
            //- Ignore parameter and generate a random number, which allows it
            //- to be used as a replacement for general unary operators.
            template<class U>
            T operator()(const U&) const
            {
                return generate();
            }
    };
    
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    
    #include "RandomI.H"
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    #ifdef NoRepository
    #   include "RandomTemplates.C"
    #endif
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    
    #endif
    
    // ************************************************************************* //