Module ateams.statistics
Sub-modules
ateams.statistics.accepts
ateams.statistics.autocorrelation
ateams.statistics.schedules
Classes
class Chain (model,
accept=<function always.<locals>._>,
statistics={},
steps=10000)-
Simulates a Markov chain on the given Model.
Args
model
:Model
- An instantiated descendant of
Model
(e.g.SwendsenWang
) generating the Markov chain. accept
:Callable
- A function that consumes the complex, model, and state to determine whether we're going to a good place.
statistics
:dict
- A mapping of names to functions which take the complex, model, and state as argument. The Chain keeps track of these at each iteration and stores whatever output is given.
steps
:int
- The number of iterations in the chain.
Expand source code
class Chain: def __init__(self, model, accept=always(), statistics={}, steps=10000): """ Simulates a Markov chain on the given Model. Args: model (Model): An instantiated descendant of `Model` (e.g. `SwendsenWang`) generating the Markov chain. accept (Callable): A function that consumes the complex, model, and state to determine whether we're going to a good place. statistics (dict): A mapping of names to functions which take the complex, model, and state as argument. The Chain keeps track of these at each iteration and stores whatever output is given. steps (int): The number of iterations in the chain. """ self.model = model self.steps = steps self.accept = accept self._exitcode = 0 self._warnings = 0 # Store stats and things. self.functions = statistics self.statistics = { name: [] for name in self.functions.keys() } def __iter__(self): """ Initializes the Chain object as a generator. """ self.step = 0 self.state = tuple([self.model.spins] + []*(self.model._returns-1)) return self def __next__(self): """ Performs the computations specified by the proposal and acceptance schemes. """ # While we haven't reached the max number of steps, propose a new plan, # check whether it's acceptable/valid, and continue. while self.step < self.steps: # Propose the next state and check whether we want to accept it as # the next state or not; assign whichever state is chosen to the # Model. try: proposed = self.model._proposal(self.step) except NumericalInstabilityWarning: self._exitcode = 2 self._warnings += 1 proposed = self.state self.state = proposed if self.accept(self.state, proposed, self.step) else self.state self.model._assign(self.state[0]) # Compute statistics. for name, function in self.functions.items(): self.statistics[name].append(function(self.model, self.state)) # Iterate. self.step += 1 return self.state raise StopIteration def progress(self, dynamic_ncols=True, desc=""): """ Progress bar. Returns: `tqdm` iterable. """ from tqdm.auto import tqdm return tqdm(self, total=self.steps, dynamic_ncols=dynamic_ncols, desc=desc)
Methods
def progress(self, dynamic_ncols=True, desc='')
-
Progress bar.
Returns
tqdm
iterable.
class Player
-
Safely "replays" recorded
Chain
output.Expand source code
class Player(): """ Safely "replays" recorded `Chain` output. """ def __init__(self): pass def playback(self, S, fp:str, outputs: dict, compressed=True, steps=None): """ Initialize playback; context management. Args: S (Model): `Model` which matches the configuration on which the `Chain` was simulated. **If the `Model` does not have the same parameters as the `Model` on which the recorded chain was simulated, statistical results from this playback may not be accurate. fp (str): File in which records are stored. outputs (dict): Dictionary mapping integer keys to initial states. compressed (bool): Are the data compressed? steps (int): How many steps does this chain take? Returns: This Player object. """ # Configure filepath, file object, and JsonLines Reader. self._fp = fp self._file = gzip.open(self._fp, "rb") if compressed else open(self._fp, "r") self._reader = jsl.Reader(self._file) self._steps = steps self.outputs = outputs.copy() # Enter context management. return self.__enter__() def __iter__(self): """ This `Player` is a generator which yields states of the recorded chain. """ return self def __next__(self): """ Iteration magic method. """ # Get the next configuration by calling __next__() on the reader. try: configuration = self._reader.read() except: raise StopIteration for k, output in configuration.items(): for spin, fs in output.items(): for f in fs: self.outputs[int(k)][int(f)] = int(spin) return tuple(self.outputs.values()) def __enter__(self): """ Required context management magic method. """ return self def __exit__(self, exc_type, exc_value, exc_tb): """ Required context management magic method; kills the reader and the file. """ self._reader.close() self._file.close() def progress(self): from tqdm.auto import tqdm return tqdm(self, total=self._steps)
Methods
def playback(self, S, fp: str, outputs: dict, compressed=True, steps=None)
-
Initialize playback; context management.
Args
S
:Model
Model
which matches the configuration on which theChain
was simulated. **If theModel
does not have the same parameters as theModel
on which the recorded chain was simulated, statistical results from this playback may not be accurate.fp
:str
- File in which records are stored.
outputs
:dict
- Dictionary mapping integer keys to initial states.
compressed
:bool
- Are the data compressed?
steps
:int
- How many steps does this chain take?
Returns
This Player object.
def progress(self)
class Recorder
-
Safely "records" states from a Chain by tracking changes between successive states, and writing these changes — alongside the initial state — to file.
Expand source code
class Recorder: """ Safely "records" states from a Chain by tracking changes between successive states, and writing these changes --- alongside the initial state --- to file. """ def __init__(self): pass def record(self, M: Chain, fp: str, outputs: dict, compressed:bool=True): """ Called to configure the recording apparatus for the Chain, and *should* be used as a context manager (i.e. with the `with` statement). Args: M (Chain): `potts.Chain` object to be recorded; `Recorder` needs access to the `Model` and `Complex` subobjects. fp (str): Filename. outputs (dict): Dictionary mapping integer keys to initial states. compressed (bool): Do we want to compress our outputs? The answer should only be "no" if we're debugging something. Returns: This `Recorder` object. """ # Set up filepath, the actual file I/O object (gzip-compressed if we want # compression, otherwise just a standard file), and initialize a JsonLines # Writer. self._fp = fp self._file = gzip.open(f"{self._fp}", "wb") if compressed else open(self._fp, "w") self._writer = jsl.Writer(self._file) # Save the chain for access during iteration; set the "previous" state to # be all -1s, since the first state yielded by iterating over the Chain # is the initial state, and we need to record the whole thing; fix a list # of possible integer states for later. self.chain = M self.outputs = outputs.copy() self.previous = tuple(self.outputs.values()) # Enter the context manager. return self.__enter__() def store(self, state: tuple) -> None: """ Stores a state yielded by iteration over a `Chain`. Args: state (tuple): Tuple of assignments or other data points. """ delta = { } for k, output in zip(self.outputs.keys(), state): # Find the indices where spin assignments *differ*, then categorize the # indices based on their spin value. *Should* save some space when # writing to file. indices = (~np.equal(self.previous[k], output)).astype(int).nonzero()[0] faces = { int(s): [] for s in set(np.array(output)) } for i in indices: faces[int(output[i])].append(int(i)) # Record the "delta," i.e. the changes encountered from the previous # state. delta[k] = faces # Write the delta to file and update the previous state to be the current # one. self._writer.write(delta) self.previous = state def __enter__(self): """ Required context management magic method. """ return self def __exit__(self, exc_type, exc_value, exc_tb): """ Required context management magic method; kills the writer and the file. """ self._writer.close() self._file.close()
Methods
def record(self,
M: ateams.statistics.Chain.Chain,
fp: str,
outputs: dict,
compressed: bool = True)-
Called to configure the recording apparatus for the Chain, and should be used as a context manager (i.e. with the
with
statement).Args
M
:Chain
potts.Chain
object to be recorded;Recorder
needs access to theModel
andComplex
subobjects.fp
:str
- Filename.
outputs
:dict
- Dictionary mapping integer keys to initial states.
compressed
:bool
- Do we want to compress our outputs? The answer should only be "no" if we're debugging something.
Returns
This
Recorder
object. def store(self, state: tuple) ‑> None
-
Stores a state yielded by iteration over a
Chain
.Args
state
:tuple
- Tuple of assignments or other data points.