# State Spaces¶

The neet module provides the following classes from which all Neet network classes inherit:

 StateSpace StateSpace represents a (potentially in-homogeneous) discrete state space. UniformSpace A StateSpace with the same number of states in each dimension.

This endows networks with methods for iterating over the states of the network, determining if a state exists in the network, and the ability to encode and decode states as integer values. In other words, these classes provide an interface for accessing the unstructured set of states of the network, with no dynamical information.

## StateSpace¶

class neet.StateSpace(shape)[source]

StateSpace represents a (potentially in-homogeneous) discrete state space. It implements iteration, inclusion testing and methods for encoding and decoding states as integers sutable for array indexing:

 size Get the size of the state space. shape Get the shape of the state space. volume Get the volume of the state space. __iter__ Iterate over the states of the state space. __contains__ Determine if a state is in the state space. _unsafe_encode Unsafely encode a state as an integer value. encode Encode a state as an integer. decode Decode an integer-encoded state into a coordinate list.

StateSpace instances are created from a shape array of integer representing the number of discrete states for each dimension of the state space.

Examples

>>> StateSpace([2])      # 1-D state space
<neet.statespace.StateSpace object at 0x...>
>>> StateSpace([2,2])    # 2-D uniform state space
<neet.statespace.StateSpace object at 0x...>
>>> StateSpace([2,3,5])  # 3-D inhomogeneous space
<neet.statespace.StateSpace object at 0x...>


From the network perspective, each dimension of the state space corresponds to a node of the network. The number of discrete states of that node is the base of the corresponding dimension.

The algorithms implemented by this class are intended to be as generic as possible. This comes at the cost of performance in some cases. This can be dealt with by deriving and overloading the appropriate methods, in particular _unsafe_encode(). In fact, the following methods are recommended for overloading:

The encode() method uses __contains__() and _unsafe_encode() internally and rarely needs to be overloaded.

Parameters: shape (list) – the base of each dimension of the state space UniformSpace
size

Get the size of the state space. That is the number of dimensions.

Examples

>>> StateSpace([2]).size
1
>>> StateSpace([2,3,4]).size
3

Returns: the number of dimensions of the state space
shape

Get the shape of the state space. That is the base of each dimension.

Examples

>>> StateSpace([2]).shape
[2]
>>> StateSpace([2,3,4]).shape
[2, 3, 4]

Returns: the shape of the state space
volume

Get the volume of the state space. That is the number of states in the space.

Examples

>>> StateSpace([2]).volume
2
>>> StateSpace([2,3,4]).volume
24

Returns: the number of states in the space
__iter__()[source]

Iterate over the states of the state space.

Examples

>>> list(StateSpace([2]))
[[0], [1]]
>>> list(StateSpace([2,2]))
[[0, 0], [1, 0], [0, 1], [1, 1]]
>>> list(StateSpace([3,2]))
[[0, 0], [1, 0], [2, 0], [0, 1], [1, 1], [2, 1]]

__contains__(states)[source]

Determine if a state is in the state space.

Examples

>>> space = StateSpace([2])
>>> [0] in space
True
>>> 0 in space
False

>>> space = StateSpace([3,2])
>>> [2,0] in space
True
>>> [0,2] in space
False
>>> [2,0,0] in space
False

_unsafe_encode(state)[source]

Unsafely encode a state as an integer value.

Examples

>>> space = StateSpace([2,3])
>>> space._unsafe_encode([1,1])
3


The resulting numeric encodings must be consistent with the ordering of the states produced by __iter__(). This allows necessary for memory-efficient implementations of many algorithms.

>>> space = StateSpace([2,3])
>>> list(space)
[[0, 0], [1, 0], [0, 1], [1, 1], [0, 2], [1, 2]]
>>> list(map(space._unsafe_encode, space))
[0, 1, 2, 3, 4, 5]


Note

This method is not safe. It does not ensure that state is in fact in the space; if that’s not the case then there are not guaruntees on the output. As such it should only be used in situations where the state is already known to be in the space, e.g. it is a state that was generated by __iter__(). This is designed to allow algorithms to utilize state encoding without incurring the cost of consistency checking.

Parameters: state (int) – the state as a list of coordinates the state encoded as an integer encode(), decode()
encode(state)[source]

Encode a state as an integer.

Examples

>>> space = StateSpace([2,3])
>>> space.encode([1,1])
3


The resulting numeric encodings are consistent with the ordering of the states produced by __iter__().

>>> space = StateSpace([2,3])
>>> list(space)
[[0, 0], [1, 0], [0, 1], [1, 1], [0, 2], [1, 2]]
>>> list(map(space.encode, space))
[0, 1, 2, 3, 4, 5]


This method is the inverse of the decode() method:

>>> space = StateSpace([3,2])
>>> space.decode(space.encode([1,1]))
[1, 1]
>>> space.encode(space.decode(3))
3

Parameters: state (int) – the state as a list of coordinates the state encoded as an integer encode(), decode()
decode(encoded)[source]

Decode an integer-encoded state into a coordinate list.

Examples

>>> space = StateSpace([2,3])
>>> space.decode(3)
[1, 1]


The resulting decoded states are consistent with the ordering of the states produced by __iter__().

>>> space = StateSpace([2,3])
>>> list(space)
[[0, 0], [1, 0], [0, 1], [1, 1], [0, 2], [1, 2]]
>>> list(map(space.decode, range(0,6)))
[[0, 0], [1, 0], [0, 1], [1, 1], [0, 2], [1, 2]]


This method is the inverse of the encode() method:

>>> space = StateSpace([3,2])
>>> space.decode(space.encode([1,1]))
[1, 1]
>>> space.encode(space.decode(3))
3

Parameters: encoded (int) – an integer-encoded state the coordinate list of the decoded state encode(), decode()

## UniformSpace¶

class neet.UniformSpace(size, base)[source]

A StateSpace with the same number of states in each dimension. This allows for more efficient implementations of several methods.

UniformSpace instances are created from their size and base; the number of dimensions and the number of states in each dimension, respectively.

In addition to the methods and attributes exposed by StateSpace, the UniformSpace also provides:

 base Get the base of the dimensions.

Examples

>>> UniformSpace(1, 2) # 1-D unform space with base-2 dimensions
<neet.statespace.UniformSpace object at 0x...>
>>> UniformSpace(2, 2) # 2-D uniform space with base-2 dimensions
<neet.statespace.UniformSpace object at 0x...>
>>> UniformSpace(2, 4) # 2-D uniform space with base-4 dimension
<neet.statespace.UniformSpace object at 0x...>

Parameters: size (int) – the number of dimensions in the space base (int) – the number of states in each dimension StateSpace
base

Get the base of the dimensions.

Examples

>>> UniformSpace(2, 3).base
3

Returns: the base of the space’s dimensions