random.RandomState and deepcopy
It is common that to guarantee good statistical independence between various random generators, a singleton instance of an RNG is shared between them. So I typically have various random generator objects, which (sometimes several levels objects deep) embed an instance of RandomState. Now I have a requirement to copy a generator object (without knowing exactly what that generator object is). My solution is to use deepcopy on the top-level object. But I need to overload __deepcopy__ on the singleton RandomState object. Unfortunately, RandomState doesn't allow customization of __deepcopy__ (or anything else). And it has no __dict__. My solution is: class shared_random_state (object): def __init__ (self, rs): self.rs = rs def __getattr__ (self, attr): return getattr (self.rs, attr) def __deepcopy__ (self): return self An example usage: rs = shared_random_state (RandomState(0)) from exponential import exponential e = exponential (rs, 1) where exponential is: class exponential (object): def __init__ (self, rs, mu): self.rs = rs self.mu = mu def __call__ (self, size=None): if size == None: return self.rs.exponential (self.mu, 1)[0] else: return self.rs.exponential (self.mu, size) def __repr__ (self): return 'exp(%s)' % self.mu I wonder if anyone has any other suggestions? Personally, I would prefer if numpy provided a more direct solution to this. Either by providing for overloading RandomState deepcopy, or by making the copy behavior switchable with a flag to the constructor. -- Those who fail to understand recursion are doomed to repeat it
On Fri, Mar 13, 2015 at 5:34 PM, Neal Becker <ndbecker2@gmail.com> wrote:
It is common that to guarantee good statistical independence between
various
random generators, a singleton instance of an RNG is shared between them.
So I typically have various random generator objects, which (sometimes several levels objects deep) embed an instance of RandomState.
Now I have a requirement to copy a generator object (without knowing exactly what that generator object is).
Or rather, you want the generator object to *avoid* copies by returning itself when a copy is requested of it.
My solution is to use deepcopy on the top-level object. But I need to overload __deepcopy__ on the singleton RandomState object.
Unfortunately, RandomState doesn't allow customization of __deepcopy__ (or anything else). And it has no __dict__.
You can always subclass RandomState to override its __deepcopy__. -- Robert Kern
Robert Kern wrote:
On Fri, Mar 13, 2015 at 5:34 PM, Neal Becker <ndbecker2@gmail.com> wrote:
It is common that to guarantee good statistical independence between
various
random generators, a singleton instance of an RNG is shared between them.
So I typically have various random generator objects, which (sometimes several levels objects deep) embed an instance of RandomState.
Now I have a requirement to copy a generator object (without knowing exactly what that generator object is).
Or rather, you want the generator object to *avoid* copies by returning itself when a copy is requested of it.
My solution is to use deepcopy on the top-level object. But I need to overload __deepcopy__ on the singleton RandomState object.
Unfortunately, RandomState doesn't allow customization of __deepcopy__ (or anything else). And it has no __dict__.
You can always subclass RandomState to override its __deepcopy__.
-- Robert Kern
Yes, I think I prefer this: from numpy.random import RandomState class shared_random_state (RandomState): def __init__ (self, rs): RandomState.__init__(self, rs) def __deepcopy__ (self, memo): return self Although, that means I have to use it like this: rs = shared_random_state (0) where I really would prefer (for aesthetic reasons): rs = shared_random_state (RandomState(0)) but I don't know how to do that if shared_random_state inherits from RandomState. -- Those who fail to understand recursion are doomed to repeat it
On Fri, Mar 13, 2015 at 5:59 PM, Neal Becker <ndbecker2@gmail.com> wrote:
Robert Kern wrote:
On Fri, Mar 13, 2015 at 5:34 PM, Neal Becker <ndbecker2@gmail.com>
It is common that to guarantee good statistical independence between
various
random generators, a singleton instance of an RNG is shared between
wrote: them.
So I typically have various random generator objects, which (sometimes several levels objects deep) embed an instance of RandomState.
Now I have a requirement to copy a generator object (without knowing
exactly
what that generator object is).
Or rather, you want the generator object to *avoid* copies by returning itself when a copy is requested of it.
My solution is to use deepcopy on the top-level object. But I need to overload __deepcopy__ on the singleton RandomState object.
Unfortunately, RandomState doesn't allow customization of __deepcopy__ (or anything else). And it has no __dict__.
You can always subclass RandomState to override its __deepcopy__.
-- Robert Kern
Yes, I think I prefer this:
from numpy.random import RandomState
class shared_random_state (RandomState): def __init__ (self, rs): RandomState.__init__(self, rs)
def __deepcopy__ (self, memo): return self
Although, that means I have to use it like this:
rs = shared_random_state (0)
where I really would prefer (for aesthetic reasons):
rs = shared_random_state (RandomState(0))
but I don't know how to do that if shared_random_state inherits from RandomState.
<shrug> If you insist: class shared_random_state(RandomState): def __init__(self, rs): self.__setstate__(rs.__getstate__()) def __deepcopy__(self, memo): return self -- Robert Kern
participants (2)
-
Neal Becker
-
Robert Kern