Skip to content

Spaces

Define the spaces that systems live in, the neighbourhoods of their members, and the time of a system.

AdjacencyNeighborhood(*, center=False, layer=None, label='neighborhood')

Bases: BaseNeighborhood

Nodes along the edges of a node of a network, in node order, after the node itself when it is included.

Rules receive the values of the neighbours padded to the largest degree of the graph. On a directed graph the neighbours are the successors.

Parameters:

Name Type Description Default
center bool

Whether the node itself comes first.

False
layer str | None

The label of the layer whose edges join the neighbours, or None for the graph of the network.

None
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import AdjacencyNeighborhood
>>> AdjacencyNeighborhood(layer='work').layer
'work'
Source code in src/skcomplex/core/spaces/_adjacency.py
31
32
33
34
def __init__(self, *, center: bool = False, layer: str | None = None, label: str = 'neighborhood') -> None:
    super().__init__(label)
    self.center = center
    self.layer = layer

BaseNeighborhood(label)

Bases: BasePart[None, SimpleNamespace]

Base of the neighbourhoods, the parts of a system that give the members a law reads around a member of a space.

A neighbourhood is a part: it stores its arguments in its own __init__, check validates them, and prepare derives what the engine reads, such as the offsets of a lattice neighbourhood. The space that reads it rejects a neighbourhood of another kind. It contributes no laws.

Parameters:

Name Type Description Default
label str

The label of the neighbourhood.

required
Source code in src/skcomplex/core/base.py
60
61
62
63
64
65
66
67
def __init__(self, label: str) -> None:
    """Store the label of the part.

    Args:
        label:
            The label of the part, unique among the parts of its system.
    """
    self.label = label

BaseSpace(label)

Bases: BasePart[None, SimpleNamespace]

Base of the spaces, the parts of a system where members live and which give vector states their dimension.

A space is a part of its system: it stores its arguments in its own __init__, check validates them, prepare derives the facts of the space, and _get_laws returns the laws the space contributes, none by default. A space with sites answers the hooks the engine reads: _get_neighbors gives the sites around a site, _index_table the neighbour of every site in every slot of a neighbourhood, _ball the neighbourhood within a radius, _neighbor_pairs the pairs of neighbouring sites, and _default_neighborhood the neighbourhood _get_neighbors reads when it is given none. A space without sites, such as a continuous one, answers none of them.

Parameters:

Name Type Description Default
label str

The label of the space in its system.

required

Attributes:

Name Type Description
size_

The number of sites, or None for a space without sites.

n_dim_

The number of dimensions, the length of the vector states of members of the space.

shape_

The shape of the arrays of the values of the sites, () for a space without sites.

positions_

The position of every site, one row per site, or an empty array of n_dim_ columns without sites.

periodic_

Whether opposite sides of the space join.

default_visual_

The name of the visual of groups on the space when neither the group nor its element sets one, or None.

Source code in src/skcomplex/core/base.py
60
61
62
63
64
65
66
67
def __init__(self, label: str) -> None:
    """Store the label of the part.

    Args:
        label:
            The label of the part, unique among the parts of its system.
    """
    self.label = label

BaseTime(label)

Bases: BasePart[None, SimpleNamespace]

Base of the time of a system, the part that decides the laws the system may hold.

A time is a part of its system: it stores its arguments in its own __init__, check validates them, prepare sets its schedule, and _get_frames returns the times of the frames of a run up to a time. It contributes no laws.

Parameters:

Name Type Description Default
label str

The label of the time in its system.

required

Attributes:

Name Type Description
schedule_

The schedule of a discrete time, or None.

Source code in src/skcomplex/core/base.py
60
61
62
63
64
65
66
67
def __init__(self, label: str) -> None:
    """Store the label of the part.

    Args:
        label:
            The label of the part, unique among the parts of its system.
    """
    self.label = label

BoxNeighborhood(radius=1, *, n_dim=1, label='neighborhood')

Bases: LatticeNeighborhood

Every site within a radius along every dimension, the site itself in place, as one-dimensional automata read.

For radius 1 in one dimension the order is left, centre, right, the order of Wolfram's rule numbers.

Parameters:

Name Type Description Default
radius int

The largest offset along any dimension.

1
n_dim int

The number of dimensions.

