Cellular Automata¶
Cellular automata are a special type of network. They can be envisioned
at a boolean networks wherein every node has exactly 3 incoming edges. The
neet.automata
modules provides two submodules, neet.automata.eca
and neet.automata.reca
. As a convenience, the classes in each are
exposed in the neet.automata
, so you never have to reference the
submodules unless you so choose.
API Documentation¶
Elementary Cellular Automata¶
The neet.automata.eca.ECA
class describes an Elementary Cellular
Automaton
with an arbitrary rule. The ECA
class is not a fixed sized network.
This means that the size is determined when it is used based on arguments
passed to the relevant methods or functions.
Examples
>>> ca = ECA(30)
>>> ca.update([0, 0, 1, 0, 0])
[0, 1, 1, 1, 0]
>>> ca.update([0, 1, 0])
[1, 1, 1]
>>> transitions(ca, size=3)
[[0, 0, 0], [1, 1, 1], [1, 1, 1], [1, 0, 0], [1, 1, 1], [0, 0, 1], [0, 1, 0], [0, 0, 0]]

class
neet.automata.eca.
ECA
(code, boundary=None)[source]¶ ECA is a class to represent elementary cellular automaton rules. Each ECA contains an 8bit integral member variable
code
representing the Wolfram code for the ECA rule and a set of boundary conditions which is eitherNone
, signifying periodic boundary conditions, or a pair of cell states signifying fixed, open boundary conditions.
__init__
(code, boundary=None)[source]¶ Construct an elementary cellular automaton rule.
Examples
>>> ca = ECA(30) >>> ca.code 30 >>> ca.boundary >>> ca = ECA(30, boundary=(0,0)) >>> ca.boundary (0, 0)
Parameters:  code (int) – the Wolfram code for the ECA
 boundary (tuple or None) – the boundary conditions for the CA
Raises:  TypeError – if
code
is not an instance of int  ValueError – if
code
is not in \(\{0,1,\ldots,255\}\)  TypeError – if
boundary
is neitherNone
or an instance of tuple  ValueError – if
boundary
is a neitherNone
or a pair of binary states

code
¶ The Wolfram code of the elementary cellular automaton
Examples
>>> eca = ECA(30) >>> eca.code 30 >>> eca.code = 45 >>> eca.code 45 >>> eca.code = 256 Traceback (most recent call last): ... ValueError: invalid ECA code
Type: int
Raises:  TypeError – if
code
is not an instance of int  ValueError – if
code
is not in \(\{0,1,\ldots,255\}\)
 TypeError – if

boundary
¶ The boundary conditions of the elemenary cellular automaton
Examples
>>> eca = ECA(30) >>> eca.boundary >>> eca.boundary = (0,1) >>> eca.boundary (0, 1) >>> eca.boundary = None >>> eca.boundary >>> eca.boundary = [0,1] Traceback (most recent call last): ... TypeError: ECA boundary are neither None nor a tuple
Type: None
or tupleRaises:  TypeError – if
boundary
is neitherNone
or an instance of tuple  ValueError – if
boundary
is a neitherNone
or a pair of binary states
 TypeError – if

state_space
(n)[source]¶ Return a
neet.statespace.StateSpace
object for a lattice of lengthn
.>>> eca = ECA(30) >>> eca.state_space(3) <neet.statespace.StateSpace object at 0x...> >>> space = eca.state_space(3) >>> list(space) [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]
Parameters: n (int) – the number of nodes in the lattice Returns: neet.statespace.StateSpace
Raises: ValueError – if n < 1

