|
4 | 4 | """ |
5 | 5 | This module provides random number generators. |
6 | 6 | """ |
7 | | -from typing import Literal |
8 | 7 |
|
9 | 8 | import numpy as np |
10 | 9 | from numpy.random import BitGenerator |
@@ -43,6 +42,24 @@ def default_generator(seed) -> Generator: |
43 | 42 | ) |
44 | 43 |
|
45 | 44 |
|
| 45 | +def conditional_negate( |
| 46 | + randoms: np.ndarray | float, condition: bool |
| 47 | +) -> np.ndarray | float: |
| 48 | + """ |
| 49 | + Negates the given random numbers when a condition is met. |
| 50 | +
|
| 51 | + :param randoms: The random numbers. |
| 52 | + :param condition: The condition. |
| 53 | + :return: The negated or original random numbers. |
| 54 | + """ |
| 55 | + if condition: |
| 56 | + if isinstance(randoms, np.ndarray): |
| 57 | + randoms[:] = -randoms[:] |
| 58 | + else: |
| 59 | + randoms = -randoms |
| 60 | + return randoms |
| 61 | + |
| 62 | + |
46 | 63 | class DefaultGenerator(Generating): |
47 | 64 | """The default random number generator.""" |
48 | 65 |
|
@@ -86,80 +103,25 @@ class DefaultNormal(Normal): |
86 | 103 | """The default normal random deviate.""" |
87 | 104 |
|
88 | 105 | _g: Generator |
89 | | - |
90 | | - def __init__(self, seed: int | np.ndarray | BitGenerator | None = None): |
91 | | - """ |
92 | | - Creates a new random deviate. |
93 | | -
|
94 | | - :param seed: The seed. |
95 | | - """ |
96 | | - self._g = default_generator(seed) |
97 | | - |
98 | | - def random(self) -> float: |
99 | | - return self._g.standard_normal() |
100 | | - |
101 | | - def randoms(self, randoms: np.ndarray) -> np.ndarray: |
102 | | - self._g.standard_normal(dtype=randoms.dtype, out=randoms) |
103 | | - return randoms |
104 | | - |
105 | | - |
106 | | -class DecileNormal(Normal): |
107 | | - """ |
108 | | - The decile normal random deviate. |
109 | | -
|
110 | | - Generates random deviates, which are uniformly distributed in a |
111 | | - selected decile of the standard normal distribution. |
112 | | - """ |
113 | | - |
114 | | - _g: Generator |
115 | | - |
116 | | - _q: np.ndarray |
117 | | - """The deciles of the normal distribution.""" |
118 | | - _s: int | Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
119 | | - """The decile selector.""" |
| 106 | + _antithetic: bool |
120 | 107 |
|
121 | 108 | def __init__( |
122 | | - self, s: int, seed: int | np.ndarray | BitGenerator | None = None |
| 109 | + self, |
| 110 | + seed: int | np.ndarray | BitGenerator | None = None, |
| 111 | + antithetic: bool = False, |
123 | 112 | ): |
124 | 113 | """ |
125 | 114 | Creates a new random deviate. |
126 | 115 |
|
127 | | - :param s: The decile selector. |
128 | 116 | :param seed: The seed. |
| 117 | + :param antithetic: To generate antithetic pairs of random numbers. |
129 | 118 | """ |
130 | | - self._s = s % 10 |
131 | 119 | self._g = default_generator(seed) |
132 | | - self._q = np.array( |
133 | | - [ |
134 | | - -3.09023, |
135 | | - -1.28155, |
136 | | - -0.841621, |
137 | | - -0.524401, |
138 | | - -0.253347, |
139 | | - 0.0, |
140 | | - 0.253347, |
141 | | - 0.524401, |
142 | | - 0.841621, |
143 | | - 1.28155, |
144 | | - 3.09023, |
145 | | - ] |
146 | | - ) |
| 120 | + self._antithetic = antithetic |
147 | 121 |
|
148 | 122 | def random(self) -> float: |
149 | | - return (self.sup - self.inf) * self._g.random() + self.inf |
| 123 | + return conditional_negate(self._g.standard_normal(), self._antithetic) |
150 | 124 |
|
151 | 125 | def randoms(self, randoms: np.ndarray) -> np.ndarray: |
152 | | - self._g.random(dtype=randoms.dtype, out=randoms) |
153 | | - randoms *= self.sup - self.inf |
154 | | - randoms += self.inf |
155 | | - return randoms |
156 | | - |
157 | | - @property |
158 | | - def sup(self) -> float: |
159 | | - """Returns the supremum of the selected decile.""" |
160 | | - return self._q[self._s + 1] |
161 | | - |
162 | | - @property |
163 | | - def inf(self) -> float: |
164 | | - """Returns the infimum of the selected decile.""" |
165 | | - return self._q[self._s] |
| 126 | + self._g.standard_normal(dtype=randoms.dtype, out=randoms) |
| 127 | + return conditional_negate(randoms, self._antithetic) |
0 commit comments