1
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import BoxNeighborhood
>>> BoxNeighborhood().check().prepare().offsets_
((-1,), (0,), (1,))
Source code in src/skcomplex/core/spaces/_box.py
34
35
36
37
def __init__(self, radius: int = 1, *, n_dim: int = 1, label: str = 'neighborhood') -> None:
    BaseNeighborhood.__init__(self, label)
    self.radius = radius
    self.n_dim = n_dim

CayleySpace(group, *, ball=None, fill=0.0, max_sites=MAX_SITES, label='space')

Bases: BaseSpace

Cayley graph of a finitely generated group, on a ball of words or a whole finite group, whose sites hold cells.

The group is a native Sage or GAP group: a Sage PermutationGroup or MatrixGroup, or a GAP group from libgap, such as the free group libgap.FreeGroup(['a', 'b']), a finitely presented group free / relators, an automaton group libgap.AutomatonGroup('t = (1, t)(1, 2)') of the AutomGrp package, or the finite quotient of one, such as libgap.PermGroupOnLevel(group, 3). Finitely presented groups are solved by Knuth-Bendix completion with KBMAG.

Sites are the distinct elements of a ball of a radius in the generators and their inverses, numbered by word length and then by order of discovery, so a ball is a prefix of every larger ball. Without a ball the group must be finite, and the sites are all its elements. A cell at the site g reads the site g s for every element s of a memory set, and a neighbour outside a ball, or reached through a site outside it, reads the value fill.

Parameters:

Name Type Description Default
group object

The group.

required
ball int | None

The radius of the ball, or None for a finite group.

None
fill float

The value read outside a ball.

0.0
max_sites int

The largest number of sites.

MAX_SITES
label str

The label of the space in its system.

'space'

Attributes:

Name Type Description
generators_

The names of the generators, their GAP names when these are identifiers, or a, b, and so on.

words_

The shortest word of every site, in site order.

lengths_

The word length of every site, its distance from the identity in the Cayley graph.

ball_sizes_

The number of sites within every radius, from 0 to the radius of the ball or of the finite group.

generator_table_

The site of g s for every site g and letter s, in the order a, a^-1, b, b^-1, ..., and -1 outside.

edges_

The edge from every site g to g s for every generator s inside the space, with the generator's number.

level_

The level of the tree whose action keys the elements of an automaton group, or 0 for other groups.

Examples:

>>> from sage.all__sagemath_gap import PermutationGroup
>>> from skcomplex.core.spaces import CayleySpace
>>> space = CayleySpace(PermutationGroup([[(1, 2)], [(1, 2, 3)]]), ball=3).check().prepare()
>>> space.size_, space.words_[:4], space.ball_sizes_
(6, ['1', 'a', 'b', 'b^-1'], [1, 4, 6, 6])
Source code in src/skcomplex/core/spaces/_cayley.py
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def __init__(
    self,
    group: object,
    *,
    ball: int | None = None,
    fill: float = 0.0,
    max_sites: int = MAX_SITES,
    label: str = 'space',
) -> None:
    super().__init__(label)
    self.group = group
    self.ball = ball
    self.fill = fill
    self.max_sites = max_sites

ConeNeighborhood(radius, angle, *, direction=None, center=False, label='neighborhood')

Bases: BaseNeighborhood

Members of a continuous space within a distance of a member and inside a cone around its direction.

A neighbour is within the radius of a member and its direction from the member makes an angle of at most angle with the member's direction, so angle = pi is the whole disk and angle = pi / 2 the half ahead. The direction is a vector state of the members, or in two dimensions a scalar state that holds the direction angle.

Parameters:

Name Type Description Default
radius float

The largest distance of a neighbour.

required
angle float

The half-angle of the cone, between 0 and pi.

required
direction str | None

The name of the state that holds the direction, or None for the velocity, the vector state declared as the rate of the position.

None
center bool

Whether a member is its own neighbour.

False
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> import math
>>> from skcomplex.core.spaces import ConeNeighborhood
>>> ConeNeighborhood(1.0, math.pi / 2, direction='theta').check().direction
'theta'
Source code in src/skcomplex/core/spaces/_cone.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def __init__(
    self,
    radius: float,
    angle: float,
    *,
    direction: str | None = None,
    center: bool = False,
    label: str = 'neighborhood',
) -> None:
    super().__init__(label)
    self.radius = radius
    self.angle = angle
    self.direction = direction
    self.center = center

