0

I'm working on creating a subclass of random.Random() where the generator is actually NumPy's default Random Generator.

The reason for this is, I can leverage parallel execution using NumPy's generator via the SeedSequence object.

Overriding methods random() and seed() is fairly easy, however, I also need to override method getrandbits(), but I haven't been able to find any Numpy's equivalent function/solution. getrandbits() is used heavily by all other functions of class random.Random().

6
  • 1
    Out of curiosity, why do you need to subclass stdlib random generators? Commented Jan 11, 2022 at 15:02
  • 1
    you can take a look at the source for random.getrandbits and port that to numpy Commented Jan 11, 2022 at 15:05
  • @jakub indeed, my thinking is however there's an easier solution in front of my eyes and I just don't see it. Looking at the code, it boils down to replicate int.from_bytes(_urandom(numbytes), 'big'). Will work on that if I don't get the easier, expected answer. Commented Jan 11, 2022 at 15:14
  • 1
    @AndrasDeak The ultimate goal is to use that subclass for creating faker.Faker objects. All functions in Faker use the underlying Random generator, specifically the functions random() and getrandbits(). Class random.Random() however cannot be parallelized and the BitGenerator cannot be advanced (PCG64 can). Commented Jan 11, 2022 at 15:18
  • @jakub This could be the gist of the solution, unless there's a simpler, higher level function. int.from_bytes(np.random.default_rng().bytes(numbytes), 'big'). Thanks! Commented Jan 11, 2022 at 15:28

1 Answer 1

1

As @jakub mentioned in the comments, easiest way is to port the source code to NumPy.

    def getrandbits(self, k):
        print()
        """getrandbits(k) -> x.  Generates an int with k random bits."""
        if k < 0:
            raise ValueError('number of bits must be non-negative')
        numbytes = (k + 7) // 8                       # bits / 8 and rounded up
        x = int.from_bytes(self.rng.bytes(numbytes), 'big')
        return x >> (numbytes * 8 - k)                # trim excess bits

where self.rng is an instance of np.random.Generator.

Sign up to request clarification or add additional context in comments.

1 Comment

you could also do something similar with a raw BitGenerator as it returns a uint64 ndarray, e.g. int.from_bytes(bitgen.random_raw(num_u64s, 'big'))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.