Skip to content

Elements

Elements of systems: entities that carry states, and groups of identical elements.

BaseElement(label, visual=None)

Bases: BasePart[BaseSpace, SimpleNamespace]

Base of every element, a part of a system that holds states.

A subclass takes its states and parameters as arguments of its own __init__, annotated with Annotated and the spec StateSpec or ParameterSpec, and stores each under its own name, as in scikit-learn. A subclass drawn in its own way gives visual a default in its signature. It returns its laws from _get_laws, which every subclass implements, returning an empty list when the element has none.

Parameters:

Name Type Description Default
label str

The label of the element, unique among the parts of its system.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None

Attributes:

Name Type Description
default_visual_

The visual of the element when it sets none.

laws_ Sequence[BasePart]

The laws the element contributes for the namespace of its last run.

Examples:

>>> from typing import Annotated
>>> from skcomplex.core.components.elements._base import BaseElement
>>> from skcomplex.core.specs import ParameterSpec, StateSpec
>>> from skcomplex.core.specs import VisualSpec
>>> class PopulationElement(BaseElement):
...     def __init__(
...         self,
...         label,
...         n: Annotated[float, StateSpec()] = 1.0,
...         r: Annotated[float, ParameterSpec()] = 0.5,
...         visual=VisualSpec('line'),
...     ):
...         super().__init__(label, visual=visual)
...         self.n = n
...         self.r = r
...
...     def _get_laws(self, namespace):
...         return []
>>> PopulationElement('rabbits', n=40).get_params(deep=False)
{'label': 'rabbits', 'n': 40, 'r': 0.5, 'visual': VisualSpec(kind='line', options={})}
Source code in src/skcomplex/core/components/elements/_base.py
70
71
72
def __init__(self, label: str, visual: VisualSpec | None = None) -> None:
    super().__init__(label)
    self.visual = visual

get_states()

Return the states the element carries with their specs, those of its class and those it declares from data.

Returns:

Name Type Description
states dict[str, StateSpec]

A mapping from the name of every state to its spec.

Examples:

>>> from typing import Annotated
>>> from skcomplex.core.components.elements import Element
>>> from skcomplex.core.specs import StateSpec
>>> class TankElement(Element):
...     def __init__(self, label, level: Annotated[float, StateSpec()] = 1.0):
...         super().__init__(label)
...         self.level = level
>>> list(TankElement('tank').get_states())
['level']
Source code in src/skcomplex/core/components/elements/_base.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def get_states(self) -> dict[str, StateSpec]:
    """Return the states the element carries with their specs, those of its class and those it declares from data.

    Returns:
        states:
            A mapping from the name of every state to its spec.

    Examples:
        >>> from typing import Annotated
        >>> from skcomplex.core.components.elements import Element
        >>> from skcomplex.core.specs import StateSpec
        >>> class TankElement(Element):
        ...     def __init__(self, label, level: Annotated[float, StateSpec()] = 1.0):
        ...         super().__init__(label)
        ...         self.level = level
        >>> list(TankElement('tank').get_states())
        ['level']
    """
    return {name: spec for name, spec in self._get_part_specs().items() if isinstance(spec, StateSpec)}

CompartmentElement(label, visual=None, *, n=0.0)

Bases: Element

Compartment, the amount of units in one named state, as a count or a fraction.

The label of the element names the compartment, such as 'A', 'B', or 'source'. A compartment has no laws of its own, and reactions and flows between compartments move its units.

Parameters:

Name Type Description Default
label str

The label of the compartment, unique among the parts of its system.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None
n Annotated[float, StateSpec(domain=closed_open(0, oo))]

The initial amount, a nonnegative count or fraction.

0.0

Attributes:

Name Type Description
default_visual_

The visual of the element when it sets none.

Examples:

>>> from skcomplex.core.components.elements import CompartmentElement
>>> from skcomplex.core.components.system import System
>>> from skcomplex.core.engine.runtime import Simulation
>>> system = System(elements=[CompartmentElement('A', n=990), CompartmentElement('B', n=10)])
>>> Simulation(system, dt=1.0).prepare().run(until=2).trajectory_.values('A.n').tolist()
[990.0, 990.0, 990.0]
Source code in src/skcomplex/core/components/elements/_compartment.py
44
45
46
47
48
49
50
51
52
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    n: Annotated[float, StateSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
) -> None:
    super().__init__(label, visual=visual)
    self.n = n

DeclaredElement(label, visual=None, *, variables=None)

Bases: Element

Element whose states and parameters are data, for a system that knows them only when it builds the element.

The compiler treats a declared variable as it treats an annotated argument of the constructor: the spec gives the declaration and the value gives the default. A law reads a declared variable from its namespace, and get_value reads its value from the element. A subclass that derives its variables from other arguments overrides _declare_variables, and variables then holds the variables that replace the derived ones. The mappings the constructor takes are read as immutable, so set_params changes a variable.

Parameters:

Name Type Description Default
label str

The label of the element, unique among the parts of its system.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None
variables Mapping[str, DeclaredVariableSpec] | None

The declared states and parameters by name, or None for none.

None

Attributes:

Name Type Description
default_visual_

The visual of the element when it sets none.

Raises:

Type Description
ValidationError

A name is not an identifier or is an argument of the constructor, raised by prepare.

Examples:

>>> from skcomplex.core.components.elements import DeclaredElement
>>> from skcomplex.core.specs import DeclaredVariableSpec, ParameterSpec, StateSpec
>>> variables = {'x': DeclaredVariableSpec(1.0, StateSpec()), 'r': DeclaredVariableSpec(0.5, ParameterSpec())}
>>> element = DeclaredElement('cell', variables=variables)
>>> element.get_value('x'), element.set_params(r=0.25).get_value('r')
(1.0, 0.25)
Source code in src/skcomplex/core/components/elements/_declared.py
52
53
54
55
56
57
58
59
60
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    variables: Mapping[str, DeclaredVariableSpec] | None = None,
) -> None:
    super().__init__(label, visual=visual)
    self.variables = variables

get_value(name)

Return the value of a declared state or parameter.

Parameters:

Name Type Description Default
name str

The name of the variable.

required

Returns:

Name Type Description
value object

The value.

Examples:

>>> from skcomplex.core.components.elements import DeclaredElement
>>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
>>> DeclaredElement('cell', variables={'x': DeclaredVariableSpec(1.0, StateSpec())}).get_value('x')
1.0
Source code in src/skcomplex/core/components/elements/_declared.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def get_value(self, name: str) -> object:
    """Return the value of a declared state or parameter.

    Args:
        name:
            The name of the variable.

    Returns:
        value:
            The value.

    Examples:
        >>> from skcomplex.core.components.elements import DeclaredElement
        >>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
        >>> DeclaredElement('cell', variables={'x': DeclaredVariableSpec(1.0, StateSpec())}).get_value('x')
        1.0
    """
    return self._get_declared()[name].value

set_params(**params)

Set arguments of the constructor and values of declared variables, which keep their specs.

Parameters:

Name Type Description Default
**params object

The new values by name.

{}

Returns:

Name Type Description
element Self

The element.

Examples:

>>> from skcomplex.core.components.elements import DeclaredElement
>>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
>>> element = DeclaredElement('cell', variables={'x': DeclaredVariableSpec(1.0, StateSpec())})
>>> element.set_params(label='other', x=2.0).get_value('x')
2.0
Source code in src/skcomplex/core/components/elements/_declared.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def set_params(self, **params: object) -> Self:
    """Set arguments of the constructor and values of declared variables, which keep their specs.

    Args:
        **params:
            The new values by name.

    Returns:
        element:
            The element.

    Examples:
        >>> from skcomplex.core.components.elements import DeclaredElement
        >>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
        >>> element = DeclaredElement('cell', variables={'x': DeclaredVariableSpec(1.0, StateSpec())})
        >>> element.set_params(label='other', x=2.0).get_value('x')
        2.0
    """
    arguments = self.get_params(deep=False)
    super().set_params(**{name: value for name, value in params.items() if name in arguments})
    declared = self._get_declared()
    rest = {name: value for name, value in params.items() if name not in arguments}
    changed = {name: replace(declared[name], value=value) for name, value in rest.items() if name in declared}
    if changed:
        super().set_params(variables={**(self.variables or {}), **changed})
    return super().set_params(**{name: value for name, value in rest.items() if name not in declared})

DensityElement(label, visual=None, *, f=0.0)

Bases: Element