ContinuousSpace(extent=(), *, n_dim=None, boundary='open', label='space')

Bases: BaseSpace

Continuous space of real positions, a box with a boundary or the whole of R^d.

A box has an extent along every dimension, from 0 to the extent. Its boundary acts on every position state of the members on it: 'open' leaves positions alone, 'periodic' joins opposite sides and measures pair distances by the minimum image, and 'reflecting' mirrors positions back into the box and reverses the velocity across the wall. Without an extent the space is unbounded and has n_dim dimensions. The positions are states of the members, so the space has no sites, and a site has no neighbours in it.

Parameters:

Name Type Description Default
extent Sequence[float]

The side of the box along every dimension, or empty for an unbounded space.

()
n_dim int | None

The number of dimensions of an unbounded space, or None for the number of sides of the box.

None
boundary str

'open', 'periodic', or 'reflecting'.

'open'
label str

The label of the space in its system.

'space'

Attributes:

Name Type Description
extent_

The side of the box along every dimension, or () for an unbounded space.

Examples:

>>> from skcomplex.core.spaces import ContinuousSpace
>>> ContinuousSpace(extent=(10.0, 5.0), boundary='periodic').check().prepare().extent_
(10.0, 5.0)
>>> ContinuousSpace(n_dim=3).check().prepare().n_dim_
3
Source code in src/skcomplex/core/spaces/_continuous.py
51
52
53
54
55
56
57
58
59
60
61
62
def __init__(
    self,
    extent: Sequence[float] = (),
    *,
    n_dim: int | None = None,
    boundary: str = 'open',
    label: str = 'space',
) -> None:
    super().__init__(label)
    self.extent = extent
    self.n_dim = n_dim
    self.boundary = boundary

ContinuousTime(*, label='time')

Bases: BaseTime

Continuous time, in which rates, noise, implicit equations, jumps, and crossings change the states.

Parameters:

Name Type Description Default
label str

The label of the time in its system.

'time'

Examples:

>>> from skcomplex.core.spaces import ContinuousTime
>>> ContinuousTime().check().prepare().schedule_ is None
True
Source code in src/skcomplex/core/spaces/_continuous_time.py
22
23
def __init__(self, *, label: str = 'time') -> None:
    super().__init__(label)

DiscreteTime(schedule='synchronous', *, label='time')

Bases: BaseTime

Discrete time, in which updates, rules, local rules, rewrites, and samples change the states every step.

Parameters:

Name Type Description Default
schedule str | ScheduleSpec

'synchronous', every update reads the states of the start of the step, 'random-sequential', members update one after another in a new random order, or a ScheduleSpec that a formalism defines, such as the phases of agents.

'synchronous'
label str

The label of the time in its system.

'time'

Examples:

>>> from skcomplex.core.spaces import DiscreteTime
>>> DiscreteTime(schedule='random-sequential').check().prepare().schedule_
'random-sequential'
Source code in src/skcomplex/core/spaces/_discrete_time.py
34
35
36
def __init__(self, schedule: str | ScheduleSpec = 'synchronous', *, label: str = 'time') -> None:
    super().__init__(label)
    self.schedule = schedule

GeneratorNeighborhood(generators, *, center=True, inverses=True, label='neighborhood')

Bases: MemoryNeighborhood

Memory set of the generators of a group, after the identity and with their inverses when asked.

Parameters:

Name Type Description Default
generators tuple[str, ...]

The names of the generators of the group.

required
center bool

Whether the identity comes first.

True
inverses bool

Whether every generator is followed by its inverse.

True
label str

The label of the neighbourhood.

'neighborhood'

Attributes:

Name Type Description
elements_

The words of the memory set.

Examples:

>>> from skcomplex.core.spaces import GeneratorNeighborhood
>>> GeneratorNeighborhood(['a', 'b']).check().prepare().elements_
('1', 'a', 'a^-1', 'b', 'b^-1')
Source code in src/skcomplex/core/spaces/_generator.py
35
36
37
38
39
40
41
42
43
44
45
46
def __init__(
    self,
    generators: tuple[str, ...],
    *,
    center: bool = True,
    inverses: bool = True,
    label: str = 'neighborhood',
) -> None:
    super().__init__((), label=label)
    self.generators = generators
    self.center = center
    self.inverses = inverses

