Continuous Dynamical System API

class pynamicalsys.core.continuous_dynamical_systems.ContinuousDynamicalSystem(model: str | None = None, equations_of_motion: Callable | None = None, jacobian: Callable | None = None, system_dimension: int | None = None, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, number_of_parameters: int | None = None)[source]

Bases: object

Class for defining, integrating, and analyzing continuous-time dynamical systems.

This class represents systems of ordinary differential equations of the form

du/dt = f(t, u; parameters),

where u is the state vector and f is the vector field. A system can be created either from one of the built-in models or from user-supplied equations of motion, with an optional Jacobian for tangent-space and stability computations.

The class provides fixed-step and adaptive-step integration together with tools for trajectory generation and nonlinear-dynamics analysis, including Poincaré sections, stroboscopic maps, maxima maps, Lyapunov exponents, covariant Lyapunov vectors (CLVs), SALI, LDI, GALI, recurrence time entropy, Hurst exponent estimation, and basin-of-attraction analysis.

Parameters

modelstr or None, optional

Name of a built-in continuous-time model.

equations_of_motioncallable or None, optional

User-defined vector field with signature f(time, u, parameters) -> NDArray[np.float64].

jacobiancallable or None, optional

Jacobian of the vector field with signature J(time, u, parameters) -> NDArray[np.float64].

system_dimensionint or None, optional

Dimension of the state space for a custom system.

parametersarray_like or None, optional

Parameter vector for the system.

number_of_parametersint or None, optional

Number of parameters expected by the custom system.

Notes

  • A system can be created either from a built-in model or from custom equations of motion, but not both at the same time.

  • The Jacobian is optional for trajectory-level analysis, but it is required for Lyapunov exponents, CLVs, SALI, LDI, and GALI.

  • Built-in models and supported integrators can be queried with the corresponding class methods.

See Also

HamiltonianSystem : Class for separable Hamiltonian systems. DiscreteDynamicalSystem : Class for discrete-time maps.

classmethod available_models() List[str][source]

Return a list of available models.

classmethod available_integrators() List[str][source]

Return a list of available integrators.

property info: Dict[str, Any]

Return a dictionary with information about the current model.

property integrator_info

Return a dictionary with information about the current integrator.

integrator(integrator: str, time_step: float64 = np.float64(0.01), atol: float64 = np.float64(1e-06), rtol: float64 = np.float64(0.001))[source]

Define the integrator.

Parameters

integratorstr

The integrator name. Available options are ‘rk4’ and ‘rk45’

time_stepnp.float64, optional

The integration time step when integrator=’rk4’, by default 1e-2

atolnp.float64, optional

The absolute tolerance used when integrator=’rk45’, by default 1e-6

rtolnp.float64, optional

The relative tolerance used when integrator=’rk45’, by default 1e-3

Raises

ValueError

If time_step, atol, or rtol are negative. If integrator is not available.

TypeError
  • If integrator is not a string.

  • If time_step, atol, or rtol are not valid numbers

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> cds.available_integrators()
['rk4', 'rk45']
>>> ds = cds(model="lorenz system")
>>> ds.integrator("rk4", time_step=0.001) #  To use the RK4 integrator
>>> ds.integrator("rk45", atol=1e-10, rtol=1e-8) #  To use the RK45 integrator
set_parameters(parameters: ndarray[tuple[int, ...], dtype[float64]] | Sequence[float] | float) None[source]

Set the parameter vector of the dynamical system.

This method validates and stores the model parameters. The input can be a scalar, a sequence of floats, or a NumPy array. It is internally converted into a float64 NumPy array of the appropriate size.

Parameters

parametersfloat or sequence of float or ndarray of shape (P,)

The parameter set to be used by the system.

Returns

None

get_parameters() ndarray[tuple[int, ...], dtype[float64]] | None[source]

Return the current parameter vector of the dynamical system.

Returns

ndarray of float64, shape (P,)

The parameter vector currently stored in the system.

evolve_system(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None) ndarray[tuple[int, ...], dtype[float64]][source]

Evolve the dynamical system from the given initial condition over a specified time interval.

Parameters

unumeric_like_t

Initial condition of the system. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

Returns

NDArray[np.float64]

State of the system at time = total_time.

Raises

ValueError
  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If total_time is negative.

