Provide the random.random algorithms using a numpy.random bit generator The intent is to allow people to contribute code that uses Python's random library, but still allow users to provide a single easily controlled random bit-stream for all work with NetworkX. This implementation is ba
| 299 | |
| 300 | |
| 301 | class PythonRandomViaNumpyBits(random.Random): |
| 302 | """Provide the random.random algorithms using a numpy.random bit generator |
| 303 | |
| 304 | The intent is to allow people to contribute code that uses Python's random |
| 305 | library, but still allow users to provide a single easily controlled random |
| 306 | bit-stream for all work with NetworkX. This implementation is based on helpful |
| 307 | comments and code from Robert Kern on NumPy's GitHub Issue #24458. |
| 308 | |
| 309 | This implementation supersedes that of `PythonRandomInterface` which rewrote |
| 310 | methods to account for subtle differences in API between `random` and |
| 311 | `numpy.random`. Instead this subclasses `random.Random` and overwrites |
| 312 | the methods `random`, `getrandbits`, `getstate`, `setstate` and `seed`. |
| 313 | It makes them use the rng values from an input numpy `RandomState` or `Generator`. |
| 314 | Those few methods allow the rest of the `random.Random` methods to provide |
| 315 | the API interface of `random.random` while using randomness generated by |
| 316 | a numpy generator. |
| 317 | """ |
| 318 | |
| 319 | def __init__(self, rng=None): |
| 320 | try: |
| 321 | import numpy as np |
| 322 | except ImportError: |
| 323 | msg = "numpy not found, only random.random available." |
| 324 | warnings.warn(msg, ImportWarning) |
| 325 | |
| 326 | if rng is None: |
| 327 | self._rng = np.random.mtrand._rand |
| 328 | else: |
| 329 | self._rng = rng |
| 330 | |
| 331 | # Not necessary, given our overriding of gauss() below, but it's |
| 332 | # in the superclass and nominally public, so initialize it here. |
| 333 | self.gauss_next = None |
| 334 | |
| 335 | def random(self): |
| 336 | """Get the next random number in the range 0.0 <= X < 1.0.""" |
| 337 | return self._rng.random() |
| 338 | |
| 339 | def getrandbits(self, k): |
| 340 | """getrandbits(k) -> x. Generates an int with k random bits.""" |
| 341 | if k < 0: |
| 342 | raise ValueError("number of bits must be non-negative") |
| 343 | numbytes = (k + 7) // 8 # bits / 8 and rounded up |
| 344 | x = int.from_bytes(self._rng.bytes(numbytes), "big") |
| 345 | return x >> (numbytes * 8 - k) # trim excess bits |
| 346 | |
| 347 | def getstate(self): |
| 348 | return self._rng.__getstate__() |
| 349 | |
| 350 | def setstate(self, state): |
| 351 | self._rng.__setstate__(state) |
| 352 | |
| 353 | def seed(self, *args, **kwds): |
| 354 | "Do nothing override method." |
| 355 | raise NotImplementedError("seed() not implemented in PythonRandomViaNumpyBits") |
| 356 | |
| 357 | |
| 358 | ################################################################## |
no outgoing calls
no test coverage detected
searching dependent graphs…