LatticeNeighborhood(offsets, *, label='neighborhood')

Bases: BaseNeighborhood

Ordered offsets of the sites a local rule reads, with the site itself as the zero offset when included.

Parameters:

Name Type Description Default
offsets tuple[IntTuple, ...]

The offsets, one tuple of integers per neighbour, in the order rules receive their values.

required
label str

The label of the neighbourhood.

'neighborhood'

Attributes:

Name Type Description
offsets_

The offsets as tuples of integers.

Examples:

>>> from skcomplex.core.spaces import LatticeNeighborhood
>>> LatticeNeighborhood([(0, 1), (1, 0)]).check().prepare().offsets_
((0, 1), (1, 0))
Source code in src/skcomplex/core/spaces/_lattice_neighborhood.py
34
35
36
def __init__(self, offsets: tuple[IntTuple, ...], *, label: str = 'neighborhood') -> None:
    super().__init__(label)
    self.offsets = offsets

LatticeSpace(shape, *, geometry='square', boundary='periodic', fill=0.0, spacing=1.0, neighborhood='moore', capacity=None, label='space')

Bases: BaseSpace

Box of the integer lattice Z^d, or of the triangular lattice in 2D, whose sites hold lattice group members.

Sites are numbered in row-major order, so site (i, j) of a lattice of shape (n, m) is member i * m + j. A triangular site (i, j) keeps its integer coordinates on a skewed grid and sits at (j + i / 2, i sqrt(3) / 2) in the plane, so it has six neighbours at unit distance.

Parameters:

Name Type Description Default
shape Sequence[int] | int

The number of sites along every dimension.

required
geometry str

'square' for the integer lattice or 'triangular' for the triangular lattice in two dimensions.

'square'
boundary str

'periodic' to join opposite edges, 'fixed' to read the value fill outside the box, or 'reflecting' to read the mirror image of the box outside it.

'periodic'
fill float

The value read outside a lattice with fixed edges.

0.0
spacing float | Sequence[float]

The distance between neighbouring sites, or one distance per dimension.

1.0
neighborhood str

The neighbourhood agents on a two-dimensional square lattice query, 'moore' for the 8 surrounding cells or 'von_neumann' for the 4 adjacent ones.

'moore'
capacity int | None

The largest number of agents in a cell, or None for no limit.

None
label str

The label of the space in its system.

'space'

Attributes:

Name Type Description
spacings_

The distance between neighbouring sites along every dimension.

Examples:

>>> from skcomplex.core.spaces import LatticeSpace
>>> space = LatticeSpace((10, 20)).check().prepare()
>>> space.size_, space.n_dim_, space.shape_
(200, 2, (10, 20))
>>> LatticeSpace((2, 2), geometry='triangular').check().prepare().positions_.round(3).tolist()
[[0.0, 0.0], [1.0, 0.0], [0.5, 0.866], [1.5, 0.866]]
Source code in src/skcomplex/core/spaces/_lattice.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def __init__(
    self,
    shape: Sequence[int] | int,
    *,
    geometry: str = 'square',
    boundary: str = 'periodic',
    fill: float = 0.0,
    spacing: float | Sequence[float] = 1.0,
    neighborhood: str = 'moore',
    capacity: int | None = None,
    label: str = 'space',
) -> None:
    super().__init__(label)
    self.shape = shape
    self.geometry = geometry
    self.boundary = boundary
    self.fill = fill
    self.spacing = spacing
    self.neighborhood = neighborhood
    self.capacity = capacity

MemoryNeighborhood(elements, *, label='neighborhood')

Bases: BaseNeighborhood

Ordered memory set of a cellular automaton on a group space: the group elements whose values a rule reads.

A cell at the element g reads the cell at g s for every element s of the memory set, in its order, so the neighbourhood keeps its orientation. Elements are words in the generators, such as 'a', 'a^-1', or 'a*b', and '1' is the identity, the cell itself.

Parameters:

Name Type Description Default
elements Sequence[str]

The words of the memory set.

required
label str

The label of the neighbourhood.