TypeError
  • If total_time is not a valid real number.

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> ds = cds(model="lorenz system")
>>> ds.integrator("rk4", time_step=0.01)
>>> parameters = [10.0, 28.0, 8.0 / 3.0]
>>> u0 = [1.0, 1.0, 1.0]
>>> ds.evolve_system(u0, 10.0, parameters=parameters)
>>> ds.integrator("rk45", atol=1e-8, rtol=1e-6)
>>> ds.evolve_system(u0, 10.0, parameters=parameters)
trajectory(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None) ndarray[tuple[int, ...], dtype[float64]] | list[ndarray[tuple[int, ...], dtype[float64]]][source]

Compute the trajectory of the dynamical system over a specified time interval.

Parameters

unumeric_like_t

Initial condition or ensemble of initial conditions. It must define either a 1D state vector of length equal to the system dimension or a 2D array whose rows are valid initial conditions.

total_timenumeric_t

Total integration time.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before storing the trajectory.

Returns

NDArray[np.float64] | list[NDArray[np.float64]]

The computed trajectory.

  • If u is one initial condition, returns an array of shape (num_steps, neq + 1), where the first column contains time and the remaining columns contain the state coordinates.

  • If u is an ensemble of initial conditions and all trajectories have the same number of stored time steps, the result may be represented as arrays with common shape (num_ic, num_steps, neq + 1).

  • If u is an ensemble of initial conditions and the trajectories have different numbers of stored time steps, returns a list of arrays, where each element has shape (num_steps_i, neq + 1).

Raises

ValueError
  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If total_time is negative.

  • If transient_time is negative or not smaller than total_time.

TypeError
  • If total_time or transient_time is not a valid real number.

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> ds = cds(model="lorenz system")
>>> u0 = [0.1, 0.1, 0.1]
>>> parameters = [10.0, 28.0, 8.0 / 3.0]
>>> traj = ds.trajectory(u0, 700.0, parameters=parameters, transient_time=500.0)
>>> u0s = [
...     [0.1, 0.1, 0.1],
...     [0.2, 0.2, 0.2],
...     [0.3, 0.3, 0.3],
... ]
>>> trajs = ds.trajectory(u0s, 700.0, parameters=parameters, transient_time=500.0)
poincare_section(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], num_intersections: int | integer, section_index: int | integer, section_value: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, crossing: int | integer = 1) ndarray[tuple[int, ...], dtype[float64]][source]

Compute the Poincaré section of the dynamical system for given initial conditions.

A Poincaré section records the points where a trajectory intersects a chosen hypersurface in phase space. This reduces a continuous flow to a lower-dimensional map, making it easier to identify periodic, quasi-periodic, or chaotic motion.

Parameters

unumeric_like_t

Initial condition or ensemble of initial conditions. It must define either a 1D state vector of length equal to the system dimension or a 2D array whose rows are valid initial conditions.

num_intersectionsint_t

Number of intersections to record.

section_indexint_t

Index of the coordinate defining the Poincaré section.

section_valuenumeric_t

Value of the coordinate at which the section is defined.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before recording the section.

crossingint_t, optional

Type of crossing to consider: - 1 : positive crossings - -1 : negative crossings - 0 : all crossings

Returns

NDArray[np.float64]

Poincaré section points.

  • If u is one initial condition, returns an array of shape (num_intersections, neq + 1), where the first column is the crossing time and the remaining columns are the state coordinates.

  • If u is an ensemble of initial conditions, returns an array of shape (num_ic, num_intersections, neq + 1).

Raises

ValueError
  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_intersections is negative.

  • If section_index is outside the valid coordinate range.

  • If transient_time is negative or not smaller than the total integration time when such a comparison is required elsewhere.

  • If crossing is not one of -1, 0, or 1.

TypeError
  • If section_value is not a valid real number.

  • If num_intersections, section_index, or crossing are not integers.

  • If transient_time is not a valid real number.

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> ds = cds(model="lorenz system")
>>> u0 = [0.1, 0.1, 0.1]
>>> parameters = [10.0, 28.0, 8.0 / 3.0]
>>> ps = ds.poincare_section(
...     u0,
...     num_intersections=500,
...     section_index=2,
...     section_value=25.0,
...     parameters=parameters,
... )
>>> u0s = [[0.1, 0.1, 0.1], [0.2, 0.2, 0.2]]
>>> ps_ensemble = ds.poincare_section(
...     u0s,
...     num_intersections=500,
...     section_index=2,
...     section_value=25.0,
...     parameters=parameters,
... )
stroboscopic_map(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], num_samples: int | integer, sampling_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None) ndarray[tuple[int, ...], dtype[float64]][source]