Value of a density at one class, a member of a distribution over the classes.

A distribution is a group of densities on the sites of a lattice of classes, one member per class, and encounter, proliferation, and destruction laws change it. A density has no laws of its own.

Parameters:

Name Type Description Default
label str

The label of the density, unique among the parts of its system.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None
f Annotated[float, StateSpec(domain=closed_open(0, oo))]

The initial density, a nonnegative number.

0.0

Attributes:

Name Type Description
default_visual_

The visual of the element when it sets none.

Examples:

>>> from skcomplex.core.components.elements import DensityElement, GroupElement
>>> from skcomplex.core.components.spaces import LatticeSpace
>>> classes = LatticeSpace(5, boundary='fixed')
>>> group = GroupElement('distribution', element=DensityElement, space=classes, on='sites', values={'f': 0.2})
>>> group.prepare().size_
5
Source code in src/skcomplex/core/components/elements/_density.py
44
45
46
47
48
49
50
51
52
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    f: Annotated[float, StateSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
) -> None:
    super().__init__(label, visual=visual)
    self.f = f

Element(label, visual=None)

Bases: BaseElement

Base class of entities that carry state, such as particles, populations, agents, or firms.

A subclass takes its states, its parameters, and visual as arguments of its own __init__, annotating each state with a StateSpec and each parameter with a ParameterSpec inside Annotated, and returns its intrinsic dynamics from _get_laws, which returns no laws by default. A subclass drawn in its own way gives visual a default in its signature.

An element whose laws have the agent trait, such as rules, alone or in a group, is an agent: under discrete time it runs on the agent stepper, whose rules receive every member as an agent with its states as attributes. Its states then hold any value, not only numbers. A member is removed only when its states tagged with a quantity are settled to zero, and its states and parameters cannot take the names of the agent view, such as location or alive, or of the attributes Mesa reads, such as position or system.

A subclass that connects to other elements declares its ports in the class variable ports, a mapping from the name of a port to its ConnectorSpec, and takes one algebraic state per variable of a port, named <port>_<variable>. A flow is positive into the element.

Parameters:

Name Type Description Default
label str

The label of the element, unique among the parts of its system.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None

Attributes:

Name Type Description
default_visual_

The visual of the element when it sets none.

Examples:

>>> from typing import Annotated
>>> from skcomplex.core.components.elements import Element
>>> from skcomplex.core.specs import StateSpec
>>> from skcomplex.core.specs import VisualSpec
>>> from sage.all__sagemath_symbolics import oo
>>> from sage.sets.real_set import RealSet
>>> class PopulationElement(Element):
...     def __init__(
...         self,
...         label,
...         n: Annotated[float, StateSpec(domain=RealSet.closed_open(0, oo))] = 1.0,
...         visual=VisualSpec('line'),
...     ):
...         super().__init__(label, visual=visual)
...         self.n = n
>>> PopulationElement('rabbits', n=40)
PopulationElement(label='rabbits', n=40)
Source code in src/skcomplex/core/components/elements/_base.py
70
71
72
def __init__(self, label: str, visual: VisualSpec | None = None) -> None:
    super().__init__(label)
    self.visual = visual

FieldElement(label, *, element, space, boundary=None, values=None, visual=None, discretization='finite-difference', symmetry=None)

Bases: LatticeElement

Group of members of one element type at the sites of a lattice, the nodes of a network, or a mesh.

The states of the members are fields, with one value per site, and the laws of the element type are written for one site, with laplacian, gradient, divergence, and advection reading the neighbouring sites. Every state takes a boundary condition at the edges of a lattice: 'periodic', 'zero-flux', or ('fixed', value), where the value can be a function of the node coordinates on a mesh.

The discretization turns the operators into numbers. 'finite-difference' uses stencils on lattices and the graph Laplacian on networks. 'spectral' multiplies Fourier modes on periodic lattices, with the two-thirds rule removing aliasing. 'finite-volume' updates cell averages by the differences of the FluxLaws of the states. 'finite-element' assembles stiffness and mass matrices on a MeshSpace.

Parameters:

Name Type Description Default
label str

The label of the field.

required
element type[BaseElement]

The element type of the members.

required
space LatticeSpace | NetworkSpace | MeshSpace

The lattice, the network, or the mesh.

required
boundary Mapping[str, object] | None

