random_generator.hpp 5.3 KB
Newer Older
1
2
3
4
//| Copyright Inria May 2015
//| This project has received funding from the European Research Council (ERC) under
//| the European Union's Horizon 2020 research and innovation programme (grant
//| agreement No 637972) - see http://www.resibots.eu
5
//|
6
7
8
9
10
11
//| Contributor(s):
//|   - Jean-Baptiste Mouret (jean-baptiste.mouret@inria.fr)
//|   - Antoine Cully (antoinecully@gmail.com)
//|   - Kontantinos Chatzilygeroudis (konstantinos.chatzilygeroudis@inria.fr)
//|   - Federico Allocati (fede.allocati@gmail.com)
//|   - Vaios Papaspyros (b.papaspyros@gmail.com)
12
//|
13
14
15
16
17
//| This software is a computer library whose purpose is to optimize continuous,
//| black-box functions. It mainly implements Gaussian processes and Bayesian
//| optimization.
//| Main repository: http://github.com/resibots/limbo
//| Documentation: http://www.resibots.eu/limbo
18
//|
19
20
21
22
23
//| This software is governed by the CeCILL-C license under French law and
//| abiding by the rules of distribution of free software.  You can  use,
//| modify and/ or redistribute the software under the terms of the CeCILL-C
//| license as circulated by CEA, CNRS and INRIA at the following URL
//| "http://www.cecill.info".
24
//|
25
26
27
28
29
//| As a counterpart to the access to the source code and  rights to copy,
//| modify and redistribute granted by the license, users are provided only
//| with a limited warranty  and the software's author,  the holder of the
//| economic rights,  and the successive licensors  have only  limited
//| liability.
30
//|
31
32
33
34
35
36
37
38
39
40
//| In this respect, the user's attention is drawn to the risks associated
//| with loading,  using,  modifying and/or developing or reproducing the
//| software by the user in light of its specific status of free software,
//| that may mean  that it is complicated to manipulate,  and  that  also
//| therefore means  that it is reserved for developers  and  experienced
//| professionals having in-depth computer knowledge. Users are therefore
//| encouraged to load and test the software's suitability as regards their
//| requirements in conditions enabling the security of their systems and/or
//| data to be ensured and,  more generally, to use and operate it in the
//| same conditions as regards security.
41
//|
42
43
//| The fact that you are presently reading this means that you have had
//| knowledge of the CeCILL-C license and that you accept its terms.
44
//|
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//|
//|
//|
//|
//|

#ifndef LIMBO_TOOLS_RANDOM_GENERATOR_HPP
#define LIMBO_TOOLS_RANDOM_GENERATOR_HPP

#include <cstdlib>
#include <cmath>
#include <ctime>
#include <list>
#include <stdlib.h>
#include <random>
#include <utility>
#include <mutex>
Konstantinos Chatzilygeroudis's avatar
Konstantinos Chatzilygeroudis committed
62
#include <limbo/tools/rand_utils.hpp>
63
64
65

namespace limbo {
    namespace tools {
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
66
67
68
69
        /// @ingroup tools
        /// a mt19937-based random generator (mutex-protected)
        ///
        /// usage :
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
70
        /// - RandomGenerator<double>(0.0, 1.0);
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
71
        /// - double r = rgen.rand();
Konstantinos Chatzilygeroudis's avatar
Konstantinos Chatzilygeroudis committed
72
        template <typename D>
73
74
        class RandomGenerator {
        public:
Konstantinos Chatzilygeroudis's avatar
Konstantinos Chatzilygeroudis committed
75
            using result_type = typename D::result_type;
Konstantinos Chatzilygeroudis's avatar
Konstantinos Chatzilygeroudis committed
76
            RandomGenerator(result_type min, result_type max) : _dist(min, max), _rgen(randutils::auto_seed_128{}.base()) {}
Konstantinos Chatzilygeroudis's avatar
Konstantinos Chatzilygeroudis committed
77
78
79
80
81
82
            result_type rand()
            {
                std::lock_guard<std::mutex> lock(_mutex);
                return _dist(_rgen);
            }

83
        private:
Konstantinos Chatzilygeroudis's avatar
Konstantinos Chatzilygeroudis committed
84
85
86
            D _dist;
            std::mt19937 _rgen;
            std::mutex _mutex;
87
        };
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
88
89

        /// @ingroup tools
90
        using rdist_double_t = std::uniform_real_distribution<double>;
Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
91
        /// @ingroup tools
92
        using rdist_int_t = std::uniform_int_distribution<int>;
93
94
        /// @ingroup tools
        using rdist_gauss_t = std::normal_distribution<>;
95

Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
96
97
        /// @ingroup tools
        /// Double random number generator
98
        using rgen_double_t = RandomGenerator<rdist_double_t>;
99

100
101
102
103
        /// @ingroup tools
        /// Double random number generator (gaussian)
        using rgen_gauss_t = RandomGenerator<rdist_gauss_t>;

Jean-Baptiste Mouret's avatar
Jean-Baptiste Mouret committed
104
105
        ///@ingroup tools
        ///integer random number generator
106
        using rgen_int_t = RandomGenerator<rdist_int_t>;
107
108
109
110
111
112

        /// @ingroup tools
        /// random vector in [0, 1]
        ///
        /// - this function is thread safe because the random number generator we use is thread-safe
        /// - we use a C++11 random number generator
113
        Eigen::VectorXd random_vector_bounded(int size)
114
115
116
117
        {
            static rgen_double_t rgen(0.0, 1.0);
            Eigen::VectorXd res(size);
            for (int i = 0; i < size; ++i)
118
                res[i] = rgen.rand();
119
120
            return res;
        }
121
122
123
124
125
126
127
128

        /// @ingroup tools
        /// random vector in R
        ///
        /// - this function is thread safe because the random number generator we use is thread-safe
        /// - we use a C++11 random number generator
        Eigen::VectorXd random_vector_unbounded(int size)
        {
129
            static rgen_gauss_t rgen(0.0, 100.0);
130
131
132
133
134
135
136
137
138
139
140
141
142
143
            Eigen::VectorXd res(size);
            for (int i = 0; i < size; ++i)
                res[i] = rgen.rand();
            return res;
        }

        /// @ingroup tools
        /// random vector wrapper for both bounded and unbounded versions
        Eigen::VectorXd random_vector(int size, bool bounded = true)
        {
            if (bounded)
                return random_vector_bounded(size);
            return random_vector_unbounded(size);
        }
144
145
146
147
    }
}

#endif