Compute the stroboscopic map of the dynamical system for given initial conditions.

A stroboscopic map samples the state of a continuous-time system at fixed time intervals. This converts the flow into a discrete sequence that can reveal periodicity, phase locking, and bifurcations.

Parameters

unumeric_like_t

Initial condition or ensemble of initial conditions. It must define either a 1D state vector of length equal to the system dimension or a 2D array whose rows are valid initial conditions.

num_samplesint_t

Number of samples to record.

sampling_timenumeric_t

Time interval between consecutive samples.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before recording the map.

Returns

NDArray[np.float64]

Stroboscopic map points.

  • If u is one initial condition, returns an array of shape (num_samples, neq + 1), where the first column is time and the remaining columns are the sampled state coordinates.

  • If u is an ensemble of initial conditions, returns an array of shape (num_ic, num_samples, neq + 1).

Raises

ValueError
  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_samples is negative.

  • If sampling_time is negative.

  • If transient_time is negative.

TypeError
  • If num_samples is not an integer.

  • If sampling_time or transient_time is not a valid real number.

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> ds = cds(model="lorenz system")
>>> u0 = [0.1, 0.1, 0.1]
>>> parameters = [10.0, 28.0, 8.0 / 3.0]
>>> smap = ds.stroboscopic_map(
...     u0,
...     num_samples=500,
...     sampling_time=0.1,
...     parameters=parameters,
... )
>>> u0s = [[0.1, 0.1, 0.1], [0.2, 0.2, 0.2]]
>>> smap_ensemble = ds.stroboscopic_map(
...     u0s,
...     num_samples=500,
...     sampling_time=0.1,
...     parameters=parameters,
... )
maxima_map(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], num_points: int | integer, maxima_index: int | integer, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None) ndarray[tuple[int, ...], dtype[float64]][source]

Compute the maxima map of the dynamical system for given initial conditions.

A maxima map records the local maxima of a chosen system variable along the trajectory. By plotting successive maxima, one obtains a discrete return map that can reveal oscillation amplitudes, period-doubling cascades, and other nonlinear behavior.

Parameters

unumeric_like_t

Initial condition or ensemble of initial conditions. It must define either a 1D state vector of length equal to the system dimension or a 2D array whose rows are valid initial conditions.

num_pointsint_t

Number of maxima points to record.

maxima_indexint_t

Index of the state variable whose maxima are recorded.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before recording the maxima map.

Returns

NDArray[np.float64]

Maxima map points.

  • If u is one initial condition, returns an array of shape (num_points, neq + 1), where the first column is time and the remaining columns are the state coordinates at each detected maximum.

  • If u is an ensemble of initial conditions, returns an array of shape (num_ic, num_points, neq + 1).

Raises

ValueError
  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_points is negative.

  • If maxima_index is outside the valid coordinate range.

  • If transient_time is negative.

TypeError
  • If num_points or maxima_index is not an integer.

  • If transient_time is not a valid real number.

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> ds = cds(model="lorenz system")
>>> u0 = [0.1, 0.1, 0.1]
>>> parameters = [10.0, 28.0, 8.0 / 3.0]
>>> mmap = ds.maxima_map(u0, 500, 0, parameters=parameters)
>>> mmap.shape
(500, 4)
>>> u0s = [[0.1, 0.1, 0.1], [0.2, 0.2, 0.2]]
>>> mmap_ensemble = ds.maxima_map(u0s, 500, 0, parameters=parameters)
>>> mmap_ensemble.shape
(2, 500, 4)
basin_of_attraction(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], num_intersections: int | integer, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, map_type: str = 'SM', section_index: int | integer | None = None, section_value: int | float | integer | floating | None = None, crossing: int | integer | None = None, sampling_time: int | float | integer | floating | None = None, eps: int | float | integer | floating = 0.05, min_samples: int | integer = 1) ndarray[tuple[int, ...], dtype[int32]][source]

Compute the basin of attraction for a set of initial conditions.

Parameters

unumeric_like_t