'neighborhood'

Attributes:

Name Type Description
elements_

The words of the memory set as strings.

Examples:

>>> from skcomplex.core.spaces import MemoryNeighborhood
>>> MemoryNeighborhood(['1', 'a', 'a^-1']).check().prepare().elements_
('1', 'a', 'a^-1')
Source code in src/skcomplex/core/spaces/_memory.py
35
36
37
def __init__(self, elements: Sequence[str], *, label: str = 'neighborhood') -> None:
    super().__init__(label)
    self.elements = elements

MeshSpace(points, cells, *, label='space')

Bases: BaseSpace

Unstructured mesh of triangles or tetrahedra, whose nodes hold the members of finite element fields.

Build the nodes and cells with scikit-fem, such as skfem.MeshTri.init_lshaped().refined(3), and pass its p and t arrays.

Parameters:

Name Type Description Default
points ArrayLike

The coordinates of the nodes, one column per node and one row per dimension.

required
cells ArrayLike

The node indices of every triangle or tetrahedron, one column per cell.

required
label str

The label of the space in its system.

'space'

Attributes:

Name Type Description
mesh_

The scikit-fem mesh of the nodes and cells, a MeshTri in 2D or a MeshTet in 3D.

boundary_nodes_

The indices of the nodes on the boundary of the mesh.

Examples:

>>> import numpy as np
>>> import skfem
>>> from skcomplex.core.spaces import MeshSpace
>>> grid = skfem.MeshTri.init_tensor(np.linspace(0, 1, 5), np.linspace(0, 1, 4))
>>> mesh = MeshSpace(grid.p, grid.t).check().prepare()
>>> mesh.size_, mesh.n_dim_, mesh.positions_.shape
(20, 2, (20, 2))
Source code in src/skcomplex/core/spaces/_mesh.py
49
50
51
52
def __init__(self, points: npt.ArrayLike, cells: npt.ArrayLike, *, label: str = 'space') -> None:
    super().__init__(label)
    self.points = points
    self.cells = cells

MooreNeighborhood(radius=1, *, n_dim=2, center=False, label='neighborhood')

Bases: LatticeNeighborhood

Sites within a radius along every dimension, the 8 surrounding cells in two dimensions for radius 1.

The offsets come in lexicographic order, after the site itself when it is included.

Parameters:

Name Type Description Default
radius int

The largest offset along any dimension.

1
n_dim int

The number of dimensions.

2
center bool

Whether the site itself comes first.

False
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import MooreNeighborhood
>>> len(MooreNeighborhood().check().prepare().offsets_)
8
>>> len(MooreNeighborhood(center=True).check().prepare().offsets_)
9
Source code in src/skcomplex/core/spaces/_moore.py
39
40
41
42
43
def __init__(self, radius: int = 1, *, n_dim: int = 2, center: bool = False, label: str = 'neighborhood') -> None:
    BaseNeighborhood.__init__(self, label)
    self.radius = radius
    self.n_dim = n_dim
    self.center = center

NearestNeighborhood(k, *, center=False, label='neighborhood')

Bases: BaseNeighborhood

The k members of a continuous space closest to a member, the topological neighbourhood.

Distances are measured between the position states of the members, by the minimum image in a periodic box. A group of at most k other members gives every member all the others.

Parameters:

Name Type Description Default
k int

The number of neighbours.

required
center bool

Whether a member is its own neighbour, besides its k nearest others.

False
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import NearestNeighborhood
>>> NearestNeighborhood(7).check().k
7
Source code in src/skcomplex/core/spaces/_nearest.py
32
33
34
35
def __init__(self, k: int, *, center: bool = False, label: str = 'neighborhood') -> None:
    super().__init__(label)
    self.k = k
    self.center = center

NetworkSpace(graph, *, layers=(), capacity=None, fill=0.0, hyperedges=(), label='space')

Bases: BaseSpace

Network whose nodes agents occupy or lattice sites sit on, with the neighbours of a node given by its edges.

Lattice groups on a network hold one member per node, in the order of graph.nodes. The graph is the default layer, and layers adds named relations over the same nodes. Edges of a layer are numbered in the order of graph.edges, and every layer lowers to arrays: the source and target node index of every edge, and the adjacency of every node in compressed sparse row form. On an undirected graph the source of an edge is the end that comes first in node order. Build the graph with NetworkX, such as nx.erdos_renyi_graph(100, 0.1, seed=0).

