3

Is there are more direct way to access the RandomState object created on import other than np.random.<some function>.__self__? Both np.random._rand and getattr(np.random, "_rand") raise AttributeError. The former works fine but doesn't seem very transparent/Pythonic, though the most transparent might just be creating a separate RandomState object. The purpose is passing the interal_state variable to a cython function that calls randomkit functions directly.

ayhan
  • 70,170
  • 20
  • 182
  • 203
deasmhumnha
  • 456
  • 4
  • 12
  • 1
    Possible duplicate of [How to access numpy default global random number generator](https://stackoverflow.com/questions/41985484/how-to-access-numpy-default-global-random-number-generator) – MB-F Jul 19 '17 at 12:42
  • I see, and the second answer on that page gives me the answer I was looking for. And future-proofing is a good argument for .__self__. Thanks. – deasmhumnha Jul 19 '17 at 12:49
  • As far I know `__self__` and `_rand` are the only way to access the actual global `RandomState` object. Usually it's better (and more pythonic :)) just to create a new instance and use that. – MB-F Jul 19 '17 at 12:54
  • I think that's what I'm going to do, which also makes for easier unit testing if my functions accept Random State objects as arguments. – deasmhumnha Jul 19 '17 at 13:11

2 Answers2

2

You can use np.random.get_state() to access the random state and np.random.set_state() to set it.

Example usage:

>>> import numpy as np
>>> state = np.random.get_state()
>>> np.random.rand()
0.5951085367670415
>>> np.random.set_state(state)
>>> np.random.rand()
0.5951085367670415

Note that state is just a tuple

>>> state
('MT19937', array([3133054952,  999208925, 1226199620, ..., 3991712371,  943990344,
    955790602], dtype=uint32), 624, 0, 0.0)
Jonas Adler
  • 10,365
  • 5
  • 46
  • 73
  • Then I'd have to (re)create the c level object myself. Why, when it already exists. I suppose my question is why isn't it (more) easily accessible. – deasmhumnha Jul 19 '17 at 12:45
  • What do you want to do with ti that this does not allow you to do? – Jonas Adler Jul 19 '17 at 12:47
  • Call a C function (through Cython) that requires a rk_state C type variable (unless I pass the object from Python back to C) – deasmhumnha Jul 19 '17 at 12:51
  • What C function would require the raw C state? – Jonas Adler Jul 19 '17 at 12:57
  • Any of the C functions in randomkit, which all require a pointer to a rk_state type. I plan on having multiple threads sharing memory within each process, so I'd like to release the GIL for the major computational work (it's a statistical program). – deasmhumnha Jul 19 '17 at 13:05
  • I'm accepting your answer because it's eventually what I decided to do instead of writing a .pxd file for mtrand. But like I said, I still have to convert it back to rk_state, which by no means trivial and come with define performance blows (3 copies of an array of 624 longs), but it works for me since the numbers only have to be generated once. – deasmhumnha Jul 23 '17 at 01:28
0

Found an answer thanks to kazemakase: _rand is accessible directly, I'd just need to import mtrand. But __self__ may be more future proof, if syntax doesn't change.

deasmhumnha
  • 456
  • 4
  • 12