Ensemble of initial conditions for the dynamical system. It must define either a valid 2D array whose rows are initial conditions, or a single initial condition if single-trajectory analysis is intended.

num_intersectionsint_t

Number of intersections or samples used to construct the reduced map.

parametersnumeric_like_t | None, optional

System parameters. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before analyzing the trajectories.

map_typestr, optional

Type of reduced map to construct: - “SM” for stroboscopic map - “PS” for Poincaré section

section_indexint_t | None, optional

Index of the section coordinate when map_type=”PS”.

section_valuenumeric_t | None, optional

Value of the Poincaré section when map_type=”PS”.

crossingint_t | None, optional

Crossing orientation when map_type=”PS”: - -1 for downward crossings - 0 for all crossings - 1 for upward crossings

sampling_timenumeric_t | None, optional

Sampling time when map_type=”SM”.

epsnumeric_t, optional

Maximum neighborhood radius used by DBSCAN.

min_samplesint_t, optional

Minimum number of points required to form a DBSCAN cluster.

Returns

NDArray[np.int32]

Integer labels indicating which attractor each initial condition belongs to. The label -1 indicates noise.

Raises

ValueError
  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_intersections, eps, or min_samples is negative.

  • If map_type is not “SM” or “PS”.

  • If section_index is outside the valid coordinate range.

  • If crossing is not one of -1, 0, or 1.

TypeError
  • If map_type is not a string.

  • If section_value, sampling_time, or transient_time is not a valid real number.

  • If num_intersections, section_index, crossing, or min_samples is not an integer.

Notes

The basin of attraction is estimated by first constructing either a stroboscopic map or a Poincaré section, then clustering trajectory centroids with DBSCAN. Trajectories whose centroids belong to the same cluster are assigned to the same attractor basin.

lyapunov(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, num_exponents: int | integer | None = None, return_history: bool = False, seed: int | integer = 13, log_base: int | float | integer | floating = 2.718281828459045, method: str = 'QR', endpoint: bool = True) float64 | ndarray[tuple[int, ...], dtype[float64]][source]

Calculate the Lyapunov exponents of the dynamical system.

The Lyapunov exponents measure the average exponential rates of divergence or convergence of nearby trajectories.

Parameters

unumeric_like_t

Initial condition of the system. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before computing the exponents.

num_exponentsint_t | None, optional

Number of Lyapunov exponents to compute. If None, the full spectrum is computed.

return_historybool, optional

If True, return the time evolution of the exponents.

seedint_t, optional

Seed used to initialize the deviation vectors.

log_basenumeric_t, optional

Base of the logarithm used to rescale the exponents.

methodstr, optional

QR decomposition method: - “QR”: custom modified Gram-Schmidt QR - “QR_HH”: numpy.linalg.qr based on Householder reflections

endpointbool, optional

Whether to include the endpoint time = total_time.

Returns

np.float64 | NDArray[np.float64]
  • If return_history=True, returns a 2D array whose first column contains the sampled times and whose remaining columns contain the Lyapunov exponents at those times.

  • If return_history=False and num_exponents == 1, returns the largest Lyapunov exponent as a scalar.

  • If return_history=False and num_exponents > 1, returns a 1D array containing the final Lyapunov exponents.

Raises

ValueError
  • If the Jacobian is not available.

  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_exponents exceeds the system dimension.

  • If method is not “QR” or “QR_HH”.

  • If log_base == 1.

TypeError
  • If method is not a string.

  • If total_time, transient_time, or log_base is not a valid real number.

  • If num_exponents or seed is not an integer.

Notes

By default, the computation uses the custom QR routine based on modified Gram-Schmidt. If method=”QR_HH”, the wrapper passes numpy.linalg.qr to the low-level routine.

CLV(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, num_clvs: int | integer | None = None, transient_time: int | float | integer | floating | None = None, warmup_time: int | float | integer | floating = 0.0, tail_time: int | float | integer | floating = 0.0, qr_time_step: int | float | integer | floating | None = None, seed: int | integer = 13) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]

Compute covariant Lyapunov vectors (CLVs) along a trajectory of this continuous-time dynamical system.

The CLVs form a covariant time-dependent basis of the tangent space. The i-th CLV is associated with the i-th Lyapunov exponent and gives the local expanding or contracting direction.

Parameters

unumeric_like_t

Initial condition. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time over which the CLVs are returned.

parametersnumeric_like_t | None, optional