A mapping from state name to its boundary condition, which overrides the edges of the lattice. The value of ('fixed', value) for a tensor state may be a matrix of the symmetry of the state.

None
values Mapping[str, object] | None

Arrays of the lattice shape, or with one value per network node in node order, or shared values.

None
visual VisualSpec | None

How the field is drawn, or None for default_visual_.

None
discretization str

'finite-difference', 'spectral', 'finite-volume', or 'finite-element'.

'finite-difference'
symmetry Mapping[str, Sequence[object]] | None

A mapping from state name to its parity along every axis of a periodic lattice, 'odd', 'even', or None, which the rates keep exactly. A lattice twice as long as a domain along an axis, with states odd or even about its middle, represents walls there, such as the free-slip walls of convection. A vector or a tensor state takes one such sequence for its first component, or one sequence per component.

None

Attributes:

Name Type Description
default_visual_

An image on a lattice, a colored mesh on a mesh, and on a network the visual of a member, or the sites of the network when the member sets none.

size_

The number of sites of the space.

values_

The values with one row per site, or one value shared by every site.

Examples:

>>> from typing import Annotated
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.core.components.elements import Element, FieldElement
>>> from skcomplex.core.components.laws import RateLaw
>>> from skcomplex.core.components.laws.utils import laplacian
>>> from skcomplex.core.components.spaces import LatticeSpace
>>> from skcomplex.core.specs import ParameterSpec, StateSpec
>>> class HeatElement(Element):
...     def __init__(
...         self, label, u: Annotated[float, StateSpec()] = 0.0, D: Annotated[float, ParameterSpec()] = 1.0
...     ):
...         super().__init__(label)
...         self.u = u
...         self.D = D
...
...     def _get_laws(self, namespace):
...         return [RateLaw(namespace.u, namespace.D * laplacian(namespace.u))]
>>> space = LatticeSpace((10, 20))
>>> plate = FieldElement('plate', element=HeatElement, space=space, boundary={'u': 'zero-flux'})
>>> plate.prepare().size_, plate.default_visual_.kind
(200, 'image')
Source code in src/skcomplex/core/components/elements/_field.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def __init__(
    self,
    label: str,
    *,
    element: type[BaseElement],
    space: LatticeSpace | NetworkSpace | MeshSpace,
    boundary: Mapping[str, object] | None = None,
    values: Mapping[str, object] | None = None,
    visual: VisualSpec | None = None,
    discretization: str = 'finite-difference',
    symmetry: Mapping[str, Sequence[object]] | None = None,
) -> None:
    super().__init__(label, element=element, space=space, values=values, visual=visual)
    self.boundary = boundary
    self.discretization = discretization
    self.symmetry = symmetry

GroupElement(label, *, element, size=None, values=None, visual=None, space=None, variable=False, on=None, location=None, layer=None, capacity=None, rank=None)

Bases: BaseElement

Group of identical elements of one type, whose variables are arrays with one row per member.

A value is either an array whose first dimension is the size of the group, or one value shared by every member. Variables without a value take the default of the constructor of the element type, and the laws of the group are the laws of its element type, written for one member.

Parameters:

Name Type Description Default
label str

The label of the group, unique among the children of its system.

required
element type[BaseElement]

The element type of the members.

required
size int | None

The number of members.

None
values Mapping[str, object] | None

A mapping from state or parameter name to its per-member or shared value.

None
visual VisualSpec | None

How the group is drawn, or None for default_visual_.

None
space BaseSpace | None

The space whose sites the members occupy, such as a lattice with one member per site, or None for the space of the enclosing system.

None
variable bool

Whether laws add and remove members during a run, such as the births and deaths of agents.

False
on str | None

The part of the space with one member each, 'sites', 'edges', or 'hyperedges', or None for members that are not tied to parts of the space. With a part and no size, the size is the number of parts.

None
location object

The initial places of agents in the space: cell coordinates, a network node, a position, or a polygon that holds the member at a uniform point inside it, one per member or one shared by every member, or None for random places. Only the agent stepper reads it.

None
layer str | None

The layer of the network whose edges a group on edges lives on, or None for the graph of the network.

None
capacity int | None

The largest number of members of a variable group on the sites or edges of a network, which compiled backends reserve rows for, or None for twice the initial size.

