Reference
Analysis¶
The quantifiers that consume any System. Prose-first
treatments live in the Analysis section.
Orbit diagrams¶
orbit_diagram
¶
orbit_diagram(
sys: Any,
param: str,
values: Any,
*,
n: int = 200,
transient: int = 500,
carry_state: bool = True,
components: int | str | tuple = 0,
ic: Any | None = None,
) -> OrbitDiagram
Sweep a parameter and record the asymptotic orbit at each value.
Works on anything discrete: a :class:~tsdynamics.families.DiscreteMap
directly, or a flow wrapped in a
:class:~tsdynamics.derived.PoincareMap /
:class:~tsdynamics.derived.StroboscopicMap — in which case this is
the bifurcation diagram of the flow. ODE parameter changes reuse the
compiled module (control parameters), so flow sweeps stay cheap; DDE
sweeps recompile per value (their structure depends on all parameters).
| PARAMETER | DESCRIPTION |
|---|---|
sys
|
The system to sweep. Never mutated — each value gets a fresh
TYPE:
|
param
|
Parameter name to sweep.
TYPE:
|
values
|
Parameter values, in sweep order.
TYPE:
|
n
|
Points recorded per parameter value.
TYPE:
|
transient
|
Steps discarded before recording, at every value.
TYPE:
|
carry_state
|
Start each value from the previous value's final state (follows the
attractor branch; the classic way to draw clean diagrams). When
False, every value starts from
TYPE:
|
components
|
Which state components to record (names allowed when the system
declares
TYPE:
|
ic
|
Initial state for the first value (and every value when
TYPE:
|
Examples:
>>> od = orbit_diagram(Logistic(), "r", np.linspace(2.5, 4.0, 600), n=120)
>>> x, y = od.flat()
>>> # bifurcation diagram of a flow:
>>> od = orbit_diagram(PoincareMap(Rossler(), (1, 0.0)), "c", np.linspace(2, 6, 80))
Source code in src/tsdynamics/analysis/orbits/orbit_diagram.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 166 167 168 169 170 171 172 | |
OrbitDiagram
dataclass
¶
OrbitDiagram(
param: str,
values: ndarray,
points: list[ndarray],
components: tuple[int, ...],
meta: dict = dict(),
)
Result of :func:orbit_diagram.
Iterate to get (value, points) pairs, or use :meth:flat for the
scatter-ready arrays.
flat
¶
Flatten to scatter-plot arrays (x, y).
x repeats each parameter value once per recorded point; y is
the chosen recorded component.
Source code in src/tsdynamics/analysis/orbits/orbit_diagram.py
Poincaré sections¶
poincare_section
¶
poincare_section(
sys_or_traj: Any,
plane: tuple,
*,
direction: int = +1,
steps: int = 1000,
transient: int = 0,
dt: float = 0.01,
max_time: float = 10000.0,
) -> Trajectory
Poincaré surface of section.
Two input modes:
- System → wraps it in a :class:
~tsdynamics.derived.PoincareMapand collectsstepsroot-refined crossings (accurate). - Trajectory → finds the plane crossings between consecutive samples by linear interpolation (pure data path; accuracy limited by the trajectory's sampling interval).
| PARAMETER | DESCRIPTION |
|---|---|
sys_or_traj
|
TYPE:
|
plane
|
TYPE:
|
direction
|
Crossing direction filter.
TYPE:
|
steps
|
System mode only — see :class:
TYPE:
|
transient
|
System mode only — see :class:
TYPE:
|
dt
|
System mode only — see :class:
TYPE:
|
max_time
|
System mode only — see :class:
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Trajectory
|
|
Examples:
>>> section = poincare_section(Rossler(), plane=(0, 0.0), steps=500)
>>> section = poincare_section(traj, plane=(2, 25.0)) # from data
Source code in src/tsdynamics/analysis/orbits/poincare.py
Lyapunov quantifiers¶
lyapunov_spectrum
¶
Lyapunov spectrum of any system — uniform entry point.
Dispatches to the family implementation (QR tangent dynamics for maps,
compiled variational equations for ODEs, jitcdde_lyap for DDEs).
Keyword arguments are forwarded (steps= for maps; final_time=,
dt=, burn_in=, ... for flows).
Source code in src/tsdynamics/analysis/lyapunov/__init__.py
max_lyapunov
¶
max_lyapunov(
sys: Any,
*,
d0: float = 1e-09,
n_rescale: int = 400,
steps_per: int = 5,
dt: float | None = None,
transient: int = 500,
ic: Any | None = None,
seed: int | None = None,
) -> float
Maximal Lyapunov exponent by two-trajectory rescaling (Benettin et al. 1976).
Runs a reference and a perturbed copy of the system in lockstep through
the :class:~tsdynamics.families.System protocol — no Jacobian needed, so it
works for any ODE or map (including ones with non-smooth right-hand
sides). Not available for DDEs (their state cannot be set_state-ed);
use DelaySystem.lyapunov_spectrum instead.
| PARAMETER | DESCRIPTION |
|---|---|
sys
|
ODE or map.
TYPE:
|
d0
|
Perturbation size restored at every rescaling.
TYPE:
|
n_rescale
|
Number of rescaling cycles (more → better averaging).
TYPE:
|
steps_per
|
Protocol steps between rescalings.
TYPE:
|
dt
|
Step size for continuous systems (default: the system's step default).
TYPE:
|
transient
|
Protocol steps discarded before measuring.
TYPE:
|
ic
|
Initial condition for the reference trajectory.
TYPE:
|
seed
|
Seed for the random perturbation direction.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
Estimated maximal exponent (per unit time / per iteration). |
Examples:
Source code in src/tsdynamics/analysis/lyapunov/__init__.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 | |
kaplan_yorke_dimension
¶
Kaplan–Yorke (Lyapunov) dimension from a Lyapunov spectrum.
D_KY = j + (λ₁ + ... + λ_j) / |λ_{j+1}| where j is the largest
index with a non-negative cumulative sum (Kaplan & Yorke 1979).
| PARAMETER | DESCRIPTION |
|---|---|
spectrum
|
Lyapunov exponents (any order; sorted descending internally).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
0.0 when every exponent is negative; |
Examples:
Source code in src/tsdynamics/analysis/lyapunov/__init__.py
Fixed points¶
fixed_points
¶
fixed_points(
map_sys: Any,
*,
box: tuple | None = None,
n_seeds: int = 200,
tol: float = 1e-12,
max_iter: int = 60,
dedup_tol: float = 1e-06,
seed: int | None = None,
) -> list[FixedPoint]
Find fixed points f(x) = x of a discrete map by multi-start Newton.
Seeds are drawn uniformly from box plus points sampled from a short
orbit; each runs Newton on g(x) = f(x) − x with the map's Jacobian.
Converged roots are deduplicated and classified by the eigenvalues of
J(x*) (stable iff every |λ| < 1).
| PARAMETER | DESCRIPTION |
|---|---|
map_sys
|
TYPE:
|
box
|
Search box; defaults to the orbit's bounding box padded by 50 %,
or
TYPE:
|
n_seeds
|
Random seeds (orbit points are added on top).
TYPE:
|
tol
|
Residual tolerance
TYPE:
|
max_iter
|
Newton iterations per seed.
TYPE:
|
dedup_tol
|
Distance below which two roots are considered the same point.
TYPE:
|
seed
|
RNG seed for reproducibility.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[FixedPoint]
|
Sorted by first coordinate. |
Examples:
>>> fps = fixed_points(Henon())
>>> [fp.x[0] for fp in fps] # analytic: (-0.7 ± sqrt(0.49 + 5.6)) / 2.8
Source code in src/tsdynamics/analysis/fixedpoints/__init__.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 | |