System parameters. If None, the parameters stored in the instance are used.

num_clvsint_t | None, optional

Number of CLVs to compute. If None, the full set of system_dimension CLVs is computed.

transient_timenumeric_t, optional

Initial integration time discarded before starting the CLV computation.

warmup_timenumeric_t, optional

Forward warmup time used to drive the tangent basis toward the backward Lyapunov vectors.

tail_timenumeric_t, optional

Additional forward integration time after the main storage window, used to initialize the backward recursion.

qr_time_stepnumeric_t | None, optional

Time between successive QR factorizations. If None, the initial integration step size is used.

seedint_t, optional

Seed used to initialize the backward recursion.

Returns

tuple[NDArray[np.float64], NDArray[np.float64]]
  • clvs: array of shape (N + 1, system_dimension, num_clvs)

  • traj: array of shape (N + 1, system_dimension + 1) with time in the first column and state variables in the remaining columns

Raises

ValueError
  • If the Jacobian is not available.

  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If total_time, transient_time, warmup_time, or tail_time is negative.

  • If num_clvs is not in [1, system_dimension].

  • If qr_time_step is not positive when provided.

TypeError
  • If seed is not an integer.

  • If any time-like argument is not a valid real number.

CLV_angles(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, subspaces: tuple[tuple[tuple[int, ...], tuple[int, ...]], ...] | None = None, pairs: tuple[tuple[int, int], ...] | None = None, transient_time: int | float | integer | floating | None = None, warmup_time: int | float | integer | floating = 0, tail_time: int | float | integer | floating = 0, qr_time_step: int | float | integer | floating | None = None, seed: int | integer = 13) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]

Compute CLV-based angle diagnostics for this continuous-time dynamical system.

This method computes CLVs along a trajectory and returns time series of angles between user-specified CLV subspaces and/or CLV direction pairs.

Parameters

unumeric_like_t

Initial condition. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time used for the angle diagnostics.

parametersnumeric_like_t | None, optional

System parameters. If None, the parameters stored in the instance are used.

subspacestuple[tuple[tuple[int, …], tuple[int, …]], …] | None, optional

Requested subspace-angle diagnostics. Each entry is a pair (A, B), where A and B are tuples of CLV indices defining two subspaces.

pairstuple[tuple[int, int], …] | None, optional

Requested pairwise CLV angles. Each entry (i, j) returns the angle between CLV i and CLV j at each sampled time.

transient_timenumeric_t, optional

Initial integration time discarded before starting the diagnostic.

warmup_timenumeric_t, optional

Forward QR warm-up duration passed to the CLV computation.

tail_timenumeric_t, optional

Backward-recursion convergence duration passed to the CLV computation.

qr_time_stepnumeric_t | None, optional

Time spacing between successive QR re-orthonormalizations and CLV samples. If None, the initial integration step size is used.

seedint_t, optional

Seed forwarded to the CLV computation.

Returns

tuple[NDArray[np.float64], NDArray[np.float64]]
  • angles: array of shape (N + 1, M) containing the requested angle time series

  • traj: sampled trajectory array with time in the first column

Raises

ValueError
  • If the Jacobian is not available.

  • If total_time is negative.

  • If transient_time is negative or not smaller than total_time.

  • If warmup_time or tail_time is negative.

  • If both subspaces and pairs are missing or empty.

  • If any CLV subspace or pair specification is invalid.

  • If qr_time_step is not positive when provided.

TypeError
  • If u cannot be interpreted as a valid initial condition.

  • If parameters cannot be interpreted as valid system parameters.

  • If seed is not an integer.

SALI(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, return_history: bool = False, seed: int | integer = 13, threshold: int | float | integer | floating = 1e-16, endpoint: bool = True) ndarray[tuple[int, ...], dtype[float64]][source]

Calculate the Smaller Alignment Index (SALI) for a continuous-time dynamical system.

Parameters

unumeric_like_t

Initial condition of the system. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before computing SALI.

return_historybool, optional

If True, return the time evolution of SALI.

seedint_t, optional

Seed used to initialize the deviation vectors.

thresholdnumeric_t, optional

Early stopping threshold. If SALI becomes smaller than threshold, the computation is terminated.

endpointbool, optional

Whether to include the endpoint time = total_time.

Returns

