chaotic_pfc.dynamics.maps

maps.py

Hénon map variants used as chaotic oscillators throughout the communication system.

Four Henon map variants and one chaotic-sequence generator are provided:

  • henon_standard() — the original Hénon (1976) map,

    \[\begin{split}x[n+1] &= 1 - a \, x[n]^2 + y[n] \\ y[n+1] &= b \, x[n]\end{split}\]

    chaotic at (a, b) = (1.4, 0.3).

  • henon_generalised() — the parametric form preferred in communications literature,

    \[\begin{split}x_1[n+1] &= \alpha - x_1[n]^2 + \beta \, x_2[n] \\ x_2[n+1] &= x_1[n]\end{split}\]

    equivalent to henon_standard() with rescaled variables.

  • henon_filtered() — generalised Hénon whose nonlinear input is a weighted combination of two consecutive state samples:

    \[\begin{split}x_1[n+1] &= \alpha - (c_0 \, x_1[n] + c_1 \, x_2[n])^2 + \beta \, x_2[n] \\ x_2[n+1] &= x_1[n]\end{split}\]

    This is the 2-tap case of the general filtered map.

  • henon_order_n() — general case with an FIR filter of arbitrary order acting on the system’s state vector. Used by the higher-order transmitter/receiver pair and by the Lyapunov sweep.

  • henon_fir_sequence() — generates a chaotic sequence from the FIR-filtered Hénon map.

Functions

henon_filtered(steps[, x0, y0, alpha, beta, ...])

Iterate the 2-tap filtered Hénon map.

henon_fir_sequence(N[, a, b, n_taps, wc, window])

Generate a chaotic sequence from the FIR-filtered Hénon map.

henon_generalised(steps[, x0, y0, alpha, beta])

Iterate the generalised 2-D Hénon map.

henon_order_n(steps, *, fir_coeffs[, x0, a, ...])

Iterate the N-th order Hénon map with an internal FIR filter.

henon_standard(steps[, x0, y0, a, b])

Iterate the standard 2-D Hénon map.

chaotic_pfc.dynamics.maps.henon_standard(steps, x0=0.0, y0=0.0, a=1.4, b=0.3)[source]

Iterate the standard 2-D Hénon map.

Parameters:
  • steps (int) – Number of iterations. Each output array has length steps + 1 (initial condition included).

  • x0 (float) – Initial conditions of the two state variables.

  • y0 (float) – Initial conditions of the two state variables.

  • a (float) – Hénon parameters. The canonical chaotic regime is (a, b) = (1.4, 0.3); smaller a yields periodic orbits, larger a yields unbounded trajectories for most ICs.

  • b (float) – Hénon parameters. The canonical chaotic regime is (a, b) = (1.4, 0.3); smaller a yields periodic orbits, larger a yields unbounded trajectories for most ICs.

Returns:

X, Y – Trajectories of x and y from n = 0 (the initial condition) to n = steps.

Return type:

ndarray, shape (steps + 1,)

chaotic_pfc.dynamics.maps.henon_generalised(steps, x0=0.0, y0=0.0, alpha=1.4, beta=0.3)[source]

Iterate the generalised 2-D Hénon map.

Mathematically equivalent to henon_standard() under a change of variables, but parameterised using α and β because that is the form used in the theoretical derivations of the project.

Parameters:
  • steps (int) – Number of iterations.

  • x0 (float) – Initial conditions of the state variables.

  • y0 (float) – Initial conditions of the state variables.

  • alpha (float) – Hénon parameters. Chaotic regime at (α, β) = (1.4, 0.3).

  • beta (float) – Hénon parameters. Chaotic regime at (α, β) = (1.4, 0.3).

Returns:

X, Y – Trajectories of x_1 and x_2.

Return type:

ndarray, shape (steps + 1,)

chaotic_pfc.dynamics.maps.henon_filtered(steps, x0=0.0, y0=0.0, alpha=1.4, beta=0.3, c0=0.7, c1=0.3)[source]