None
rank int | None

The largest number of members of a hyperedge of a variable group on the hyperedges of a network, the rank of its hypergraph, which compiled backends reserve a column per member for, so the group holds hyperedges of every size up to it, or None for one size, that of the initial hyperedges.

None

Attributes:

Name Type Description
default_visual_

The visual of a member, or the plain visual when the member sets none, which the group takes when it sets none.

size_

The number of members: the size, or for a group on parts without one, the number of parts of its space.

values_

The values with one row per member, or one value shared by every member.

Examples:

>>> from typing import Annotated
>>> import networkx as nx
>>> from skcomplex.core.specs import StateSpec
>>> from skcomplex.core.components.elements import Element, GroupElement
>>> from skcomplex.core.components.spaces import NetworkSpace
>>> from skcomplex.core.specs import LayerSpec
>>> from skcomplex.core.specs import VisualSpec
>>> class PopulationElement(Element):
...     def __init__(self, label, n: Annotated[float, StateSpec()] = 1.0, visual=VisualSpec('line')):
...         super().__init__(label, visual=visual)
...         self.n = n
>>> GroupElement('herds', element=PopulationElement, size=3).prepare().size_
3
>>> ring = NetworkSpace(nx.cycle_graph(30))
>>> GroupElement('weights', element=PopulationElement, space=ring, on='edges').prepare().size_
30
>>> space = NetworkSpace(nx.cycle_graph(4), layers=[LayerSpec('work', nx.complete_graph(4))])
>>> wages = GroupElement('wages', element=PopulationElement, space=space, on='edges', layer='work')
>>> wages.prepare().size_
6
>>> herds = GroupElement('herds', element=PopulationElement, size=3).prepare()
>>> herds.default_visual_
VisualSpec(kind='line', options={})
Source code in src/skcomplex/core/components/elements/_group.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def __init__(
    self,
    label: str,
    *,
    element: type[BaseElement],
    size: int | None = None,
    values: Mapping[str, object] | None = None,
    visual: VisualSpec | None = None,
    space: BaseSpace | None = None,
    variable: bool = False,
    on: str | None = None,
    location: object = None,
    layer: str | None = None,
    capacity: int | None = None,
    rank: int | None = None,
) -> None:
    super().__init__(label, visual=visual)
    self.element = element
    self.size = size
    self.values = values
    self.space = space
    self.variable = variable
    self.on = on
    self.location = location
    self.layer = layer
    self.capacity = capacity
    self.rank = rank

get_declaring_part()

Return what declares the variables of a member: its class, or a member when it declares them from data.

Returns:

Name Type Description
part type[BaseElement] | BaseElement

The element class, or a member with the values of the group.

Examples:

>>> from skcomplex.core.components.elements import DeclaredElement, GroupElement
>>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
>>> values = {'variables': {'x': DeclaredVariableSpec(1.0, StateSpec())}}
>>> group = GroupElement('cells', element=DeclaredElement, size=2, values=values)
>>> group.get_declaring_part().get_value('x')
1.0
Source code in src/skcomplex/core/components/elements/_group.py
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
def get_declaring_part(self) -> type[BaseElement] | BaseElement:
    """Return what declares the variables of a member: its class, or a member when it declares them from data.

    Returns:
        part:
            The element class, or a member with the values of the group.

    Examples:
        >>> from skcomplex.core.components.elements import DeclaredElement, GroupElement
        >>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
        >>> values = {'variables': {'x': DeclaredVariableSpec(1.0, StateSpec())}}
        >>> group = GroupElement('cells', element=DeclaredElement, size=2, values=values)
        >>> group.get_declaring_part().get_value('x')
        1.0
    """
    return self._get_member() if issubclass(self.element, DeclaredElement) else self.element

get_states()

Return the states of a member of the group with their specs.

Returns:

Name Type Description
states dict[str, StateSpec]

A mapping from the name of every state to its spec.

Examples:

>>> from skcomplex.core.components.elements import DeclaredElement, GroupElement
>>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
>>> values = {'variables': {'x': DeclaredVariableSpec(1.0, StateSpec())}}
>>> list(GroupElement('cells', element=DeclaredElement, size=3, values=values).get_states())
['x']
Source code in src/skcomplex/core/components/elements/_group.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def get_states(self) -> dict[str, StateSpec]:
    """Return the states of a member of the group with their specs.

    Returns:
        states:
            A mapping from the name of every state to its spec.

    Examples:
        >>> from skcomplex.core.components.elements import DeclaredElement, GroupElement
        >>> from skcomplex.core.specs import DeclaredVariableSpec, StateSpec
        >>> values = {'variables': {'x': DeclaredVariableSpec(1.0, StateSpec())}}
        >>> list(GroupElement('cells', element=DeclaredElement, size=3, values=values).get_states())
        ['x']
    """
    return {name: spec for name, spec in self._get_member_specs().items() if isinstance(spec, StateSpec)}

LatticeElement(label, *, element, space, values=None, visual=None)

Bases: GroupElement

Group of elements with one member per site of a lattice or node of a network.

The laws of the element type are written for one cell, and local rules read the cells around it. Preparing turns values in the shape of the lattice, or mappings from node to value on a network, into one row per site.

Parameters:

Name Type Description Default
label str

The label of the group, unique among the parts of its system.

required
element type[BaseElement]

The element type of the cells.

required
space BaseSpace

The lattice or other space of sites, or the network whose nodes are the sites, in the order of graph.nodes.

required
values Mapping[str, object] | None

A mapping from state or parameter name to an array of the lattice shape, an array in node order, a mapping from node to value on a network, or a value shared by every cell.

None
visual VisualSpec | None

How the group is drawn, or None for default_visual_.

None

Attributes:

Name Type Description
default_visual_

The visual of a member, or the default visual of the space when the member sets none, which the group takes when it sets none.

size_

The number of sites of the space.

values_

The values with one row per site, or one value shared by every site.

Examples:

>>> from typing import Annotated
>>> import numpy as np
>>> from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
>>> from skcomplex.core.components.elements import Element, LatticeElement
>>> from skcomplex.core.components.spaces import LatticeSpace
>>> from skcomplex.core.specs import StateSpec
>>> class CellElement(Element):
...     def __init__(self, label, alive: Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))] = 0):
...         super().__init__(label)
...         self.alive = alive
>>> space = LatticeSpace((3, 4))
>>> cells = LatticeElement('cells', element=CellElement, space=space, values={'alive': np.eye(3, 4)})
>>> cells.prepare().size_, cells.values_['alive'].shape
(12, (12,))
Source code in src/skcomplex/core/components/elements/_lattice.py
68
69
70
71
72
73
74
75
76
77
def __init__(
    self,
    label: str,
    *,
    element: type[BaseElement],
    space: BaseSpace,
    values: Mapping[str, object] | None = None,
    visual: VisualSpec | None = None,
) -> None:
    super().__init__(label, element=element, values=values, visual=visual, space=space, on='sites')

PatchElement(label, tiles=None, *, prototiles=(), filled=False, max_size=10000000, bounds=None, visual=None)

Bases: Element

Element that holds tiles, each a prototile under an affine placement, replaced in parallel by substitutions.

A subclass returns the SubstitutionLaws of the patch from _get_laws. Its states are the count of every prototile and the number size of tiles.

Parameters:

Name Type Description Default
label str

The label of the element.

required
tiles Annotated[Sequence[tuple[str, AffineSpec]] | None, StateSpec(domain=None)]

Pairs of a prototile name and its placement at generation 0, or None for the first prototile in place.

None
prototiles Sequence[PrototileSpec]

The prototiles.

()
filled bool

Whether the geometry visual draws polygons as a filled image instead of outlines.

False
max_size int

The largest number of tiles a generation may produce.

10000000
bounds Sequence[float] | None

The box (xmin, ymin, xmax, ymax) the geometry visual shows, or None for the box of the initial tiles.

None
visual VisualSpec | None

How the patch is drawn, or None for default_visual_.

None

Examples:

>>> from skcomplex.core.components.elements import PatchElement
>>> from skcomplex.core.specs import PrototileSpec
>>> PatchElement('cantor', prototiles=[PrototileSpec('interval', [(0, 0), (1, 0)])]).filled
False
Source code in src/skcomplex/core/components/elements/_patch.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def __init__(
    self,
    label: str,
    tiles: Annotated[Sequence[tuple[str, AffineSpec]] | None, StateSpec(domain=None)] = None,
    *,
    prototiles: Sequence[PrototileSpec] = (),
    filled: bool = False,
    max_size: int = 10_000_000,
    bounds: Sequence[float] | None = None,
    visual: VisualSpec | None = None,
) -> None:
    super().__init__(label, visual=visual)
    self.tiles = tiles
    self.prototiles = prototiles
    self.filled = filled
    self.max_size = max_size
    self.bounds = bounds