NDArray[np.float64]
  • If return_history=False, returns an array containing the final time and the final SALI value.

  • If return_history=True, returns the time history of SALI.

Raises

ValueError
  • If the Jacobian is not available.

  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If total_time, transient_time, or threshold is negative.

TypeError
  • If total_time, transient_time, or threshold is not a valid real number.

  • If seed is not an integer.

Examples

>>> from pynamicalsys import ContinuousDynamicalSystem as cds
>>> ds = cds(model="lorenz system")
>>> u0 = [0.1, 0.1, 0.1]
>>> parameters = [16.0, 45.92, 4.0]
>>> ds.SALI(u0, 1000.0, parameters=parameters, transient_time=500.0)
>>> sali_hist = ds.SALI(
...     u0,
...     1000.0,
...     parameters=parameters,
...     transient_time=500.0,
...     return_history=True,
... )
LDI(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, k: int | integer, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, return_history: bool = False, seed: int | integer = 13, threshold: int | float | integer | floating = 1e-16, endpoint: bool = True) ndarray[tuple[int, ...], dtype[float64]][source]

Calculate the Linear Dependence Index (LDI_k) for a continuous-time dynamical system.

Parameters

unumeric_like_t

Initial condition of the system. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time.

kint_t

Number of deviation vectors used in the computation.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before computing LDI.

return_historybool, optional

If True, return the time evolution of LDI.

seedint_t, optional

Seed used to initialize the deviation vectors.

thresholdnumeric_t, optional

Early stopping threshold. If LDI becomes smaller than threshold, the computation is terminated.

endpointbool, optional

Whether to include the endpoint time = total_time.

Returns

NDArray[np.float64]
  • If return_history=False, returns an array containing the final time and the final LDI value.

  • If return_history=True, returns the time history of LDI.

Raises

ValueError
  • If the Jacobian is not available.

  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If total_time, transient_time, or threshold is negative.

  • If k < 2.

  • If k > system_dimension.

TypeError
  • If total_time, transient_time, or threshold is not a valid real number.

  • If k or seed is not an integer.

GALI(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], total_time: int | float | integer | floating, k: int | integer, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, return_history: bool = False, method: str = 'QR', seed: int | integer = 13, threshold: int | float | integer | floating = 1e-16, endpoint: bool = True) ndarray[tuple[int, ...], dtype[float64]][source]

Calculate the Generalized Alignment Index (GALI_k) for a continuous-time dynamical system.

Parameters

unumeric_like_t

Initial condition of the system. It must define a 1D state vector whose length matches the system dimension.

total_timenumeric_t

Total integration time.

kint_t

Number of deviation vectors used in the computation.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before computing GALI.

return_historybool, optional

If True, return the time evolution of GALI.

methodstr, optional

Method used to compute GALI. Supported options are: - “DET” : determinant of the Gram matrix - “QR” : custom QR routine - “QR_HH” : numpy.linalg.qr

seedint_t, optional

Seed used to initialize the deviation vectors.

thresholdnumeric_t, optional

Early stopping threshold. If GALI becomes smaller than threshold, the computation is terminated.

endpointbool, optional

Whether to include the endpoint time = total_time.

Returns

NDArray[np.float64]
  • If return_history=False, returns an array containing the final time and the final GALI value.

  • If return_history=True, returns the time history of GALI.

Raises

ValueError
  • If the Jacobian is not available.

  • If u does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If total_time, transient_time, or threshold is negative.

  • If k < 2.

  • If k > system_dimension.

  • If method is not one of “DET”, “QR”, or “QR_HH”.

TypeError
  • If total_time, transient_time, or threshold is not a valid real number.

  • If k or seed is not an integer.

  • If method is not a string.

recurrence_time_entropy(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], num_intersections: int | integer, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, map_type: str = 'SM', section_index: int | integer | None = None, section_value: int | float | integer | floating | None = None, crossing: int | integer | None = None, sampling_time: int | float | integer | floating | None = None, maxima_index: int | integer | None = None, **kwargs: Any) float | tuple[float, ndarray[tuple[int, ...], dtype[float64]]] | tuple[float, ndarray[tuple[int, ...], dtype[uint8]]] | tuple[float, ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[uint8]]] | tuple[float, ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]] | tuple[float, ndarray[tuple[int, ...], dtype[uint8]], ndarray[tuple[int, ...], dtype[float64]]] | tuple[float, ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[uint8]], ndarray[tuple[int, ...], dtype[float64]]][source]