Iterate the 2-tap filtered Hénon map.

The quadratic nonlinearity acts on a weighted combination of the two most recent state samples, z = c_0 · x_1 + c_1 · x_2, rather than on a single sample. This is the smallest non-trivial case of henon_order_n().

Parameters:
  • steps (int) – Number of iterations.

  • x0 (float) – Initial conditions of the state variables.

  • y0 (float) – Initial conditions of the state variables.

  • alpha (float) – Hénon parameters.

  • beta (float) – Hénon parameters.

  • c0 (float) – FIR filter coefficients. With (c0, c1) = (1, 0) the map reduces exactly to henon_generalised() — this equivalence is exercised by TestHenonFiltered in the test suite.

  • c1 (float) – FIR filter coefficients. With (c0, c1) = (1, 0) the map reduces exactly to henon_generalised() — this equivalence is exercised by TestHenonFiltered in the test suite.

Returns:

X, Y – Trajectories of x_1 and x_2.

Return type:

ndarray, shape (steps + 1,)

chaotic_pfc.dynamics.maps.henon_order_n(steps, *, fir_coeffs, x0=None, a=1.4, b=0.3, driving=None, seed=None)[source]

Iterate the N-th order Hénon map with an internal FIR filter.

The system dimension N_c is inferred from len(fir_coeffs). At each step, the carrier output is the filtered state component x[2], and the next iterate is computed by _henon_n4_step_inplace().

The driving parameter lets callers override the nonlinear input: when driving=None the map runs autonomously (s = x[2]); when driving is provided the map is forced by that external signal. This is used by the transmitter (self-driven) vs. the receiver (driven by the received signal).

Parameters:
  • steps (int) – Number of iterations. The output state has shape (Nc, steps + 1).

  • fir_coeffs (ndarray[tuple[Any, ...], dtype[_ScalarT]]) – FIR filter coefficients, shape (Nc,). Must have Nc >= 3.

  • x0 (ndarray[tuple[Any, ...], dtype[_ScalarT]] | None) – Optional explicit initial state, shape (Nc,). If None, a random state is drawn from Uniform(0, 0.5) per component.

  • a (float) – Hénon parameters.

  • b (float) – Hénon parameters.

  • driving (ndarray[tuple[Any, ...], dtype[_ScalarT]] | None) – Optional external driving signal, shape (steps,). When provided, replaces the self-driving term at each iteration.

  • seed (int | None) – RNG seed used when x0=None to pick the random initial condition. Has no effect if x0 is provided.

Returns:

  • state (ndarray, shape (Nc, steps + 1)) – Full state trajectory. Column 0 is the initial condition.

  • output (ndarray, shape (steps,)) – Carrier signal x[2][n] for n = 0, …, steps 1.

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

chaotic_pfc.dynamics.maps.henon_fir_sequence(N, a=1.4, b=0.3, n_taps=5, wc=0.9091, window='hamming')[source]

Generate a chaotic sequence from the FIR-filtered Hénon map.

Iterates the generalised Hénon form x[n+1] = a - xf[n]^2 + b * y[n], y[n+1] = x[n], where xf is the current output of an FIR filter applied to the state history.

Parameters:
  • N (int) – Number of samples to produce.

  • a (float) – Hénon map parameters (default: 1.4, 0.3).

  • b (float) – Hénon map parameters (default: 1.4, 0.3).

  • n_taps (int) – FIR filter order (number of coefficients).

  • wc (float) – Normalised cutoff frequency in (0, 1).

  • window (str) – SciPy window name (e.g. "hamming", "kaiser").

Returns:

Chaotic samples.

Return type:

ndarray, shape (N,)

Raises:
  • ValueError – If the trajectory diverges (|x| > 100) or produces NaN/Inf.

  • .. deprecated: – 0.8.0: This function is no longer used internally. For filtered chaotic sequences, prefer henon_order_n() with pre-computed FIR coefficients.