PointElement(label, x=0.0, x_d1=0.0, visual=None)

Bases: Element

Point of a continuous space, a member with a vector state x of order 2 that locates it.

The laws that act on the point give the second derivative of x, and the companion state x_d1 holds its first derivative. The boundary of the space acts on x.

Parameters:

Name Type Description Default
label str

The label of the point.

required
x Annotated[ArrayLike, StateSpec(vector=True, order=2, role=position)]

The initial value of the vector state. A number applies to every component.

0.0
x_d1 ArrayLike

The initial value of the first derivative of the vector state. A number applies to every component.

0.0
visual VisualSpec | None

How the point is drawn, or None for default_visual_.

None

Attributes:

Name Type Description
default_visual_

Points at the values of x.

Examples:

>>> from skcomplex.core.components.elements import PointElement
>>> from skcomplex.core.components.spaces import ContinuousSpace
>>> from skcomplex.core.components.system import System
>>> from skcomplex.core.engine.runtime import Simulation
>>> system = System(elements=[PointElement('ball', x_d1=[1.0, 0.0])], space=ContinuousSpace(n_dim=2))
>>> Simulation(system, dt=1.0).prepare().run(until=2.0).trajectory_.values('ball.x')[-1].tolist()
[2.0, 0.0]
Source code in src/skcomplex/core/components/elements/_point.py
48
49
50
51
52
53
54
55
56
57
def __init__(
    self,
    label: str,
    x: Annotated[npt.ArrayLike, StateSpec(vector=True, order=2, role='position')] = 0.0,
    x_d1: npt.ArrayLike = 0.0,
    visual: VisualSpec | None = None,
) -> None:
    super().__init__(label, visual=visual)
    self.x = x
    self.x_d1 = x_d1

WordElement(label, axiom='', *, alphabet=None, ignore='', geometry=None, max_size=10000000, bounds=None, visual=None)

Bases: Element

Element that holds a word of modules rewritten in parallel by string productions.

A subclass returns the ProductionLaws of the word from _get_laws. Its states are the count of every symbol whose name is a word of letters, digits, and underscores, and the length size of the word.

Parameters:

Name Type Description Default
label str

The label of the element.

required
axiom Annotated[Letters, StateSpec(domain=None)]

The word at generation 0.

''
alphabet str | Mapping[str, int] | None

The symbols, as a string of one-character symbols or a mapping from name to number of parameters, or None to take them from the axiom and the productions.

None
ignore str | Sequence[str]

The symbols that contexts skip.

''
geometry GeometrySpec | None

The interpretation of the word as line segments, or None.

None
max_size int

The largest word a generation may produce.

10000000
bounds Sequence[float] | None

The box (xmin, ymin, xmax, ymax) the geometry visual shows, or None to fit the data.

None
visual VisualSpec | None

How the word is drawn, or None for default_visual_.

None

Examples:

>>> from skcomplex.core.components.elements import WordElement
>>> from skcomplex.core.components.laws import ProductionLaw
>>> class AlgaeElement(WordElement):
...     def _get_laws(self, namespace):
...         return [ProductionLaw('A', 'AB'), ProductionLaw('B', 'A')]
>>> AlgaeElement('algae', axiom='A').axiom
'A'
Source code in src/skcomplex/core/components/elements/_word.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def __init__(
    self,
    label: str,
    axiom: Annotated[Letters, StateSpec(domain=None)] = '',
    *,
    alphabet: str | Mapping[str, int] | None = None,
    ignore: str | Sequence[str] = '',
    geometry: GeometrySpec | None = None,
    max_size: int = 10_000_000,
    bounds: Sequence[float] | None = None,
    visual: VisualSpec | None = None,
) -> None:
    super().__init__(label, visual=visual)
    self.axiom = axiom
    self.alphabet = alphabet
    self.ignore = ignore
    self.geometry = geometry
    self.max_size = max_size
    self.bounds = bounds