Compute the recurrence time entropy (RTE) for a continuous-time dynamical system.

Parameters

unumeric_like_t

Initial condition. It must define a 1D state vector whose length matches the system dimension.

num_intersectionsint_t

Number of reduced-map points used in the recurrence analysis.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before generating the reduced map.

map_typestr, optional

Reduced map used to generate the data: - “PS” for Poincaré section - “SM” for stroboscopic map - “MM” for maxima map

section_indexint_t | None, optional

Coordinate index defining the Poincaré section when map_type=”PS”.

section_valuenumeric_t | None, optional

Section value for the Poincaré section when map_type=”PS”.

crossingint_t | None, optional

Crossing orientation for the Poincaré section when map_type=”PS”.

sampling_timenumeric_t | None, optional

Sampling interval for the stroboscopic map when map_type=”SM”.

maxima_indexint_t | None, optional

Index of the state variable whose maxima are used when map_type=”MM”.

**kwargsAny

Additional keyword arguments passed to RTEConfig, including: - metric - std_metric - threshold - threshold_mode - threshold_std - lmin - return_final_state - return_recmat - return_p

Returns

float or tuple

The RTE value, optionally followed by: - the final reduced-map point - the recurrence matrix - the white-vertical-line distribution

Raises

ValueError
  • If the initial condition does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_intersections is negative.

  • If map_type is not one of “PS”, “SM”, or “MM”.

  • If required arguments for the selected map type are missing.

  • If section_index or maxima_index is outside the valid coordinate range.

  • If crossing is not one of -1, 0, or 1.

TypeError
  • If map_type is not a string.

  • If section_value, sampling_time, or transient_time is not a valid real number.

  • If section_index, crossing, maxima_index, or num_intersections is not an integer.

hurst_exponent(u: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]], num_intersections: int | integer, parameters: int | float | integer | floating | Sequence[int | float | integer | floating] | ndarray[tuple[int, ...], dtype[number]] | None = None, transient_time: int | float | integer | floating | None = None, wmin: int | integer = 2, map_type: str = 'SM', section_index: int | integer | None = None, section_value: int | float | integer | floating | None = None, crossing: int | integer | None = None, sampling_time: int | float | integer | floating | None = None, maxima_index: int | integer | None = None) ndarray[tuple[int, ...], dtype[float64]][source]

Estimate the Hurst exponent from a reduced map generated by the continuous-time system.

Parameters

unumeric_like_t

Initial condition. It must define a 1D state vector whose length matches the system dimension.

num_intersectionsint_t

Number of reduced-map points used in the Hurst analysis.

parametersnumeric_like_t | None, optional

Parameters of the system. If None, the parameters stored in the instance are used.

transient_timenumeric_t | None, optional

Initial integration time discarded before generating the reduced map.

wminint_t, optional

Minimum window size used in the rescaled-range calculation.

map_typestr, optional

Reduced map used to generate the data: - “PS” for Poincaré section - “SM” for stroboscopic map - “MM” for maxima map

section_indexint_t | None, optional

Coordinate index defining the Poincaré section when map_type=”PS”.

section_valuenumeric_t | None, optional

Section value for the Poincaré section when map_type=”PS”.

crossingint_t | None, optional

Crossing orientation for the Poincaré section when map_type=”PS”.

sampling_timenumeric_t | None, optional

Sampling interval for the stroboscopic map when map_type=”SM”.

maxima_indexint_t | None, optional

Index of the state variable whose maxima are used when map_type=”MM”.

Returns

NDArray[np.float64]

Estimated Hurst exponent values for the reduced-map coordinates.

Raises

ValueError
  • If the initial condition does not match the system dimension.

  • If the number of parameters does not match the expected number.

  • If num_intersections is negative.

  • If map_type is not one of “PS”, “SM”, or “MM”.

  • If required arguments for the selected map type are missing.

  • If section_index or maxima_index is outside the valid coordinate range.

  • If crossing is not one of -1, 0, or 1.

  • If sampling_time is not positive.

  • If wmin < 2 or wmin >= num_intersections // 2.

TypeError
  • If map_type is not a string.

  • If section_value, sampling_time, or transient_time is not a valid real number.

  • If section_index, crossing, maxima_index, wmin, or num_intersections is not an integer.