Landscape Analysis¶
The neet
module provides the LandscapeMixin
class from which
the neet.Network
class inherits. This endows all networks with the
various methods for computing the various landscape-related properties of the
networks, such as LandscapeMixin.attractors
. These properties are often
associated with the state space of the network; however, we have opted to
provide them via a separate mixin because the neet.StateSpace
class
represents an unstructured set of states, with no dynamical information
A key feature of the LandscapeMixin
is that it is lazy and caches
results as they are computed. For example, the attractors of the landscape are
computed the first the user requests the LandscapeMixin.attractors
property, but the result is cached in the LandscapeMixin.landscape_data
attribute. Subsequent calls simply return the cached data. What’s more, many of
the properties of the landscape can be determined using almost the exact same
algorithm, so whenever one is requested, they are all simultaneously computed.
See LandscapeMixin.expound
for a list of such properties.
LandscapeData¶
-
class
neet.
LandscapeData
[source]¶ The LandscapeData class stores the various landscape properties computed in the
LandscapeMixin
. This is used rather an individual properties withinLandscapeMixin
to make it simple for users to extract all of the landscape properties before modifying a network and observing the effects of that change on the landscape.The following properties are stored in LandscapeData:
LandscapeMixin.transitions
Get the state transitions as an array. LandscapeMixin.attractors
Get the attractors of the landscape as an array. LandscapeMixin.attractor_lengths
Get the length of the attractors as an array. LandscapeMixin.basins
Get the basins of the states as an array. LandscapeMixin.basin_sizes
Get the sizes of the attractor basins as an array. LandscapeMixin.basin_entropy
Compute the basin entropy of the landscape [Krawitz2007]. LandscapeMixin.heights
Get the heights of each state in the landscape. LandscapeMixin.recurrence_times
Get the recurrence time of each state in the landscape. LandscapeMixin.in_degrees
Get the in-degree of each state in the landscape. Basic Usage
>>> s_pombe.attractors array([array([76]), array([4]), array([8]), array([12]), array([144, 110, 384]), array([68]), array([72]), array([132]), array([136]), array([140]), array([196]), array([200]), array([204])], dtype=object) >>> default_landscape = s_pombe.landscape_data >>> s_pombe.landscape(pin=[0,1]).attractors array([array([0]), array([1]), array([386, 402, 178, 162]), array([387, 403, 179, 163]), array([4]), array([8]), array([12]), array([76]), array([65]), array([64]), array([68]), array([72]), array([132]), array([136]), array([140]), array([192]), array([193]), array([196]), array([200]), array([204])], dtype=object) >>> default_landscape.attractors array([array([76]), array([4]), array([8]), array([12]), array([144, 110, 384]), array([68]), array([72]), array([132]), array([136]), array([140]), array([196]), array([200]), array([204])], dtype=object) >>> s_pombe.clear_landscape()
LandscapeMixin¶
-
class
neet.
LandscapeMixin
[source]¶ The LandscapeMixin class represents the structure and topology of the “landscape” of state transitions. That is, it is the state space together with information about state transitions and the topology of the state transition graph.
The LandscapeMixin class exposes the following methods:
landscape
Setup the landscape. clear_landscape
Clear the landscape’s data and graph from memory. landscape_data
Get the LandscapeData
object.transitions
Get the state transitions as an array. attractors
Get the attractors of the landscape as an array. attractor_lengths
Get the length of the attractors as an array. basins
Get the basins of the states as an array. basin_sizes
Get the sizes of the attractor basins as an array. basin_entropy
Compute the basin entropy of the landscape [Krawitz2007]. heights
Get the heights of each state in the landscape. recurrence_times
Get the recurrence time of each state in the landscape. in_degrees
Get the in-degree of each state in the landscape. trajectory
Compute the trajectory from a given state. timeseries
Compute a time series from all states. landscape_graph
Construct a networkx.DiGraph
of the state transitions.draw_landscape_graph
Draw the state transition graph. expound
Compute all cached data. -
landscape
(index=None, pin=None, values=None)[source]¶ Setup the landscape.
Prepares the landscape for computation of the various properties, specifying which nodes will be updated (
index
), pinned (pin
) or set to a particular state (values
). In particular, it computes the state transitions of the network and prepares private variables for a subsequent call toexpound()
,landscape_graph()
, etc…This function is implicitly called with no arguments by the various landscape accessors if it has not already been called. This is intended as a convenience since most of the time the user would do this anyway.
This function implicitly calls
clear_landscape
, so make sure to create a reference tolandscape_data
if landscape information has previously been compute and you wish to keep it around.Basic Usage
>>> s_pombe.landscape_data.transitions >>> s_pombe.landscape() <neet.boolean.wtnetwork.WTNetwork object at 0x...> >>> len(s_pombe.landscape_data.transitions) 512
Pinning States
# Prevents all states from transitioning >>> s_pombe.landscape(pin = range(s_pombe.size)) <neet.boolean.wtnetwork.WTNetwork object at 0x...> >>> np.array_equal(s_pombe.landscape_data.transitions, range(s_pombe.volume)) True >>> s_pombe.clear_landscape()
Overriding Node States
# Forces all states to transition to 0 >>> s_pombe.landscape(values={i: 0 for i in range(s_pombe.size)}) <neet.boolean.wtnetwork.WTNetwork object at 0x...> >>> np.all(s_pombe.landscape_data.transitions == 0) True >>> s_pombe.clear_landscape()
Parameters: - index – the index to update (or None)
- pin – the indices to pin during update (or None)
- values – a dictionary of index-value pairs to set after update
Returns: self
-
landscape_data
¶ Get the
LandscapeData
object.The
LandscapeData
object contains any cached attractor landscape information generated by a call toexpound()
.
-
transitions
¶ Get the state transitions as an array. Each element of the array is the next (encoded) state of the system starting from the initial state equal to the index. For example, if
>>> net.transitions array([ 0, 3, 1, 2 ])
then state
0
will transition to0
,1
to3
, etc… Be aware that iflandscape()
has not been called, this method will call it.Basic Usage
>>> s_pombe.transitions array([ 2, 2, 130, 130, 4, 0, 128, 128, 8, 0, 128, 128, 12, 0, 128, 128, 256, 256, 384, 384, 260, 256, 384, 384, 264, 256, ... 208, 208, 336, 336, 464, 464, 340, 336, 464, 464, 344, 336, 464, 464, 348, 336, 464, 464])
Pinned States
A preceding call to
landscape()
can, for example, pin specific nodes to their current state, thus affecting the state transitions.>>> s_pombe.landscape(pin = [0]).transitions array([ 2, 3, 130, 131, 4, 1, 128, 129, 8, 1, 128, 129, 12, 1, 128, 129, 256, 257, 384, 385, 260, 257, 384, 385, 264, 257, ... 208, 209, 336, 337, 464, 465, 340, 337, 464, 465, 344, 337, 464, 465, 348, 337, 464, 465]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of state transitions
-
attractors
¶ Get the attractors of the landscape as an array. Each element of the array is an attractor cycle, each of which is an array of states in the cycle. If
landscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.attractors array([array([76]), array([4]), array([8]), array([12]), array([144, 110, 384]), array([68]), array([72]), array([132]), array([136]), array([140]), array([196]), array([200]), array([204])], dtype=object)
Update Only a Single Node
A preceding call to
landscape()
can, for example, specify which nodes will be updated in the process of computing the attractors. For example, we can allow only the first node of the state to be updated.>>> s_pombe.landscape(index=0).attractors array([[ 0], [ 2], [ 4], ... [506], [508], [510]]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of attractor cycles, each of which is an array of encoded states
-
attractor_lengths
¶ Get the length of the attractors as an array. The array is indexed by the basin number. The order of the attractor lengths is the same as in
attractors
. For example,>>> net.attractors array([ array([0,1]), array([1]) ] >>> net.attractor_lengths array([2, 1])
If
landscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.attractor_lengths array([1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1])
Pinned States
A preceding call to
landscape()
can pin specific nodes to their current state, thus affecting the attractor lengths.>>> s_pombe.landscape(pin = [0]).attractor_lengths array([1, 6, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of the lengths of the attractors
-
basins
¶ Get the basins of the states as an array. Each index of the array is an encoded state and the corresponding value is the attractor basin in which it resides. The attractor basins are integers which can be used to index the
attractors
array, providing the attractor cycle for the base. For example, if>>> net.basins array([ 0, 1, 2, 1 ]) >>> net.attractors array([ array([0]), array([1]), array([2]) ])
then the states
1
and3
are both in the attractor basin which attracts to the fixed-point1
. Iflandscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.basins array([ 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 4, 4, ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Resetting Node States
A preceding call to
landscape()
can, for example, specify that specific nodes are reset to a particular value after the updating the. For example, we can force the first and second nodes to0
, thus affecting the basins.>>> s_pombe.landscape(values={0: 0, 1: 0}).basins array([ 0, 0, 1, 1, 2, 0, 1, 1, 3, 0, 1, 1, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of each state’s attractor basin
-
basin_sizes
¶ Get the sizes of the attractor basins as an array. The array is indexed by the basin number. The order of the basin sizes is the same as in
attractors
. For example, if>>> net.attractors array([ array([0,1]), array([3,6]) ] >>> net.basin_sizes array([ 5, 3 ])
then the attractor
[0, 1]
has a basin size of \(5\) with the remaining states in the other attractor’s basin. Iflandscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.basin_sizes array([378, 2, 2, 2, 104, 6, 6, 2, 2, 2, 2, 2, 2])
Pinning States
A preceding call to
landscape()
can specify that some of the nodes are not updated, say the first two.>>> s_pombe.landscape(pin=[0,1]).basin_sizes array([ 1, 4, 128, 128, 1, 1, 1, 114, 120, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of each attractor’s basin size
-
basin_entropy
¶ Compute the basin entropy of the landscape [Krawitz2007]. That is the Shannon entropy (in bits) of the distribution of basin sizes. For example,
>>> net.basin_sizes array([6, 2]) >>> net.basin_entropy 0.8112781244591328
which is \(-\frac{6}{8}\log_2{\frac{6}{8}) - \frac{2}{8}\log_2{\frac{2}{8})\). If
landscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.basin_entropy 1.2218888...
Pinning States
A preceding call to
landscape()
can specify that some of the nodes are not updated, say the first two.>>> s_pombe.landscape(pin=[0,1]).basin_entropy 2.328561849437885 >>> s_pombe.clear_landscape()
Returns: basin entropy in bits
-
heights
¶ Get the heights of each state in the landscape. That is the fewest number of time steps from that state to a state in it’s attractor cycle, as an array. Each index of the array is an encoded state, and the corresponding value is the height. For example, if
>>> net.heights array([ 3, 0, 1, ... ])
then it will take \(3\) time steps for the state
0
to reach an attractor state while state1
is an attractor state`. Iflandscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.heights array([7, 7, 6, 6, 0, 8, 6, 6, 0, 8, 6, 6, 0, 8, 6, 6, 8, 8, 1, 1, 2, 8, 1, 1, 2, 8, 1, 1, 2, 8, 1, 1, 2, 2, 2, 2, 9, 9, 1, 1, 9, 9, 1, 1, ... 3, 9, 9, 9, 3, 9, 9, 9, 3, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3])
Resetting Node States
A preceding call to
landscape()
can specify that specific nodes are reset to a particular value after the updating the. For example, we can force the first and second nodes to0
, thus affecting the basins.>>> s_pombe.landscape(values={0: 0, 1: 0}).heights array([0, 1, 6, 6, 0, 1, 6, 6, 0, 1, 6, 6, 0, 1, 6, 6, 2, 2, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 3, 3, 6, 6, 3, 3, 6, 6, 3, 3, 6, 6, ... 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
, each value of which is the height of the indexing state
-
recurrence_times
¶ Get the recurrence time of each state in the landscape. That is the number of time steps from that state after which some state is repeated, as an array. Each index of the array is an encoded state, and the corresponding value is the recurrence time of that state. For example, if
>>> net.recurrent_times array([ 3, 10, 0, ... ])
then a state will be seen at least twice if the
0
state is updated more than \(3\) times. The2
state is a fixed-point attractor state as updating even once will repeat a state. Iflandscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.recurrence_times array([7, 7, 6, 6, 0, 8, 6, 6, 0, 8, 6, 6, 0, 8, 6, 6, 8, 8, 3, 3, 2, 8, 3, 3, 2, 8, 3, 3, 2, 8, 3, 3, 4, 4, 4, 4, 9, 9, 3, 3, 9, 9, 3, 3, ... 3, 9, 9, 9, 3, 9, 9, 9, 3, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3])
Resetting Node States
A preceding call to
landscape()
can specify that specific nodes are reset to a particular value after the updating the. For example, we can force the first and second nodes to0
, thus affecting the basins.>>> s_pombe.landscape(pin=[0,1]).recurrence_times array([0, 0, 5, 5, 0, 1, 5, 5, 0, 1, 5, 5, 0, 1, 5, 5, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 3, 3, 5, 5, 3, 3, 5, 5, 3, 3, 5, 5, ... 3, 3, 5, 5, 3, 3, 5, 5, 3, 3, 5, 5, 3, 3, 8, 8, 3, 3, 8, 8, 3, 3, 8, 8, 3, 3, 8, 8]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of recurrence times, one for each state
-
in_degrees
¶ Get the in-degree of each state in the landscape. That is the number of states which transition to that state in a single time step, as a array. Each index of the array is an encoded state, and the corresponding value is the number of preceding states. For example, if
>>> net.in_degrees array([ 5, 2, 0, 0, ... ]
then \(5\) states transition to the
0
state in a single time step, while states2
and3
are in the Garden of Eden. Iflandscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.in_degrees array([ 6, 0, 4, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Pinning States
A preceding call to
landscape()
can specify that some of the nodes are not updated, say nodes7
and8
.>>> s_pombe.landscape(pin=[7,8]).in_degrees array([36, 0, 6, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 42, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) >>> s_pombe.clear_landscape()
Returns: a numpy.ndarray
of the in-degree of each state
-
trajectory
(init, timesteps=None, encode=None)[source]¶ Compute the trajectory from a given state.
This method computes a trajectory from
init
to the last before the trajectory begins to repeat. Iftimesteps
is provided, then the trajectory will have a length oftimesteps + 1
regardless of repeated states. Theencode
argument forces the states in the trajectory to be either encoded or not. Whenencode is None
, whether or not the states of the trajectory are encoded is determined by whether or not the initial state (init
) is provided in encoded form.Note that when
timesteps is None
, the length of the resulting trajectory should be one greater than the recurrence time of the state.If
landscape()
has not been called, this method will implicitly call it. Otherwise, it respects any settings provided by such a call.Basic Usage
>>> s_pombe.trajectory([1,0,0,1,0,1,1,0,1]) [[1, 0, 0, 1, 0, 1, 1, 0, 1], ... [0, 0, 1, 1, 0, 0, 1, 0, 0]] >>> s_pombe.trajectory([1,0,0,1,0,1,1,0,1], encode=True) [361, 80, 320, 78, 128, 162, 178, 400, 332, 76] >>> s_pombe.trajectory(361) [361, 80, 320, 78, 128, 162, 178, 400, 332, 76] >>> s_pombe.trajectory(361, encode=False) [[1, 0, 0, 1, 0, 1, 1, 0, 1], ... [0, 0, 1, 1, 0, 0, 1, 0, 0]] >>> s_pombe.trajectory(361, timesteps=5) [361, 80, 320, 78, 128, 162] >>> s_pombe.trajectory(361, timesteps=10) [361, 80, 320, 78, 128, 162, 178, 400, 332, 76, 76]
Parameters: Returns: a list whose elements are subsequent states of the trajectory
Raises: - ValueError – if
init
an empty array - ValueError – if
timesteps
is less than \(1\)
- ValueError – if
-
timeseries
(timesteps)[source]¶ Compute a time series from all states.
This method computes a 3-dimensional array elements are the states of each node in the network. The dimensions of the array are indexed by, in order, the node, the initial state and the time step.
If
landscape()
has not been called, this method will implicitly call it. Otherwise, it respects any settings provided by such a call.Basic Usage
>>> s_pombe.timeseries(5) array([[[0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], ..., [1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0]], [[0, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 0], [1, 1, 1, 1, 0, 0], ..., [0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0]], ... [[0, 0, 1, 1, 1, 1], [0, 0, 1, 1, 1, 1], [0, 1, 1, 1, 1, 0], ..., [1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0]], [[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1], ..., [1, 1, 1, 0, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 0, 0, 0]]])
Parameters: timesteps (int) – the number of timesteps to evolve the system Returns: a 3-D array of node states Raises: ValueError – if timesteps
is less than \(1\)
-
landscape_graph
(**kwargs)[source]¶ Construct a
networkx.DiGraph
of the state transitions.If
landscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.landscape_graph() <networkx.classes.digraph.DiGraph object at 0x...>
Parameters: kwargs – kwargs to pass to networkx.DiGraph
Returns: a networkx.DiGraph
representing the state transition graph of the landscape
-
draw_landscape_graph
(graphkwargs={}, pygraphkwargs={})[source]¶ Draw the state transition graph.
This method requires the optional dependency pygraphviz, which can be installed via
pip
. Be aware thatpygraphviz
requires native binaries of Graphviz which cannot be installed via pip.If
landscape()
has not been called, this method will implicitly call it.Basic Usage
>>> s_pombe.draw_landscape_graph()
Parameters: - graphkwargs – kwargs to pass to landscape_graph
- pygraphkwargs – kwargs to pass to view_pygraphviz
-
expound
()[source]¶ Compute all cached data.
This function performs the bulk of the calculations that the LandscapeMixin is concerned with. Most of the properties in this class are computed by this function whenever any one of them is requested and the results are cached. The advantage of this is that it saves computation time; why traverse the state space for every property call when you can do it all at once? The downside is that the cached results may use a good bit more memory. This is a trade-off that we are willing to make for now.
The properties that are computed by this function include:
attractors
Get the attractors of the landscape as an array. attractor_lengths
Get the length of the attractors as an array. basins
Get the basins of the states as an array. basin_sizes
Get the sizes of the attractor basins as an array. basin_entropy
Compute the basin entropy of the landscape [Krawitz2007]. heights
Get the heights of each state in the landscape. recurrence_times
Get the recurrence time of each state in the landscape. in_degrees
Get the in-degree of each state in the landscape.
-