1 #ifndef PYTHONIC_INCLUDE_NUMPY_RANDOM_GENERATOR_HPP
2 #define PYTHONIC_INCLUDE_NUMPY_RANDOM_GENERATOR_HPP
3 
4 #include <random>
5 
6 PYTHONIC_NS_BEGIN
7 namespace numpy
8 {
9   namespace random
10   {
11     namespace details
12     {
13 
14       /*
15        * PCG Random Number Generation for C.
16        *
17        * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
18        *
19        * Licensed under the Apache License, Version 2.0 (the "License");
20        * you may not use this file except in compliance with the License.
21        * You may obtain a copy of the License at
22        *
23        *     http://www.apache.org/licenses/LICENSE-2.0
24        *
25        * Unless required by applicable law or agreed to in writing, software
26        * distributed under the License is distributed on an "AS IS" BASIS,
27        * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
28        *implied.
29        * See the License for the specific language governing permissions and
30        * limitations under the License.
31        *
32        * For additional information about the PCG random number generation
33        *scheme,
34        * including its license and other licensing options, visit
35        *
36        *       http://www.pcg-random.org
37        */
38 
39       class pcg
40       {
41         uint64_t state;
42         static constexpr uint64_t inc = 0xda3e39cb94b95bdbULL;
43 
44       public:
45         using result_type = uint32_t;
min()46         static constexpr result_type min()
47         {
48           return 0;
49         }
max()50         static constexpr result_type max()
51         {
52           return std::numeric_limits<uint32_t>::max();
53         }
operator ==(pcg const & self,pcg const & other)54         friend bool operator==(pcg const &self, pcg const &other)
55         {
56           return self.state == other.state;
57         }
operator !=(pcg const & self,pcg const & other)58         friend bool operator!=(pcg const &self, pcg const &other)
59         {
60           return self.state != other.state;
61         }
62 
pcg()63         pcg() : state(0)
64         {
65         }
pcg(std::random_device & rd)66         explicit pcg(std::random_device &rd)
67         {
68           seed(rd());
69         }
70 
seed(uint64_t value=0)71         void seed(uint64_t value = 0)
72         {
73           state = value;
74           (void)operator()();
75         }
76 
operator ()()77         result_type operator()()
78         {
79           uint64_t oldstate = state;
80           state = oldstate * 6364136223846793005ULL + inc;
81           uint32_t xorshifted = uint32_t(((oldstate >> 18u) ^ oldstate) >> 27u);
82           int rot = oldstate >> 59u;
83           return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
84         }
85 
discard(std::size_t n)86         void discard(std::size_t n)
87         {
88           for (std::size_t i = 0; i < n; ++i)
89             operator()();
90         }
91 
92       private:
93       };
94 
95       std::random_device rd;
96       pcg generator(rd);
97     } // namespace details
98   }   // namespace random
99 }
100 PYTHONIC_NS_END
101 
102 #endif
103