pyGD.dynamics module
Continuous phase dynamics on graphs.
This module ports the MATLAB Kuramoto and KuramotoCG classes to Python.
Both consume a networkx.Graph directly; the adjacency matrix is pulled
once as a SciPy sparse (CSR) matrix and the hot loop is the sparse mat-vec
A @ exp(i*theta), mirroring the MATLAB G.adjacency multiply.
KuramotoThe base environment, Eq. (1) of Sowinski, Frank & Ghoshal, PRR 6, 043188 (2024):
dtheta_i/dt = omega_i + sigma * sum_j A_ij sin(theta_j - theta_i).KuramotoCGThe coarse-grained stochastic variant, Eq. (7): the intervening agent is integrated out (Appendix B) into a degree-modulated frequency shift plus a Wiener fluctuation. Kept as an independent class, mirroring the MATLAB.
- class pyGD.dynamics.Kuramoto(sigma, G, omegas, r0=0.0, dt=0.0625, rng=None)[source]
Bases:
objectKuramoto oscillators on the nodes of a graph.
Ported from
Kuramoto.m. Each node carries a phasetheta_i; the global order parameter isZ = mean(exp(i*theta))with magnituderand mean phasephi. The per-node complex local field iskrexp = (A @ exp(i*theta)) * conj(exp(i*theta)).- Parameters:
sigma (float) – Coupling strength.
G (networkx.Graph) – Interaction graph. Adjacency is extracted once as sparse CSR.
omegas (array_like) – Natural frequencies, one per node (node order =
list(G.nodes())).r0 (float, optional) – Initial spread of phases;
theta = (2*U - 1)*pi*(1 - r0)withU ~ Uniform[0,1).r0 = 0gives fully random phases (default).dt (float, optional) – Timestep. Default 0.0625 (= 1/16), matching the MATLAB.
rng (numpy.random.Generator, optional) – Random source; defaults to
numpy.random.default_rng().
- thetas
Current phases, wrapped to (-pi, pi].
- Type:
ndarray
- Z, r, phi
Global order parameter, its magnitude, and its angle.
- Type:
complex, float, float
- krexp
Complex per-node local field (updated by
compute_mean_field()).- Type:
ndarray
- word
Sign bits of
imag(krexp)via Heaviside (0.5 at exactly 0), matching the MATLABcompute_word.- Type:
ndarray
Examples
>>> import networkx as nx, numpy as np >>> G = nx.erdos_renyi_graph(50, 0.1, seed=0) >>> rng = np.random.default_rng(0) >>> env = Kuramoto(0.5, G, rng.standard_normal(G.number_of_nodes()), rng=rng) >>> env.run(10) >>> bool(0.0 <= env.r <= 1.0) True
- run(n_steps, record=False)[source]
Advance
n_stepssteps.- Parameters:
n_steps (int) – Number of steps.
record (bool, optional) – If True, call
update_order_parameter()each step and return the array ofrvalues. Default False (faster; no measurement).
- Returns:
The
rhistory ifrecordelse None.- Return type:
ndarray or None
- class pyGD.dynamics.KuramotoCG(sigma, G, omegas, ab, dt=0.0625, rng=None)[source]
Bases:
objectCoarse-grained (stochastic) Kuramoto dynamics, Eq. (7).
Ported from
KuramotoCG.m. The intervening agent is integrated out into (i) a degree-modulated shift of the natural frequencies and (ii) a Wiener fluctuation whose amplitude scales with node degree. See Appendix B of the paper; the two agent parameters enter only through their productab(= alpha*beta). This is the continuum limit of aKuramotoenvironment driven by a Yokai agent, but is kept as an independent class.- Parameters:
sigma (float) – Coupling strength.
G (networkx.Graph) – Interaction graph.
omegas (array_like) – Base natural frequencies, one per node.
ab (float) – The product alpha*beta (kick strength times hop speed).
dt (float, optional) – Timestep. Default 0.0625.
rng (numpy.random.Generator, optional) – Random source; defaults to
numpy.random.default_rng().
- thetas, Z, r, phi, krexp, word
As in
Kuramoto.
- fluc
Per-node fluctuation amplitude
sqrt(dt * ab * deg/mean(deg)).- Type:
ndarray
- run(n_steps, record=False)[source]
Advance
n_stepssteps. SeeKuramoto.run().