update
(lattice, index=None, pin=None, values=None)[source]¶ Update the state of the
lattice
in place.Basic Use:
>>> ca = ECA(30) >>> xs = [0,0,1,0,0] >>> ca.update(xs) [0, 1, 1, 1, 0] >>> ca.boundary = (1,1) >>> ca.update([0,0,1,0,0]) [1, 1, 1, 1, 1]
SingleNode Update:
>>> ca.boundary = None >>> xs = [0,0,1,0,0] >>> ca.update(xs, index=1) [0, 1, 1, 0, 0] >>> xs [0, 1, 1, 0, 0] >>> ca.boundary = (1,1) >>> ca.update(xs, index=1) [0, 1, 1, 0, 1]
State Pinning:
>>> ca.boundary = None >>> xs = [0,0,1,0,0] >>> ca.update(xs, pin=[2]) [0, 1, 1, 0, 0] >>> ca.boundary = (1,1) >>> ca.update(xs, pin=[4]) [0, 1, 0, 1, 0]
Value Fixing:
>>> ca.boundary = None >>> xs = [0,0,1,0,0] >>> ca.update(xs, values={0:1,2:0}) [1, 1, 1, 0, 0] >>> ca.boundary = (1,1) >>> xs = [1,1,1,0,0] >>> ca.update(xs, values={1:0,1:0}) [0, 0, 0, 1, 0]
Erroneous Usage:
>>> xs = [] >>> ca.update(xs) Traceback (most recent call last): ... ValueError: lattice is empty >>> xs = [0,0,2,0,0] >>> ca.update(xs) Traceback (most recent call last): ... ValueError: invalid value "2" in lattice >>> ca.update(xs, index=5) Traceback (most recent call last): ... ValueError: the provided state is not in the ECA's state space >>> ca.update([0,0,1,0,0,], index=1, pin=[0]) Traceback (most recent call last): ... ValueError: cannot provide both the index and pin arguments >>> ca.update([0,0,1,0,0], index=1, values={0:0}) Traceback (most recent call last): ... ValueError: cannot provide both the index and values arguments >>> ca.update([0,0,1,0,0], pin=[2], values={2:0}) Traceback (most recent call last): ... ValueError: cannot set a value for a pinned state >>> ca.update([0,0,1,0,0], values={2:2}) Traceback (most recent call last): ... ValueError: invalid state in values argument
Parameters:  lattice – the onedimensional sequence of states
 index – the index to update (or None)
 pin – a sequence of indicies to pin (or None)
 values – a dictionary of indexvalue pairs to fix after update
Returns: the updated lattice
Raises:  ValueError – if
lattice
is not in the ECA’s state space  IndexError – if
index is not None and index > len(states)
 ValueError – if
index
andpin
are both provided  ValueError – if
index
andvalues
are both provided  ValueError – if an element of
pin
is a key invalues
 ValueError – if a value in
values
is not binary (0 or 1)

neighbors_in
(index, size, **kwargs)[source]¶ Return the set of all incoming neighbor nodes.
In the cases of the lattices having fixed boundary conditions, the left boundary, being on the left of the leftmost index 0, has an index of 1, while the right boundary’s index is the size+1. The full state of the lattices and the boundaries is equavolent to: [cell0, cell1, …, cellN, right_boundary, left_boundary] if it is ever presented as a single list in Python.
Parameters:  index – node index
 size – size of ECA
Returns: the set of all node indices which point toward the index node
Raises: ValueError – if index < 0 or index > n  1
Basic Use:
>>> net = ECA(30) >>> net.neighbors_in(1, size=3) {0, 1, 2} >>> net.neighbors_in(2, size=3) {0, 1, 2} >>> net.boundary = (1,1) >>> net.neighbors_in(2, size=3) {1, 2, 3} >>> net.neighbors_in(0, 3) {0, 1, 1}
Erroneous Usage:
>>> net = ECA(30,boundary=(1, 1)) >>> net.neighbors_in(5, 3) Traceback (most recent call last): ... ValueError: index must be a nonnegative integer less than size

neighbors_out
(index, size)[source]¶ Return the set of all outgoing neighbor nodes.
Fixed boundaries are excluded as they are not affected by internal states.
Parameters:  index – node index
 size – size of ECA
Returns: the set of all node indices which point from the index node
Raises: ValueError – if index < 0 or index > n  1
Basic Use:
>>> net = ECA(30) >>> net.neighbors_out(1, 3) {0, 1, 2} >>> net.neighbors_out(2, 3) {0, 1, 2} >>> net.boundary = (1, 1) >>> net.neighbors_out(2, 3) {1, 2} >>> net.neighbors_out(0, 3) {0, 1}
Erroneous Usage:
>>> net = ECA(30,boundary=(1, 1)) >>> net.neighbors_out(5, 3) Traceback (most recent call last): ... ValueError: index must be a nonnegative integer less than size

neighbors
(index, size)[source]¶ Return a set of neighbors for a specified node.
In the cases of the lattices having fixed boundary conditions, the left boundary, being on the left of the leftmost index 0, has an index of 1, while the right boundary’s index is the size+1. The full state of the lattices and the boundaries is equavolent to: [cell0, cell1, …, cellN, right_boundary, left_boundary] if it is ever presented as a single list in Python.
Parameters:  index – node index
 size – size of ECA
Returns: the set of all node indices adjacent to the index node
Raises: ValueError – if index < 0 or index > n  1
Basic Use:
>>> net = ECA(30) >>> net.neighbors(1, size=3) {0, 1, 2} >>> net.neighbors(2, size=3) {0, 1, 2} >>> net.boundary = (1,1) >>> net.neighbors(2, size=3) {1, 2, 3} >>> net.neighbors(0, 3) {0, 1, 1}
Erroneous Usage:
>>> net = ECA(30,boundary=(1, 1)) >>> net.neighbors(5, 3) Traceback (most recent call last): ... ValueError: index must be a nonnegative integer less than size

to_networkx_graph
(size)[source]¶ Return networkx graph given neet network. Requires networkx.
Parameters: size – size of ECA, required if network is an ECA Returns: a networkx.DiGraph

draw
(size, filename=None)[source]¶ Output a file with a simple network drawing.
Requires networkx and pygraphviz.
Supported image formats are determined by graphviz. In particular, pdf support requires ‘cairo’ and ‘pango’ to be installed prior to graphviz installation.
Parameters:  filename – filename to write drawing to. Temporary filename will be used if no filename provided.
 size – size of ECA, required if network is an ECA
Returns: a
pygraphviz
network drawing

Rewired Elementary Cellular Automata¶
The neet.automata.reca.RewiredECA
implements a variant of an ECA
wherein the neighbors of a give cell can be specified by the user. This
allows one to study, for example, the role of topology in the dynamics of a
network. Every ECA
can be represented as a RewiredECA
with standard
wiring, but all RewiredECA
are fixed sized networks.
Examples
>>> ca = RewiredECA(30, size=3)
>>> ca.update([0, 1, 0])
[1, 1, 1]
>>> ca = RewiredECA(30, wiring=[[0,1,3], [1,1,1], [2,1,2]])
>>> ca.update([0, 1, 0])
[1, 0, 1]

class
neet.automata.reca.
RewiredECA
(code, boundary=None, size=None, wiring=None)[source]¶ RewiredECA is a class to represent elementary cellular automata rules with arbitrarily defined topology. Since the topology must be provided, RewiredECA are naturally fixedsized.

__init__
(code, boundary=None, size=None, wiring=None)[source]¶ Construct a rewired elementary cellular automaton rule.
Examples
>>> reca = RewiredECA(30, size=3) >>> reca.code 30 >>> reca.size 3 >>> reca.wiring array([[1, 0, 1], [ 0, 1, 2], [ 1, 2, 3]])
>>> reca = RewiredECA(30, wiring=[[0,1,2],[1,0,0],[2,3,1]]) >>> reca.code 30 >>> reca.size 3 >>> reca.wiring array([[ 0, 1, 2], [1, 0, 0], [ 2, 3, 1]])
Parameters:  code (int) – the 8bit Wolfram code for the rule
 boundary (tuple or None) – the boundary conditions for the CA
 size (int or None) – the number of cells in the lattice
 wiring – a wiring matrix
Raises:  ValueError – if
size is None and wiring is None
 ValueError – if
size is not None and wiring is not None
 TypeError – if
size is not None and not isinstance(size, int)
 ValueError – if
size is not None and size <= 0
 TypeError – if
not isinstance(wiring, list) and not isinstance(wiring, numpy.ndarray)
 ValueError – if
wiring
is not \(3 imes N\)  ValueError – if
any(wiring < 1) or any(wiring > N)

code
¶ The Wolfram code of the elementary cellular automaton
Examples
>>> eca = ECA(30) >>> eca.code 30 >>> eca.code = 45 >>> eca.code 45 >>> eca.code = 256 Traceback (most recent call last): ... ValueError: invalid ECA code
Type: int
Raises:  TypeError – if
code
is not an instance of int  ValueError – if
code
is not in \(\{0,1,\ldots,255\}\)
 TypeError – if

boundary
¶ The boundary conditions of the elemenary cellular automaton
Examples
>>> eca = ECA(30) >>> eca.boundary >>> eca.boundary = (0,1) >>> eca.boundary (0, 1) >>> eca.boundary = None >>> eca.boundary >>> eca.boundary = [0,1] Traceback (most recent call last): ... TypeError: ECA boundary are neither None nor a tuple
Type: None
or tupleRaises:  TypeError – if
boundary
is neitherNone
or an instance of tuple  ValueError – if
boundary
is a neitherNone
or a pair of binary states
 TypeError – if

size
¶ The number of cells in the CA lattice.
Examples
>>> eca = RewiredECA(30, size=3) >>> eca.size 3 >>> eca = RewiredECA(30, wiring=[[1,0], [0,1], [1,0]]) >>> eca.size 2
Type: int

wiring
¶ The wiring matrix for the rule.
Examples
>>> reca = RewiredECA(30, size=3) >>> reca.wiring array([[1, 0, 1], [ 0, 1, 2], [ 1, 2, 3]]) >>> eca = RewiredECA(30, wiring=[[0,1],[1,1],[1,1]]) >>> eca.wiring array([[ 0, 1], [ 1, 1], [1, 1]])
Type: numpy.ndarray

state_space
()[source]¶ Return a
neet.statespace.StateSpace
object for the cellular automaton lattice.Examples
>>> eca = RewiredECA(30, size=3) >>> eca.state_space() <neet.statespace.StateSpace object at 0x...> >>> space = eca.state_space() >>> list(space) [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]
Returns: neet.statespace.StateSpace

