Synchronization
Synchronization: coupled phase oscillators, pulse-coupled oscillators, swarmalators, chaos, and Kuramoto order.
AdaptiveCouplingInteraction(label, *, nodes, links, K=1.0, alpha=0.0, beta=0.0, epsilon=0.01)
Bases: NeighborInteraction
Adaptive Kuramoto-Sakaguchi coupling, whose weights relax towards a phase-lagged sine of the phase difference.
On every directed link from j to i, the phase of i turns by -K kappa_ij sin(theta_i - theta_j + alpha) and
the weight relaxes as kappa_ij' = -epsilon (kappa_ij + sin(theta_i - theta_j + beta)), so it grows between
oscillators whose phases differ by about -beta - pi / 2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
nodes
|
Annotated[str, RoleSpec()]
|
The path of the group of phase oscillators on the nodes. |
required |
links
|
Annotated[str, RoleSpec()]
|
The path of the group of adaptive links on the edges. |
required |
K
|
Annotated[float, ParameterSpec()]
|
The coupling strength, |
1.0
|
alpha
|
Annotated[float, ParameterSpec()]
|
The phase lag of the coupling. |
0.0
|
beta
|
Annotated[float, ParameterSpec()]
|
The phase lag of the adaptation. |
0.0
|
epsilon
|
Annotated[float, ParameterSpec()]
|
The rate of the adaptation. |
0.01
|
Examples:
>>> from skcomplex.systems.physics.synchronization import AdaptiveCouplingInteraction
>>> AdaptiveCouplingInteraction('adaptation', nodes='nodes', links='links').epsilon
0.01
Source code in src/skcomplex/systems/physics/synchronization/_adaptive.py
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
AdaptiveLinkElement(label, visual=None, *, kappa=0.0)
Bases: Element
Directed link of an adaptive network with the coupling weight kappa, a state that the phases of its ends adapt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the link or the group on the links. |
required |
visual
|
VisualSpec | None
|
How the link is drawn, or |
None
|
kappa
|
Annotated[float, StateSpec()]
|
The initial coupling weight. |
0.0
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the link when it sets none. |
Examples:
>>> from skcomplex.systems.physics.synchronization import AdaptiveLinkElement
>>> AdaptiveLinkElement('link', kappa=0.5).kappa
0.5
Source code in src/skcomplex/systems/physics/synchronization/_adaptive.py
47 48 49 50 51 52 53 54 55 | |
AggregateAveragingInteraction(label, *, source, target, r=4.0, kappa=0.4, kind='logistic', delay=0)
Bases: MapInteraction
Logistic or Bernoulli map of an aggregate of the value of a target and the value of a source, possibly delayed.
The map sets x_t(t + 1) = f(a) with the aggregate a = (1 - kappa) x_t(t) + kappa x_s(t - delay), and with the
logistic map f(a) = r a (1 - a) or the Bernoulli shift f(a) = r a mod 1. A delayed source keeps delay lags.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
source
|
Annotated[str, RoleSpec()]
|
The path of the unit whose value the aggregate reads. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the unit whose value the map sets. |
required |
r
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The growth rate of the logistic map. |
4.0
|
kappa
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the source in the aggregate. |
0.4
|
kind
|
str
|
The map, |
'logistic'
|
delay
|
int
|
The number of steps by which the source is delayed. |
0
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
The map is unknown, or the delay is not a nonnegative integer. |
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.physics.synchronization import AggregateAveragingInteraction
>>> averaging = AggregateAveragingInteraction('averaging', source='a', target='b').prepare()
>>> source, target = SimpleNamespace(x=var('u')), SimpleNamespace(x=var('v'))
>>> namespace = SimpleNamespace(source=source, target=target, r=4, kappa=var('kappa'))
>>> [law.value.factor() for law in averaging.run(namespace).laws_]
[-4*(kappa*u - kappa*v + v)*(kappa*u - kappa*v + v - 1)]
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
DelayedCouplingInteraction(label, *, source, target, K=1.0, tau=1.0)
Bases: RateInteraction
Delayed sine coupling of one phase oscillator to another, theta_t' += K sin(theta_s(t - tau) - theta_t).
The target reads the phase of the source as it was a delay tau earlier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
source
|
Annotated[str, RoleSpec()]
|
The path of the oscillator whose delayed phase the coupling reads. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the oscillator whose phase the coupling turns. |
required |
K
|
Annotated[float, ParameterSpec()]
|
The coupling strength. |
1.0
|
tau
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The delay. |
1.0
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.physics.synchronization import DelayedCouplingInteraction
>>> coupling = DelayedCouplingInteraction('coupling', source='a', target='b').prepare()
>>> namespace = SimpleNamespace(source=SimpleNamespace(theta=var('a')), target=SimpleNamespace(theta=var('b')))
>>> [law.value for law in coupling.run(SimpleNamespace(**vars(namespace), K=var('K'), tau=1)).laws_]
[K*sin(-b + delayed(a, 1))]
Source code in src/skcomplex/systems/physics/synchronization/_kuramoto.py
61 62 63 64 65 66 67 68 69 70 71 72 73 | |
DelayedUnitElement(label, visual=None, *, value=0.3, delay=1, variables=None)
Bases: DeclaredElement
Value x of a map that keeps its last delay values, which a delayed coupling reads.
The state x has delay lags, x_lag1 to x_lag<delay>, and before the start every lag holds the initial value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the unit. |
required |
visual
|
VisualSpec | None
|
How the unit is drawn, or |
None
|
value
|
float
|
The initial value of |
0.3
|
delay
|
int
|
The number of past values the unit keeps, at least 1. |
1
|
variables
|
Mapping[str, DeclaredVariableSpec] | None
|
The declared variables that replace the derived ones, or |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the unit when it sets none. |
Examples:
>>> from skcomplex.systems.physics.synchronization import DelayedUnitElement
>>> DelayedUnitElement('unit', delay=2).get_value('x')
0.3
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
134 135 136 137 138 139 140 141 142 143 144 145 | |
DiffusiveCouplingInteraction(label, *, source, target, state='x2', k=0.1)
Bases: RateInteraction
Diffusive coupling of a state of one element to the same state of another, x_t' += k (x_s - x_t).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
source
|
Annotated[str, RoleSpec()]
|
The path of the element whose state the coupling reads. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the element whose state the coupling changes. |
required |
state
|
str
|
The name of the coupled state. |
'x2'
|
k
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The coupling strength. |
0.1
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.physics.synchronization import DiffusiveCouplingInteraction
>>> coupling = DiffusiveCouplingInteraction('coupling', source='a', target='b').prepare()
>>> source, target = SimpleNamespace(x2=var('u')), SimpleNamespace(x2=var('v'))
>>> [law.value for law in coupling.run(SimpleNamespace(source=source, target=target, k=var('k'))).laws_]
[k*(u - v)]
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
394 395 396 397 398 399 400 401 402 403 404 405 | |
EdgeCouplingInteraction(label, *, target, links, K=1.0, alpha=0.0)
Bases: KuramotoCouplingInteraction
Kuramoto coupling along the weighted edges of a network, theta_i' += K w_ij sin(theta_j - theta_i).
The coupling runs once per edge of the network of its oscillators and reads the weight w of the edge from the
group on the edges.
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 of oscillators on the nodes. |
required |
links
|
Annotated[str, RoleSpec()]
|
The path of the group on the edges, whose parameter |
required |
K
|
float
|
The coupling strength. |
1.0
|
alpha
|
float
|
The phase lag. |
0.0
|
Examples:
>>> from skcomplex.systems.physics.synchronization import EdgeCouplingInteraction
>>> EdgeCouplingInteraction('coupling', target='nodes', links='edges', K=0.5).weights
'w'
Source code in src/skcomplex/systems/physics/synchronization/_networks.py
100 101 102 103 104 105 106 107 108 109 110 | |
GlobalCouplingInteraction(label, *, target, state='x', K=1.0)
Bases: CouplingInteraction
Diffusive coupling of one state of every member to the mean of the group, x_i' += K (mean_j x_j - x_i).
The mean runs over every member, the member itself included.
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. |
required |
state
|
str
|
The name of the coupled state. |
'x'
|
K
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The coupling strength. |
1.0
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.physics.synchronization import GlobalCouplingInteraction
>>> coupling = GlobalCouplingInteraction('coupling', target='oscillators', state='y').prepare()
>>> member, other = SimpleNamespace(y=var('y')), SimpleNamespace(y=var('z'))
>>> coupling.function(SimpleNamespace(K=var('K'), member=member, other=other))
-K*(y - z)
Source code in src/skcomplex/systems/physics/synchronization/_amplitude_death.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | |
IntegrateAndFireOscillatorElement(label, visual=None, *, x=0.0, S=2.0, gamma=1.0, epsilon=0.1)
Bases: Element
Integrate-and-fire oscillator that charges as x' = S - gamma x, and sends pulses of strength epsilon.
The oscillator charges towards S / gamma. Its firing at 1 is a crossing of the group it belongs to, which resets
the most charged oscillators to 0 and lifts every other one by epsilon.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the oscillator or the group. |
required |
visual
|
VisualSpec | None
|
How the oscillator is drawn, or |
None
|
x
|
Annotated[float, StateSpec()]
|
The initial charge. |
0.0
|
S
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The charging input. |
2.0
|
gamma
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The leak rate. |
1.0
|
epsilon
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The strength of a pulse. |
0.1
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the oscillator when it sets none. |
Examples:
>>> from skcomplex.systems.physics.synchronization import IntegrateAndFireOscillatorElement
>>> IntegrateAndFireOscillatorElement('oscillator').epsilon
0.1
Source code in src/skcomplex/systems/physics/synchronization/_pulses.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
LinkElement(label, visual=None, *, w=1.0)
Bases: Element
Edge of a network with a weight w, which couplings along the edge read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the edge or the group on the edges. |
required |
visual
|
VisualSpec | None
|
How the edge is drawn, or |
None
|
w
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the edge. |
1.0
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the edge when it sets none. |
Examples:
>>> from skcomplex.systems.physics.common.oscillators import LinkElement
>>> LinkElement('link', w=0.5).w
0.5
Source code in src/skcomplex/systems/physics/common/oscillators/_link.py
38 39 40 41 42 43 44 45 46 | |
LogisticCouplingInteraction(label, *, target, state='x')
Bases: CouplingInteraction
Coupled logistic maps, x_i(t + 1) = (1 - epsilon) f(x_i) + epsilon mean_j f(x_j) with f(x) = r x (1 - x).
The map of every node mixes with the mean of the maps of its neighbours j on its lattice or network, with the
parameters r and epsilon of the node. A node with no neighbours keeps (1 - epsilon) f(x_i). It is the map
form of coupling, with the mean of the maps of the neighbours combined with the map of the node.
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 of maps, on the nodes of a lattice or network. |
required |
state
|
str
|
The name of the state that the maps iterate. |
'x'
|
Examples:
>>> import networkx as nx
>>> from skcomplex.core.components.elements import LatticeElement
>>> from skcomplex.core.components.spaces import DiscreteTime, NetworkSpace
>>> from skcomplex.core.components.system import System
>>> from skcomplex.core.engine.runtime import Simulation
>>> from skcomplex.systems.physics.synchronization import LogisticCouplingInteraction, LogisticNodeElement
>>> maps = LatticeElement(
... 'maps',
... element=LogisticNodeElement,
... space=NetworkSpace(nx.path_graph(2)),
... values={'x': [0.25, 0.5], 'epsilon': 0.5},
... )
>>> coupling = LogisticCouplingInteraction('coupling', target='maps')
>>> system = System(elements=[maps], interactions=[coupling], time=DiscreteTime())
>>> Simulation(system).prepare().run(until=1).trajectory_.values('maps.x')[-1].tolist()
[0.875, 0.875]
Source code in src/skcomplex/systems/physics/synchronization/_networks.py
149 150 151 152 153 154 155 156 157 158 159 160 | |
LogisticNodeElement(label, visual=None, *, x=0.5, r=4.0, epsilon=0.5)
Bases: Element
Logistic map on a node of a network, with its value, growth rate, and weight of the neighbours.
LogisticCouplingInteraction iterates x_i(t + 1) = (1 - epsilon) f(x_i) + epsilon mean_j f(x_j), where the map
f(x) = r x (1 - x) of the node mixes with the mean of the maps of its neighbours j on the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the node or the group on the nodes. |
required |
visual
|
VisualSpec | None
|
How the node is drawn, or |
None
|
x
|
Annotated[float, StateSpec()]
|
The initial value. |
0.5
|
r
|
Annotated[float, ParameterSpec()]
|
The growth rate of the logistic map. |
4.0
|
epsilon
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The weight of the neighbours. |
0.5
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the node when it sets none. |
Examples:
>>> from skcomplex.systems.physics.synchronization import LogisticNodeElement
>>> LogisticNodeElement('node').epsilon
0.5
Source code in src/skcomplex/systems/physics/synchronization/_networks.py
57 58 59 60 61 62 63 64 65 66 67 68 69 | |
LogisticUnitElement(label, visual=None, *, x=0.3)
Bases: Element
Value x in [0, 1] of a logistic map, which maps of the coupling iterate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the unit. |
required |
visual
|
VisualSpec | None
|
How the unit is drawn, or |
None
|
x
|
Annotated[float, StateSpec()]
|
The initial value. |
0.3
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the unit when it sets none. |
Examples:
>>> from skcomplex.systems.physics.synchronization import LogisticUnitElement
>>> LogisticUnitElement('unit').x
0.3
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
176 177 178 179 180 181 182 183 184 | |
RosslerOscillatorElement(label, visual=None, *, x1=1.0, x2=0.0, x3=0.0, omega=1.0, a=0.2, b=0.2, c=5.7, p=1.0)
Bases: Element
Rössler oscillator x1' = -omega x2 - x3, x2' = omega x1 + a x2, x3' = b + x3 (x1 - c).
It is chaotic for a = b = 0.2 and c = 5.7. The time scale p divides every rate, p x' = f(x), so p < 1
speeds the oscillator up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the oscillator. |
required |
visual
|
VisualSpec | None
|
How the oscillator is drawn, or |
None
|
x1
|
Annotated[float, StateSpec()]
|
The initial first variable. |
1.0
|
x2
|
Annotated[float, StateSpec()]
|
The initial second variable. |
0.0
|
x3
|
Annotated[float, StateSpec()]
|
The initial third variable. |
0.0
|
omega
|
Annotated[float, ParameterSpec()]
|
The natural frequency. |
1.0
|
a
|
Annotated[float, ParameterSpec()]
|
The first Rössler parameter. |
0.2
|
b
|
Annotated[float, ParameterSpec()]
|
The second Rössler parameter. |
0.2
|
c
|
Annotated[float, ParameterSpec()]
|
The third Rössler parameter. |
5.7
|
p
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The time scale, which divides every rate. |
1.0
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
The visual of the oscillator when it sets none. |
Examples:
>>> from skcomplex.systems.physics.synchronization import RosslerOscillatorElement
>>> RosslerOscillatorElement('oscillator').c
5.7
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
SimplexCouplingInteraction(label, *, target, K1=0.0, K2=1.0)
Bases: HyperedgeInteraction
Kuramoto coupling through the simplices of a hypergraph, pairs and triangles.
On a link, the focal oscillator i gets K1 sin(theta_j - theta_i), and on a triangle K2 sin(theta_j + theta_k -
2 theta_i) from its two other members j and k.
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 of oscillators on the nodes. |
required |
K1
|
Annotated[float, ParameterSpec()]
|
The coupling of every link. |
0.0
|
K2
|
Annotated[float, ParameterSpec()]
|
The coupling of every triangle. |
1.0
|
Examples:
>>> from skcomplex.systems.physics.synchronization import SimplexCouplingInteraction
>>> SimplexCouplingInteraction('coupling', target='oscillators', K2=0.5).K2
0.5
Source code in src/skcomplex/systems/physics/synchronization/_hypergraphs.py
54 55 56 57 58 59 60 61 62 63 64 65 | |
SwarmalatorCouplingInteraction(label, first, second, cutoff=1000000.0, position='x', *, A=1.0, B=1.0, J=1.0, K=0.0, period=None, n_units=1)
Bases: PairCouplingInteraction
Coupling of two swarmalators through their separation r and their phase difference dtheta.
Each swarmalator moves toward the other at the speed (A + J cos(dtheta)) / N, away from it at B / (N |r|), and
turns its phase toward the other's at the rate K sin(dtheta) / (N |r|), as in O'Keeffe, Ceron, and Petersen. It
is a pair coupling of the positions and the phases jointly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
first
|
Annotated[str, RoleSpec()]
|
The path of the group of the first members. |
required |
second
|
Annotated[str, RoleSpec()]
|
The path of the group of the second members. |
required |
cutoff
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The distance beyond which pairs do not interact, large for the all-to-all system. |
1000000.0
|
position
|
str
|
The name of the vector state that holds the positions of the members. |
'x'
|
A
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The strength of the attraction. |
1.0
|
B
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The strength of the repulsion. |
1.0
|
J
|
Annotated[float, ParameterSpec()]
|
The influence of the phase similarity on the attraction. |
1.0
|
K
|
Annotated[float, ParameterSpec()]
|
The phase coupling, synchronizing when positive. |
0.0
|
period
|
float | None
|
The side of a periodic box, for minimum image distances, or |
None
|
n_units
|
int
|
The number of swarmalators |
1
|
Examples:
>>> from skcomplex.systems.physics.synchronization import SwarmalatorCouplingInteraction
>>> SwarmalatorCouplingInteraction('coupling', first='units', second='units', J=0.5).J
0.5
Source code in src/skcomplex/systems/physics/synchronization/_swarmalators.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 135 136 137 138 | |
SwarmalatorElement(label, visual=None, *, theta=0.0, omega=1.0, x=0.0)
Bases: SitedOscillatorElement
Phase oscillator whose place x is a position that moves by the rates of interactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the swarmalator or the group. |
required |
visual
|
VisualSpec | None
|
How the swarmalator is drawn, or |
None
|
theta
|
float
|
The initial phase. |
0.0
|
omega
|
float
|
The natural frequency. |
1.0
|
x
|
Annotated[ArrayLike, StateSpec(vector=True, role=position)]
|
The initial position. A number applies to every component. |
0.0
|
Examples:
>>> from skcomplex.systems.physics.synchronization import SwarmalatorElement
>>> SwarmalatorElement('unit', x=[0.0, 1.0]).x
[0.0, 1.0]
Source code in src/skcomplex/systems/physics/synchronization/_swarmalators.py
50 51 52 53 54 55 56 57 58 59 | |
WinfreeMeanFieldInteraction(label, *, target, K=1.0)
Bases: CouplingInteraction
Winfree coupling theta_i' += K mean_j P(theta_j) R(theta_i) over every member j of the group.
The influence P(theta) = 1 + cos(theta) that an oscillator sends and the sensitivity R(theta) = -sin(theta) with
which it responds make every oscillator respond to the mean influence of the group.
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 of oscillators. |
required |
K
|
Annotated[float, ParameterSpec()]
|
The coupling strength. |
1.0
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.physics.synchronization import WinfreeMeanFieldInteraction
>>> coupling = WinfreeMeanFieldInteraction('coupling', target='oscillators')
>>> member, other = SimpleNamespace(theta=var('a')), SimpleNamespace(theta=var('b'))
>>> coupling.function(SimpleNamespace(K=var('K'), member=member, other=other))
-K*(cos(b) + 1)*sin(a)
Source code in src/skcomplex/systems/physics/synchronization/_pulses.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
adaptive_kuramoto(n_oscillators=50, *, alpha=0.3 * math.pi, beta=0.23 * math.pi, epsilon=0.01, omega=0.0, seed=0)
Return globally coupled phase oscillators whose coupling weights adapt to their phase differences.
The oscillators follow the Kuramoto-Sakaguchi model theta_i' = omega - (1 / N) Σ_j kappa_ij sin(theta_i - theta_j +
alpha), and every weight of the directed link from j to i adapts as
kappa_ij' = -epsilon (kappa_ij + sin(theta_i - theta_j + beta)), Eqs. 28-29 of Berner et al. The weights are
states of a group on the edges of the complete directed graph. Even identical oscillators split into frequency
clusters: groups whose members share one mean frequency, strongly coupled within and weakly coupled across, with
the weights inside a cluster near -sin(theta_i - theta_j + beta). The phases and the weights start uniformly at
random in [0, 2 pi) and [-1, 1].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators. |
50
|
alpha
|
float
|
The phase lag of the coupling. |
0.3 * pi
|
beta
|
float
|
The phase lag of the adaptation. |
0.23 * pi
|
epsilon
|
float
|
The rate of the adaptation, slow for small values. |
0.01
|
omega
|
float
|
The natural frequency of every oscillator. |
0.0
|
seed
|
int
|
The seed of the random initial phases and weights. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import adaptive_kuramoto
>>> adaptive_kuramoto(5).elements[1].prepare().size_
20
Source code in src/skcomplex/systems/physics/synchronization/_adaptive.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |
aggregate_averaging_synchronization(x1=0.3, x2=0.6, *, r=4.0, kappa=0.4, kind='logistic', delay=0)
Return two chaotic maps coupled by aggregate averaging, which synchronize their chaos for strong coupling.
Each map iterates on the aggregate of its own value and the other's, x_i(t + 1) = f(a_i) with a_1 = (1 - kappa)
x_1(t) + kappa x_2(t - T) and a_2 = (1 - kappa) x_2(t) + kappa x_1(t - T), for the delay T. The logistic map is
f(a) = r a (1 - a). Without delay, its synchronized orbit is stable for kappa > (r - 1) / (2 r), which is 3 /
8 for r = 4, and the maps agree in one step for kappa = 1 / 2. The Bernoulli shift f(a) = r a mod 1 has the
constant slope r, so a difference d of the maps follows d(t + 1) = r ((1 - kappa) d(t) - kappa d(t - T))
exactly, and the maps synchronize when every root of z^(T + 1) - r (1 - kappa) z^T + r kappa lies in the unit
disk, which for T = 0 is |r (1 - 2 kappa)| < 1. The delay shrinks the window of synchronizing couplings: for r
= 1.5 it is 0.17 < kappa < 0.83 without delay, 0.17 < kappa < 0.66 for T = 1, and 0.17 < kappa < 0.44 for
T = 2, and it closes for T >= 5. Before the start, the delayed values equal the initial values. An integer slope
such as 2 loses one binary digit of the value per step in floating point and falls onto 0, so a slope that is not an
integer, such as 1.5, keeps the chaos.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x1
|
float
|
The initial value of the first map. |
0.3
|
x2
|
float
|
The initial value of the second map. |
0.6
|
r
|
float
|
The growth rate of the logistic map. |
4.0
|
kappa
|
float
|
The coupling strength. |
0.4
|
kind
|
str
|
The map, |
'logistic'
|
delay
|
int
|
The delay |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the values |
Examples:
>>> from skcomplex.systems.physics.synchronization import aggregate_averaging_synchronization
>>> aggregate_averaging_synchronization(kappa=0.1).interactions[0].kappa
0.1
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | |
coupled_map_lattices_on_networks(n_nodes=100, *, network='erdos_renyi', degree=20, rewiring=0.1, r=4.0, epsilon=0.9, seed=0)
Return chaotic logistic maps on the nodes of a network, each pulled towards the mean of its neighbours.
Node i follows x_i(t + 1) = (1 - epsilon) f(x_i) + (epsilon / k_i) sum_j A_ij f(x_j) with the logistic map
f(x) = r x (1 - x), a mean over the neighbours of the network. For a coupling epsilon large enough against the
Lyapunov exponent of the map and the spectral gap of the network, the maps synchronize on one chaotic orbit, and
the variance of the states over the nodes falls to zero. Below it they stay incoherent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_nodes
|
int
|
The number of maps, the nodes of the network. |
100
|
network
|
str
|
The generator, |
'erdos_renyi'
|
degree
|
int
|
The mean degree of the network. |
20
|
rewiring
|
float
|
The probability of rewiring every edge of the Watts-Strogatz ring. |
0.1
|
r
|
float
|
The parameter of the logistic map, chaotic at 4. |
4.0
|
epsilon
|
float
|
The coupling between 0 and 1. |
0.9
|
seed
|
int
|
The seed of the network and the initial states. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the states |
Raises:
| Type | Description |
|---|---|
ValueError
|
The network is unknown. |
Examples:
>>> from skcomplex.systems.physics.synchronization import coupled_map_lattices_on_networks
>>> coupled_map_lattices_on_networks(20).elements[0].prepare().size_
20
Source code in src/skcomplex/systems/physics/synchronization/_networks.py
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
coupled_rossler(n_oscillators=2, *, k=0.04, mismatch=0.02, a=0.2, b=0.2, c=5.7, seed=0)
Return chaotic Rössler oscillators on a ring, diffusively coupled through their second variable.
Oscillator i follows x1' = -ω_i x2 - x3, x2' = ω_i x1 + a x2 + k sum_j (x2_j - x2_i), and
x3' = b + x3 (x1 - c), summed over its neighbours on the ring. Two oscillators with frequencies 1 ± mismatch
pass from no synchronization to chaotic phase synchronization as k grows. Identical oscillators, with no mismatch,
synchronize completely when every nonzero eigenvalue of the ring's Laplacian times k falls where the master
stability function is negative.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators on the ring. |
2
|
k
|
float
|
The coupling strength. |
0.04
|
mismatch
|
float
|
The half width of the interval of natural frequencies around 1. |
0.02
|
a
|
float
|
The first Rössler parameter. |
0.2
|
b
|
float
|
The second Rössler parameter. |
0.2
|
c
|
float
|
The third Rössler parameter. |
5.7
|
seed
|
int
|
The seed of the initial states. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the states |
Examples:
>>> from skcomplex.systems.physics.synchronization import coupled_rossler
>>> [element.omega for element in coupled_rossler().elements]
[0.98, 1.02]
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | |
delayed_kuramoto(n_oscillators=5, *, K=2.0, tau=1.0, spread=0.2, seed=0)
Return Kuramoto phase oscillators coupled all to all through signals that arrive after a delay.
Oscillator i follows theta_i' = omega_i + (K / N) sum_j sin(theta_j(t - tau) - theta_i), with natural
frequencies spread evenly around 1 and initial phases spread around the circle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators. |
5
|
K
|
float
|
The coupling strength. |
2.0
|
tau
|
float
|
The delay of the coupling. |
1.0
|
spread
|
float
|
The width of the interval of natural frequencies around 1. |
0.2
|
seed
|
int
|
The seed of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import delayed_kuramoto
>>> len(delayed_kuramoto(n_oscillators=3).interactions)
6
Source code in src/skcomplex/systems/physics/synchronization/_kuramoto.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
heterogeneous_global_coupling(n_systems=100, *, k=2.0, beta=0.1, gamma=2.0, heterogeneity=0.8, random_state=0)
Return globally coupled oscillators with heterogeneous time scales, whose fixed point the coupling restabilizes.
System j follows x_j' = τ_j g(x_j, y_j) + k (X - x_j) and y_j' = τ_j h(x_j, y_j) + k (Y - y_j), where X
and Y are the population means and g + ih = (beta + i gamma) z - |z|² z is the Hopf normal form of
z = x + iy. Its fixed point 0 is an unstable focus with eigenvalues beta ± i gamma. The time scales τ_j are
spread evenly over [1 - heterogeneity, 1 + heterogeneity], with mean 1 and variance sigma². The order
parameters X, Y, V = <δτ δx>, and W = <δτ δy> close on four equations. The global fixed point is stable
when their eigenvalues nu - k / 2 ± √(k² / 4 + sigma² nu²), for nu = beta ± i gamma, have negative real parts,
which holds roughly for 2 beta (1 + sigma) < k < (gamma² - beta²) sigma² / beta.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_systems
|
int
|
The number of coupled systems. |
100
|
k
|
float
|
The coupling constant. |
2.0
|
beta
|
float
|
The growth rate |
0.1
|
gamma
|
float
|
The rotation rate |
2.0
|
heterogeneity
|
float
|
The half width of the interval of time scales, below 1. |
0.8
|
random_state
|
int | Generator | None
|
The seed or generator of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the states |
Examples:
>>> from skcomplex.systems.physics.synchronization import heterogeneous_global_coupling
>>> heterogeneous_global_coupling(4).elements[0].values['tau']
array([0.4, 0.8, 1.2, 1.6])
Source code in src/skcomplex/systems/physics/synchronization/_amplitude_death.py
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
hypergraph_kuramoto(n_oscillators=60, *, K1=0.0, K2=8.0, width=0.5, links=1.0, triangles=1.0, phases=None, seed=0)
Return Kuramoto oscillators coupled in pairs and by three-body interactions on the triangles of a hypergraph.
Oscillator i follows theta_i' = omega_i + (K1 / <k1>) sum_j sin(theta_j - theta_i) + (K2 / <k2>) sum_jk
sin(theta_j + theta_k - 2 theta_i) over the links ij and the triangles ijk of a random hypergraph, where <k1>
and <k2> are the mean numbers of links and of triangles of a node. All-to-all, the triangle term is the
three-body coupling of Skardal and Arenas, and the Ott-Antonsen reduction of Lorentzian frequencies of half width
width gives r' = -width r + K1 (r - r^3) / 2 + K2 (r^3 - r^5) / 2. Without links, the incoherent state stays
stable for every K2, and for K2 > 8 width a synchronized state of r^2 = (1 + sqrt(1 - 8 width / K2)) / 2
coexists with it, so the order parameter depends on the initial phases and sweeps of the coupling show hysteresis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators, the nodes of the hypergraph. |
60
|
K1
|
float
|
The pairwise coupling, divided by the mean number of links of a node. |
0.0
|
K2
|
float
|
The three-body coupling, divided by the mean number of triangles of a node. |
8.0
|
width
|
float
|
The half width of the Lorentzian distribution of the natural frequencies. |
0.5
|
links
|
float
|
The probability that a pair of oscillators is a link. |
1.0
|
triangles
|
float
|
The probability that a triple of oscillators is a triangle. |
1.0
|
phases
|
Sequence[float] | None
|
The initial phases, or |
None
|
seed
|
int
|
The seed of the hypergraph, the frequencies, and the phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import hypergraph_kuramoto
>>> system = hypergraph_kuramoto(6)
>>> len(system.elements[0].space.prepare().hyperedges_)
35
Source code in src/skcomplex/systems/physics/synchronization/_hypergraphs.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | |
kuramoto(n_oscillators=50, *, K=4.0, sigma=1.0, seed=0)
Return Kuramoto oscillators coupled all to all, theta_i' = omega_i + (K / N) sum_j sin(theta_j - theta_i).
Every oscillator reads the group means of cos theta and sin theta, so the coupling costs time linear in the
number of oscillators. The natural frequencies are drawn from a normal distribution of width sigma, and the
phases uniformly from the circle. Above the critical coupling K_c = 2 sigma sqrt(2 / pi) a synchronized cluster
forms, and the order parameter r, the modulus of the mean of exp(i theta), grows from about 1 / sqrt(N)
towards 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators. |
50
|
K
|
float
|
The coupling strength. |
4.0
|
sigma
|
float
|
The standard deviation of the natural frequencies. |
1.0
|
seed
|
int
|
The seed of the natural frequencies and the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import kuramoto
>>> system = kuramoto(10)
>>> system.elements[0].size, system.space
(10, None)
Source code in src/skcomplex/systems/physics/synchronization/_kuramoto.py
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
kuramoto_on_networks(n_oscillators=200, *, network='watts_strogatz', degree=6, rewiring=0.1, K=1.0, sigma=0.5, seed=0)
Return Kuramoto oscillators coupled along the edges of a network, theta_i' = omega_i + K sum_j A_ij sin(...).
Oscillator i follows theta_i' = omega_i + (K / <k>) sum_j w_ij sin(theta_j - theta_i) over its neighbours j,
where the weights w_ij = 1 live on a group on the edges and <k> is the mean degree. The coupling runs once per
edge. The natural frequencies are drawn from a normal distribution of width sigma, and the phases uniformly from
the circle. Above a critical coupling of the order of the all-to-all value 2 sigma sqrt(2 / pi), the order
parameter r = |<exp(i theta)>| grows from about 1 / sqrt(N) towards 1, and small-world shortcuts lower it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators, the nodes of the network. |
200
|
network
|
str
|
The generator, |
'watts_strogatz'
|
degree
|
int
|
The mean degree of the network, even for the Watts-Strogatz ring. |
6
|
rewiring
|
float
|
The probability of rewiring every edge of the Watts-Strogatz ring. |
0.1
|
K
|
float
|
The coupling strength, divided by the mean degree. |
1.0
|
sigma
|
float
|
The standard deviation of the natural frequencies. |
0.5
|
seed
|
int
|
The seed of the network, the frequencies, and the phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Raises:
| Type | Description |
|---|---|
ValueError
|
The network is unknown. |
Examples:
>>> from skcomplex.systems.physics.synchronization import kuramoto_on_networks
>>> system = kuramoto_on_networks(20, degree=4)
>>> system.elements[1].prepare().size_
40
Source code in src/skcomplex/systems/physics/synchronization/_networks.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | |
kuramoto_sakaguchi_chimera(n_oscillators=32, *, A=0.2, beta=0.1, spread=0.1, seed=0)
Return two populations of identical phase oscillators with phase lag, where one synchronizes and one drifts.
Oscillator i of population p follows theta_i' = sum_q (K_pq / N) sum_j sin(theta_j - theta_i - alpha), with
the stronger coupling mu = (1 + A) / 2 inside a population, the weaker nu = (1 - A) / 2 between them, and the
lag alpha = pi / 2 - beta. Every population reads the means of cos theta and sin theta of both populations.
The first population starts nearly synchronized and the second spread over the circle. The populations settle in a
chimera, where one is fully synchronized and the other keeps drifting with a partial order parameter, which
breathes for A = 0.2. Which population ends up coherent depends on the initial phases.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators of every population. |
32
|
A
|
float
|
The disparity of the couplings inside and between the populations. |
0.2
|
beta
|
float
|
The distance of the phase lag from |
0.1
|
spread
|
float
|
The width of the initial phases of the first population. |
0.1
|
seed
|
int
|
The seed of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import kuramoto_sakaguchi_chimera
>>> len(kuramoto_sakaguchi_chimera(4).interactions)
4
Source code in src/skcomplex/systems/physics/synchronization/_kuramoto.py
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
mirollo_strogatz(n_oscillators=5, *, S=2.0, gamma=1.0, epsilon=0.1, seed=0)
Return integrate-and-fire oscillators coupled by pulses, which end up firing in unison.
Every oscillator of the group charges as x' = S - gamma x, a concave rise, and fires when it reaches 1. Firing is
an event whose guard is the group maximum of the charges, and it resets the most charged oscillators to 0 and lifts
every other one by epsilon. An oscillator lifted to 1 fires at the same instant and is absorbed into the group
that fired, so the groups merge until all oscillators fire together.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators. |
5
|
S
|
float
|
The charging input. |
2.0
|
gamma
|
float
|
The leak rate, below |
1.0
|
epsilon
|
float
|
The strength of a pulse. |
0.1
|
seed
|
int
|
The seed of the initial charges. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the charges |
Examples:
>>> from skcomplex.systems.physics.synchronization import mirollo_strogatz
>>> mirollo_strogatz(3).elements[0].prepare().size_
3
Source code in src/skcomplex/systems/physics/synchronization/_pulses.py
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
nonlocal_ring_chimera(n_oscillators=100, *, R=14, alpha=1.46, omega=0.0, seed=0)
Return identical phase oscillators on a ring, each coupled to its R nearest neighbours on both sides.
Oscillator i follows phi_i' = omega - (1 / 2R) sum_{j = i - R}^{i + R} sin(phi_i - phi_j + alpha), where the sum
includes the oscillator itself. Near alpha = pi / 2, coherent and incoherent domains coexist on the ring as a
chimera state, which is a long transient on small rings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators on the ring. |
100
|
R
|
int
|
The range of the coupling. |
14
|
alpha
|
float
|
The phase lag. |
1.46
|
omega
|
float
|
The natural frequency. |
0.0
|
seed
|
int
|
The seed of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import nonlocal_ring_chimera
>>> nonlocal_ring_chimera(20, R=3).interactions[0].neighborhood.radius
3.5
Source code in src/skcomplex/systems/physics/synchronization/_kuramoto.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | |
oscillator_death(n_oscillators=100, *, K=3.0, width=1.5, distribution='lorentzian', random_state=0)
Return globally coupled Stuart-Landau oscillators, whose oscillations all die for strong coupling and spread.
Oscillator j follows z_j' = (1 + iω_j) z_j - |z_j|² z_j + (K / N) Σ_k (z_k - z_j) for z_j = x_j + i y_j.
Alone it settles on the unit circle. The frequencies are the midpoint quantiles of a density of width ω0, the
Lorentzian ω0 / (π (ω² + ω0²)) or the quartic g0 / (ω⁴ + ω0⁴). For many oscillators, the common fixed point
z = 0 is stable for K > 1 and ω0 above a critical width, 1 for the Lorentzian and
(1 + √(2K - 1)) / √2 for the quartic density, and every amplitude then decays to zero. For the Lorentzian, the
slowest perturbation decays at the rate ω0 - 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators. |
100
|
K
|
float
|
The coupling strength. |
3.0
|
width
|
float
|
The width |
1.5
|
distribution
|
str
|
The density of frequencies, |
'lorentzian'
|
random_state
|
int | Generator | None
|
The seed or generator of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the states |
Raises:
| Type | Description |
|---|---|
ValidationError
|
The distribution is neither |
Examples:
>>> from skcomplex.systems.physics.synchronization import oscillator_death
>>> oscillator_death(4, distribution='quartic').elements[0].prepare().size_
4
Source code in src/skcomplex/systems/physics/synchronization/_amplitude_death.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | |
ott_antonsen(r=0.1, *, K=2.0, Delta=0.5, omega=0.0)
Return the Ott-Antonsen equation for the order parameter of infinitely many Kuramoto oscillators.
For natural frequencies with a Lorentzian distribution of center omega and half width Delta, the complex order
parameter z = x + i y follows exactly z' = (i omega - Delta) z + (K / 2)(1 - |z|²) z, a Stuart-Landau
oscillator with the growth rate K / 2 - Delta and the saturation K / 2. Its modulus settles at
sqrt(1 - 2 Delta / K) above the critical coupling K_c = 2 Delta, and at 0 below it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r
|
float
|
The initial modulus of the order parameter. |
0.1
|
K
|
float
|
The coupling strength. |
2.0
|
Delta
|
float
|
The half width of the distribution of natural frequencies. |
0.5
|
omega
|
float
|
The center of the distribution of natural frequencies. |
0.0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the real part |
Examples:
>>> from skcomplex.systems.physics.synchronization import ott_antonsen
>>> ott_antonsen(K=3.0).elements[0].kappa
1.5
Source code in src/skcomplex/systems/physics/synchronization/_kuramoto.py
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | |
rossler_driven_lorenz(k=8.0, *, auxiliary=True, p=1 / 6)
Return a chaotic Rössler system that drives a Lorenz-63 system through its second variable.
The drive follows p x1' = -x2 - x3, p x2' = x1 + 0.2 x2, p x3' = 0.2 + x3 (x1 - 5.7), with the time scale
p = 1 / 6 that brings it close to the Lorenz system, and the response follows y1' = 10 (y2 - y1),
y2' = 28 y1 - y2 - y1 y3 + k x2, y3' = y1 y2 - 2.666 y3. The two systems have nothing in common, yet for a
coupling above k ≈ 6.66 the response forgets its initial state and becomes a function of the state of the drive,
generalized synchronization. With auxiliary, a second copy of the response from another initial state receives
the same drive, and the two copies converge to each other exactly when generalized synchronization holds, the
auxiliary system method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
k
|
float
|
The strength of the coupling. |
8.0
|
auxiliary
|
bool
|
Whether a second copy of the response, |
True
|
p
|
float
|
The time scale of the drive. |
1 / 6
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the drive |
Examples:
>>> from skcomplex.systems.physics.synchronization import rossler_driven_lorenz
>>> [element.label for element in rossler_driven_lorenz(auxiliary=False).elements]
['drive', 'response']
Source code in src/skcomplex/systems/physics/synchronization/_chaos.py
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 | |
swarmalators(n_units=100, *, J=1.0, K=0.0, A=1.0, B=1.0, random_state=0)
Return swarmalators, identical oscillators whose phases set their attraction and whose positions their coupling.
Every swarmalator i moves by (1 / N) sum_j [(x_j - x_i) / |x_j - x_i| (A + J cos(theta_j - theta_i)) -
B (x_j - x_i) / |x_j - x_i|^2] and turns by (K / N) sum_j sin(theta_j - theta_i) / |x_j - x_i|. With J > 0
like phases attract. With K = 0 and J = 1 the swarm settles into a static phase wave, a disk whose phase winds
once around its center, so one of the order parameters S± = |mean(exp(i (phi ± theta)))| of the spatial angle
phi and the phase approaches 1. With K > 0 the phases synchronize into a uniform disk, and with K < 0 and
small J they stay asynchronous.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_units
|
int
|
The number of swarmalators |
100
|
J
|
float
|
The influence of the phase similarity on the attraction. |
1.0
|
K
|
float
|
The phase coupling. |
0.0
|
A
|
float
|
The strength of the attraction. |
1.0
|
B
|
float
|
The strength of the repulsion. |
1.0
|
random_state
|
int | Generator | None
|
The seed or generator of the initial positions in the square of side 2 and of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the positions |
Examples:
>>> from skcomplex.systems.physics.synchronization import swarmalators
>>> swarmalators(10, K=-0.1).interactions[0].K
-0.1
Source code in src/skcomplex/systems/physics/synchronization/_swarmalators.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | |
topological_kuramoto(n_nodes=30, *, density=0.4, coupling=2.0, width=1.0, seed=0, model='NL')
Return phases on the nodes and links of a clique complex, coupled through its incidence by order parameters.
Node phases follow theta' = omega + K R_links codifferential(sin(d theta)). Link phases follow phi' = omega + K
R_nodes d(sin(codifferential(phi))) - K codifferential(sin(d phi)). With the signs of codifferential, these are
the Nodes-Links system of Ghorbanchian et al. (2021), Eq. 6 of the review of Majhi, Perc, and Ghosh (2022,
arXiv 2203.06601 §III), which is the source at hand. Here R_nodes is the order parameter of the node phases and
R_links that of the projection of the link phases on the nodes. The review takes frequencies of mean Omega and
standard deviation 1 / tau, with Omega = 2 and tau = 1 for its Fig. 2, on complexes of 500 nodes. The mean 0,
the size, and the random graph are choices of this system.
The Nodes-Links-Triangles system, model='NLT', Eq. 8 of the review, scales the coupling of the link phases through
the nodes by R_nodes R_up and through the triangles by R_links, where R_up is the order parameter of the
projection of the link phases on the triangles. Every projection then couples to another, so all three order
parameters jump together at one explosive transition, while in the Nodes-Links system R_up moves on its own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_nodes
|
int
|
The number of nodes of the random graph. |
30
|
density
|
float
|
The probability of every edge of the random graph. |
0.4
|
coupling
|
float
|
The coupling |
2.0
|
width
|
float
|
The standard deviation of the natural frequencies of the nodes and the links. |
1.0
|
seed
|
int
|
The seed of the graph, the frequencies, and the initial phases. |
0
|
model
|
str
|
The coupling, |
'NL'
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with a group |
Raises:
| Type | Description |
|---|---|
ValidationError
|
The model is neither |
Examples:
>>> from skcomplex.systems.physics.synchronization import topological_kuramoto
>>> [element.size_ for element in topological_kuramoto(6, density=0.8).prepare().elements]
[6, 13]
Source code in src/skcomplex/systems/physics/synchronization/_topological.py
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
winfree(n_oscillators=50, *, K=0.5, spread=0.1, seed=0)
Return the Winfree system, theta_i' = omega_i + (K / N) sum_j P(theta_j) R(theta_i), with the sum over all j.
The influence P(theta) = 1 + cos(theta) and the sensitivity R(theta) = -sin(theta) make every oscillator respond
to the mean influence of the population, which every oscillator reads as a group mean. The natural frequencies are
spread evenly over [1 - spread, 1 + spread]. Weak coupling leaves the oscillators incoherent, moderate coupling
locks them to one frequency, and strong coupling stops them, which is oscillator death.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_oscillators
|
int
|
The number of oscillators. |
50
|
K
|
float
|
The coupling strength. |
0.5
|
spread
|
float
|
The half width of the interval of natural frequencies around 1. |
0.1
|
seed
|
int
|
The seed of the initial phases. |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
system |
System
|
The system, with the phases |
Examples:
>>> from skcomplex.systems.physics.synchronization import winfree
>>> len(winfree(5).interactions)
1
Source code in src/skcomplex/systems/physics/synchronization/_pulses.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |