lyapunov
experimental.network_dynamics.analysis.lyapunov
Functions
| Name | Description |
|---|---|
| lyapunov | Estimate the maximum Lyapunov exponent for a network. |
| lyapunov_spectrum | Estimate the Lyapunov spectrum of a network. |
lyapunov
experimental.network_dynamics.analysis.lyapunov.lyapunov(
network,
solver=None,
t=1000.0,
n=10,
d0=1e-09,
dt=0.1,
t0=0.0,
)Estimate the maximum Lyapunov exponent for a network.
Uses Benettin’s rescaling algorithm: two nearby trajectories are simulated for n segments of length t ms; their divergence rate is averaged to estimate the MLE.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| network | Network | required | |
| solver | solver instance, optional (default: Heun()) | None |
|
| t | float — segment duration in ms | 1000.0 |
|
| n | int — number of rescaling steps | 10 |
|
| d0 | float — initial perturbation magnitude | 1e-09 |
|
| dt | float — integration timestep in ms | 0.1 |
|
| t0 | float — simulation start time | 0.0 |
Returns
| Name | Type | Description |
|---|---|---|
| float — estimated maximum Lyapunov exponent (1/ms) |
Notes
For delayed coupling the history buffer is held fixed across segments (each rescaling step re-seeds only the point state), so the result is a good approximation only when t >> max_delay, not exact. The two-trajectory method is the natural route to a delay-correct MLE – each trajectory evolves its own history, so no explicit history-space tangents are needed – but that needs carrying the full final state (point + history) across segments, or running unsegmented. Run a warmup via network.update_history(result) first to initialise the delay buffer from a settled trajectory.
lyapunov_spectrum
experimental.network_dynamics.analysis.lyapunov.lyapunov_spectrum(
network,
solver=None,
t=1000.0,
n=10,
k=None,
dt=0.1,
t0=0.0,
mode='jvp',
d0=1e-09,
)Estimate the Lyapunov spectrum of a network.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| network | Network | required | |
| solver | solver instance, optional (default: Heun()) | None |
|
| t | float — segment duration in ms | 1000.0 |
|
| n | int — number of rescaling steps | 10 |
|
| k | int — number of exponents to compute (default: all D) | None |
|
| dt | float — integration timestep in ms | 0.1 |
|
| t0 | float — simulation start time | 0.0 |
|
| mode | str — "jvp" (default) uses tangent-space propagation via | jax.linearize; exact and efficient for differentiable systems. “sim” uses finite-difference with d0-scaled perturbations; works for non-differentiable systems. | 'jvp' |
| d0 | float — perturbation magnitude (only used when mode="sim") | 1e-09 |
Returns
| Name | Type | Description |
|---|---|---|
| jnp.ndarray — top k Lyapunov exponents sorted descending (1/ms) |
Notes
Exact for instantaneous (non-delayed) coupling only. Both modes propagate a point state (perturb/linearize only initial_state.dynamics) and reset the delay history buffer each rescaling step, so for delayed coupling the history is held fixed across segments: a good approximation only when t >> max_delay, not the true DDE spectrum (which would need tangents spanning the augmented history-buffer state).