Parameters:

Name Type Description Default
graph Graph

The NetworkX graph, the default layer.

required
layers Sequence[LayerSpec]

The named layers over the nodes of the graph.

()
capacity int | None

The largest number of agents on a node, or None for no limit.

None
fill float

The value lattice rules read in the padding slots of nodes with fewer neighbours than the largest degree.

0.0
hyperedges Sequence[Sequence[object]] | Hypergraph

The hyperedges of the network, which hyperedge interactions and groups on hyperedges read: sequences of at least two nodes, an XGI Hypergraph, or an XGI SimplicialComplex, whose faces of at least two nodes are its hyperedges. The members of an XGI hyperedge follow the order of the nodes of the graph.

()
label str

The label of the space in its system.

'space'

Attributes:

Name Type Description
graphs_

The graph of every layer by label, None first for the graph of the network.

edges_

The source and target node index of every edge of every layer by label, in the order of graph.edges.

adjacency_

The neighbours of every node of every layer by label in compressed sparse row form: the start of the neighbours of every node with the number of entries last, the sorted neighbours of every node in turn, the successors on a directed graph, and the edge that joins every node to every neighbour.

hyperedges_

The node index of every member of every hyperedge, in the order of the hyperedges.

incidence_

The sparse incidence matrix of the hyperedges, with one row per node and one column per hyperedge.

memberships_

The indices of the hyperedges every node belongs to, in increasing order.

Examples:

>>> import networkx as nx
>>> from skcomplex.core.spaces import NetworkSpace
>>> from skcomplex.specs import LayerSpec
>>> NetworkSpace(nx.cycle_graph(5)).check().prepare().size_
5
>>> space = NetworkSpace(nx.path_graph(3), layers=[LayerSpec('work', nx.complete_graph(3))])
>>> space = space.check().prepare()
>>> list(space.graphs_), space.graphs_['work'].number_of_edges()
([None, 'work'], 3)
>>> [item.tolist() for item in space.edges_[None]]
[[0, 1], [1, 2]]
>>> [item.tolist() for item in space.adjacency_[None]]
[[0, 1, 3, 4], [1, 0, 2, 1], [0, 0, 1, 1]]
>>> import itertools
>>> import xgi
>>> triangles = xgi.Hypergraph([list(nodes) for nodes in itertools.combinations(range(5), 3)])
>>> space = NetworkSpace(nx.complete_graph(5), hyperedges=triangles).check().prepare()
>>> len(space.hyperedges_), space.hyperedges_[0], space.memberships_[0]
(10, (0, 1, 2), (0, 1, 2, 3, 4, 5))
Source code in src/skcomplex/core/spaces/_network.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def __init__(
    self,
    graph: nx.Graph,
    *,
    layers: Sequence[LayerSpec] = (),
    capacity: int | None = None,
    fill: float = 0.0,
    hyperedges: Sequence[Sequence[object]] | xgi.Hypergraph = (),
    label: str = 'space',
) -> None:
    super().__init__(label)
    self.graph = graph
    self.layers = layers
    self.capacity = capacity
    self.fill = fill
    self.hyperedges = hyperedges

PhaseSpace(position, axes, *, limit=DEFAULT_LIMIT, label='space')

Bases: LatticeSpace

Product of a position lattice and class axes, a lattice whose sites are the points of the product.

The position axes come first and sites are in row-major order, so the sites at one position are contiguous. A class axis has its own cells, of width (high - low) / size, and its own edges, without flux for an interval and joined for a periodic axis. The position axes keep the boundary of the position lattice.

Parameters:

Name Type Description Default
position LatticeSpace

The lattice of the positions.

required
axes Sequence[AxisSpec]

The class axes.

required
limit int

The largest number of sites of the space.

DEFAULT_LIMIT
label str

The label of the space in its system.

'space'

Attributes:

Name Type Description
coordinates_

The coordinate of every cell of every class axis, at the cell centres, by the name of the axis.

position_axes_

The indices of the position axes among the axes of the product.

class_axes_

The index of every class axis among the axes of the product, by its name.

position_size_

The number of positions.

