Skip to content

Networks

Network realizations shared by the biology packages: weighted edges, infected hosts, and Boolean nodes.

BooleanFunctionInteraction(label, *, target, inputs, table=(0,))

Bases: MapInteraction

Synchronous update of a node by a truth table of any number of input nodes.

A table of 2^k entries reads the k inputs as the bits of a binary number, from the most significant, and gives the next value of the target. The update is the sum, over the patterns whose entry is 1, of the product that is 1 exactly on that pattern.

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the updated node.

required
inputs Annotated[list[str], RoleSpec(variadic=True)]

The paths of the input nodes, in the order of the bits of the table.

required
table tuple[int, ...]

The next value of the target for each of the 2^k input patterns.

(0,)

Raises:

Type Description
ValidationError

The table does not have one entry per pattern of the inputs.

Examples:

>>> from skcomplex.systems.biology.systems_biology import BooleanFunctionInteraction
>>> BooleanFunctionInteraction('and', target='c', inputs=['a', 'b'], table=(0, 0, 0, 1)).table
(0, 0, 0, 1)
Source code in src/skcomplex/systems/biology/common/networks/_boolean_function.py
48
49
50
51
52
53
54
55
56
57
58
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    inputs: Annotated[list[str], RoleSpec(variadic=True)],
    table: tuple[int, ...] = (0,),
) -> None:
    super().__init__(label, target=target, state='x', function=self._get_next)
    self.inputs = inputs
    self.table = table

BooleanNodeElement(label, visual=None, *, x=0)

Bases: Element

Node of a Boolean network, a gene or protein that is on or off.

Parameters:

Name Type Description Default
label str

The label of the node.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None
x Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]

The initial value, 0 or 1.

0

Examples:

>>> from skcomplex.systems.biology.systems_biology import BooleanNodeElement
>>> BooleanNodeElement('Sic1', x=1).x
1
Source code in src/skcomplex/systems/biology/common/networks/_boolean_node.py
33
34
35
36
37
38
39
40
41
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    x: Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))] = 0,
) -> None:
    super().__init__(label, visual=visual)
    self.x = x

EdgeDrawInteraction(label, *, target, edges, noise=0.0, low=-1.0, high=1.0, state='w')

Bases: NeighborInteraction

First draw of the weight of every new edge of a network, and a random drift of the weights of the other edges.

Every step of discrete time an edge marked fresh draws its weight uniformly from [low, high] and loses its mark, and every other edge adds noise times a standard normal draw to its weight, or keeps it without noise.

Parameters:

Name Type Description Default
label str

The label of the interaction.

required
target Annotated[str, RoleSpec()]

The path of the group on the nodes of the network.

required
edges Annotated[str, RoleSpec()]

The path of the group on its edges, whose members hold the weight and the mark.

required
noise Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The standard deviation of the drift of a weight in a step, 0 for none.

0.0
low float

The least weight of a new edge.

-1.0
high float

The largest weight of a new edge.

1.0
state str

The name of the state of the edges that holds the weight.

'w'

Examples:

>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.biology.common.networks import EdgeDrawInteraction
>>> edge = SimpleNamespace(w=var('w'), fresh=var('fresh'))
>>> draw = EdgeDrawInteraction('draw', target='species', edges='links').prepare()
>>> [str(law.value) for law in draw.run(SimpleNamespace(edge=edge, noise=var('noise'))).laws_][1]
'0'
Source code in src/skcomplex/systems/biology/common/networks/_edge_draw.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    edges: Annotated[str, RoleSpec()],
    noise: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    low: float = -1.0,
    high: float = 1.0,
    state: str = 'w',
) -> None:
    super().__init__(label)
    self.target = target
    self.edges = edges
    self.noise = noise
    self.low = low
    self.high = high
    self.state = state

HostElement(label, visual=None, *, i=0.0, w=1.0)

Bases: Element

Node of a network that is susceptible at i = 0 or infected at i = 1, in continuous time.

A SpreadingInteraction infects and recovers it, and a TopologyInteraction rewires its edges at its rate w.

Parameters:

Name Type Description Default
label str

The label of the node or of the group of nodes.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

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

Whether the node is infected.

0.0
w Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The rate at which the node, while susceptible, rewires an edge to an infected neighbour.

1.0

Examples:

>>> from skcomplex.systems.biology.epidemiology import HostElement
>>> HostElement('node').w
1.0
Source code in src/skcomplex/systems/biology/common/networks/_host.py
39
40
41
42
43
44
45
46
47
48
49
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    i: Annotated[float, StateSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    w: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 1.0,
) -> None:
    super().__init__(label, visual=visual)
    self.i = i
    self.w = w

SpreadingInteraction(label, *, target, state='state', beta=1.0, gamma=0.0, omega=0.0, inactive=0.0, active=1.0, removed=None, form='number', layer=None)

Bases: TransitionInteraction

Spreading of the active value of a discrete state along the edges of a network or the bonds of a lattice.

An inactive member becomes active at the rate beta times the number of its active neighbours, or times their fraction of its neighbours. An active member recovers at the rate gamma, to the inactive value, or to the removed value when there is one, and a removed member returns to the inactive value at the rate omega. Every move is a transition at a rate, so the state changes by random events in continuous time.

Parameters:

Name Type Description Default
label str

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

required
target Annotated[str, RoleSpec()]

The path of the group on the nodes or sites.

required
state str

The name of the discrete state of the members.

'state'
beta Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The rate of spreading from one active neighbour, or from all neighbours when they are all active.

1.0
gamma Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The rate of recovery of an active member.

0.0
omega Annotated[float, ParameterSpec(domain=closed_open(0, oo))]

The rate at which a removed member returns to the inactive value.

0.0
inactive float

The value of the state of an inactive member.

0.0
active float

The value of the state of an active member.

1.0
removed float | None

The value of the state of a recovered member, or None for members that recover to the inactive value.

None
form str

'number' for a rate proportional to the number of active neighbours, or 'fraction' for one proportional to their fraction of the neighbours.

'number'
layer str | None

The layer of the network whose edges the spreading runs on, or None for the graph of the network or the neighbourhood of the lattice.

None

Raises:

Type Description
ValidationError

The form is unknown, or the values of the state are not distinct.

Examples:

>>> from skcomplex.systems.biology.epidemiology import SpreadingInteraction
>>> spreading = SpreadingInteraction('spreading', target='sites', beta=2.0, gamma=1.0, form='fraction')
>>> spreading.form
'fraction'
Source code in src/skcomplex/systems/biology/common/networks/_spreading.py
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def __init__(
    self,
    label: str,
    *,
    target: Annotated[str, RoleSpec()],
    state: str = 'state',
    beta: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 1.0,
    gamma: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    omega: Annotated[float, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 0.0,
    inactive: float = 0.0,
    active: float = 1.0,
    removed: float | None = None,
    form: str = 'number',
    layer: str | None = None,
) -> None:
    super().__init__(label, target=target, state=state)
    self.beta = beta
    self.gamma = gamma
    self.omega = omega
    self.inactive = inactive
    self.active = active
    self.removed = removed
    self.form = form
    self.layer = layer

WeightedEdgeElement(label, visual=None, *, w=0.0, fresh=1.0)

Bases: Element

Edge of a network with a weight w, such as the strength of an influence or a coupling between two species.

A new edge is marked fresh until an EdgeDrawInteraction draws its weight.

Parameters:

Name Type Description Default
label str

The label of the edge or of the group of edges.

required
visual VisualSpec | None

How the element is drawn, or None for default_visual_.

None
w Annotated[float, StateSpec()]

The weight.

0.0
fresh Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))]

Whether the edge has not drawn its weight yet, 1 or 0.

1.0

Examples:

>>> from skcomplex.systems.biology.common.networks import WeightedEdgeElement
>>> WeightedEdgeElement('edge').fresh
1.0
Source code in src/skcomplex/systems/biology/common/networks/_weighted_edge.py
38
39
40
41
42
43
44
45
46
47
48
def __init__(
    self,
    label: str,
    visual: VisualSpec | None = None,
    *,
    w: Annotated[float, StateSpec()] = 0.0,
    fresh: Annotated[float, StateSpec(domain=FiniteEnumeratedSet([0, 1]))] = 1.0,
) -> None:
    super().__init__(label, visual=visual)
    self.w = w
    self.fresh = fresh