update
(lattice, index=None, pin=None, values=None)[source]¶ Update the state of the
lattice
in place.Examples
>>> reca = RewiredECA(30, size=5) >>> reca.update([1,0,0,0,0]) [1, 1, 0, 0, 1] >>> reca.wiring[:,:] = [[1, 2, 1, 2, 1], [0, 1, 2, 3, 4], [0, 2, 3, 4, 5]] >>> reca.update([0,0,1,0,0]) [0, 0, 1, 1, 0] >>> reca.update([1,1,1,1,1]) [0, 0, 0, 0, 0] >>> reca.update([1,1,1,1,1], index=2) [1, 1, 0, 1, 1] >>> reca.update([1,1,1,1,1], pin=[1, 3]) [0, 1, 0, 1, 0] >>> reca.update([1,1,1,1,1], values={0: 1, 1: 1}) [1, 0, 0, 0, 1]
Parameters:  lattice – the onedimensional sequence of states
 index – the index to update (optional)
 pin – a sequence of indices to fix (optional)
 values – a dict of index/value pairs to set (optional)
Returns: the updated lattice

neighbors_in
(index, size, **kwargs)¶ Return the set of all incoming neighbor nodes.
In the cases of the lattices having fixed boundary conditions, the left boundary, being on the left of the leftmost index 0, has an index of 1, while the right boundary’s index is the size+1. The full state of the lattices and the boundaries is equavolent to: [cell0, cell1, …, cellN, right_boundary, left_boundary] if it is ever presented as a single list in Python.
Parameters:  index – node index
 size – size of ECA
Returns: the set of all node indices which point toward the index node
Raises: ValueError – if index < 0 or index > n  1
Basic Use:
>>> net = ECA(30) >>> net.neighbors_in(1, size=3) {0, 1, 2} >>> net.neighbors_in(2, size=3) {0, 1, 2} >>> net.boundary = (1,1) >>> net.neighbors_in(2, size=3) {1, 2, 3} >>> net.neighbors_in(0, 3) {0, 1, 1}
Erroneous Usage:
>>> net = ECA(30,boundary=(1, 1)) >>> net.neighbors_in(5, 3) Traceback (most recent call last): ... ValueError: index must be a nonnegative integer less than size

neighbors_out
(index, size)¶ Return the set of all outgoing neighbor nodes.
Fixed boundaries are excluded as they are not affected by internal states.
Parameters:  index – node index
 size – size of ECA
Returns: the set of all node indices which point from the index node
Raises: ValueError – if index < 0 or index > n  1
Basic Use:
>>> net = ECA(30) >>> net.neighbors_out(1, 3) {0, 1, 2} >>> net.neighbors_out(2, 3) {0, 1, 2} >>> net.boundary = (1, 1) >>> net.neighbors_out(2, 3) {1, 2} >>> net.neighbors_out(0, 3) {0, 1}
Erroneous Usage:
>>> net = ECA(30,boundary=(1, 1)) >>> net.neighbors_out(5, 3) Traceback (most recent call last): ... ValueError: index must be a nonnegative integer less than size

neighbors
(index, size)¶ Return a set of neighbors for a specified node.
In the cases of the lattices having fixed boundary conditions, the left boundary, being on the left of the leftmost index 0, has an index of 1, while the right boundary’s index is the size+1. The full state of the lattices and the boundaries is equavolent to: [cell0, cell1, …, cellN, right_boundary, left_boundary] if it is ever presented as a single list in Python.
Parameters:  index – node index
 size – size of ECA
Returns: the set of all node indices adjacent to the index node
Raises: ValueError – if index < 0 or index > n  1
Basic Use:
>>> net = ECA(30) >>> net.neighbors(1, size=3) {0, 1, 2} >>> net.neighbors(2, size=3) {0, 1, 2} >>> net.boundary = (1,1) >>> net.neighbors(2, size=3) {1, 2, 3} >>> net.neighbors(0, 3) {0, 1, 1}
Erroneous Usage:
>>> net = ECA(30,boundary=(1, 1)) >>> net.neighbors(5, 3) Traceback (most recent call last): ... ValueError: index must be a nonnegative integer less than size

to_networkx_graph
(size)¶ Return networkx graph given neet network. Requires networkx.
Parameters: size – size of ECA, required if network is an ECA Returns: a networkx.DiGraph

draw
(size, filename=None)¶ Output a file with a simple network drawing.
Requires networkx and pygraphviz.
Supported image formats are determined by graphviz. In particular, pdf support requires ‘cairo’ and ‘pango’ to be installed prior to graphviz installation.
Parameters:  filename – filename to write drawing to. Temporary filename will be used if no filename provided.
 size – size of ECA, required if network is an ECA
Returns: a
pygraphviz
network drawing