axes_periodic_

Whether the edges of every axis of the product are joined.

Raises:

Type Description
PhaseSpaceTooLargeError

The product has more sites than the limit.

Examples:

>>> from skcomplex.core.spaces import LatticeSpace, PhaseSpace
>>> from skcomplex.specs import AxisSpec
>>> space = PhaseSpace(LatticeSpace((64,), spacing=0.2), [AxisSpec('v', 128, -6.0, 6.0)]).check().prepare()
>>> space.size_, space.shape_, space.class_axes_
(8192, (64, 128), {'v': 1})
>>> space.coordinates_['v'][:2].round(4).tolist()
[-5.9531, -5.8594]
Source code in src/skcomplex/core/spaces/_phase.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def __init__(
    self,
    position: LatticeSpace,
    axes: Sequence[AxisSpec],
    *,
    limit: int = DEFAULT_LIMIT,
    label: str = 'space',
) -> None:
    super().__init__(
        position.shape,
        geometry=position.geometry,
        boundary=position.boundary,
        fill=position.fill,
        spacing=position.spacing,
        label=label,
    )
    self.position = position
    self.axes = axes
    self.limit = limit

RadiusNeighborhood(radius, *, center=False, label='neighborhood')

Bases: BaseNeighborhood

Members of a continuous space within a distance of a member, the metric neighbourhood.

Distances are measured between the position states of the members, by the minimum image in a periodic box.

Parameters:

Name Type Description Default
radius float

The largest distance of a neighbour.

required
center bool

Whether a member is its own neighbour.

False
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import RadiusNeighborhood
>>> RadiusNeighborhood(1.5).check().radius
1.5
Source code in src/skcomplex/core/spaces/_radius.py
31
32
33
34
def __init__(self, radius: float, *, center: bool = False, label: str = 'neighborhood') -> None:
    super().__init__(label)
    self.radius = radius
    self.center = center

StaticTime(*, label='time')

Bases: BaseTime

No time: the system holds only constraints and objectives, and a run solves it once.

Parameters:

Name Type Description Default
label str

The label of the time in its system.

'time'

Examples:

>>> from skcomplex.core.spaces import StaticTime
>>> StaticTime().check().prepare().schedule_ is None
True
Source code in src/skcomplex/core/spaces/_static_time.py
25
26
def __init__(self, *, label: str = 'time') -> None:
    super().__init__(label)

TriangularNeighborhood(*, center=False, label='neighborhood')

Bases: LatticeNeighborhood

Six neighbours of a site of a triangular lattice, counterclockwise from the direction of the second axis.

Direction k points at 60 k degrees in the plane, so direction k + 3 modulo 6 is opposite to direction k.

Parameters:

Name Type Description Default
center bool

Whether the site itself comes first.

False
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import TriangularNeighborhood
>>> TriangularNeighborhood().check().prepare().offsets_
((0, 1), (1, 0), (1, -1), (0, -1), (-1, 0), (-1, 1))
Source code in src/skcomplex/core/spaces/_triangular.py
31
32
33
def __init__(self, *, center: bool = False, label: str = 'neighborhood') -> None:
    BaseNeighborhood.__init__(self, label)
    self.center = center

VonNeumannNeighborhood(radius=1, *, n_dim=2, center=False, label='neighborhood')

Bases: LatticeNeighborhood

Sites within a Manhattan distance, the 4 adjacent cells in two dimensions for radius 1.

The offsets come in lexicographic order, after the site itself when it is included.

Parameters:

Name Type Description Default
radius int

The largest Manhattan distance.

1
n_dim int

The number of dimensions.

2
center bool

Whether the site itself comes first.

False
label str

The label of the neighbourhood.

'neighborhood'

Examples:

>>> from skcomplex.core.spaces import VonNeumannNeighborhood
>>> VonNeumannNeighborhood().check().prepare().offsets_
((-1, 0), (0, -1), (0, 1), (1, 0))
Source code in src/skcomplex/core/spaces/_von_neumann.py
37
38
39
40
41
def __init__(self, radius: int = 1, *, n_dim: int = 2, center: bool = False, label: str = 'neighborhood') -> None:
    BaseNeighborhood.__init__(self, label)
    self.radius = radius
    self.n_dim = n_dim
    self.center = center