Working examples#

The examples/ directory of the repository contains one script per model below. They are not part of the installed package; run them from a clone of the repository:

git clone https://github.com/Yuu-Miino/mappy.git
cd mappy
uv sync --all-extras          # or: pip install -e ".[plot]"
uv run python examples/henon.py --help

Each script takes a --mode option selecting what to do; --help lists the choices. Typically:

  • an interactive mode (the default) opens plot2d() (needs a display);

  • a non-interactive mode iterates the map and saves a figure (works headless, e.g. with MPLBACKEND=Agg);

  • trace runs the numerical analysis — periodic points, their continuation, local bifurcations and bifurcation curves — and prints the results.

For example:

uv run python examples/duffing.py --mode trace

The mode graphs below are written as in Concept of modes; the mode names used inside the scripts may differ.

Hénon map#

examples/henon.py. The classic two-dimensional map

\[x_{k+1} = 1 - a x_k^2 + y_k, \qquad y_{k+1} = b x_k,\]

with \(a = 1.4\), \(b = 0.3\) (the Hénon attractor). It is discrete from the start, so the whole system is one discrete mode wrapped in a Diffeomorphism.

Mode graph:

map ──▶ map

The interactive plot shows only the image points (only_map=True); a and b can be changed with the keyboard. Two further modes sweep \(a \in [1, 1.42]\): --mode bifurcation draws the one-parameter bifurcation diagram of \(x\), and --mode mle the maximum Lyapunov exponent by Benettin’s method — a unit tangent vector is pushed forward by res.jac at every iteration and renormalised — which is positive exactly in the chaotic windows of the diagram.

Izhikevich neuron#

examples/izhikevich.py. The spiking neuron of the tutorial:

\[\dot v = 0.04 v^2 + 5 v + 140 - u + I, \qquad \dot u = a (b v - u), \qquad v = 30 \;\Rightarrow\; (v, u) \leftarrow (c, u + d),\]

with \(a = 0.2\), \(b = 0.2\), \(c = -50\), \(d = 2\), \(I = 10\). The Poincaré section is the firing threshold \(v = 30\), parametrised by \(u\), so the Poincaré map is one-dimensional.

Mode graph:

Pinv (R → R²) ──▶ B (jump) ──▶ A (flow) ──[v = 30]──▶ P (R² → R) ──▶ Pinv

The analysis follows the fixed point as \(I\) decreases, finds the period-doubling bifurcation (\(I \approx 4.5869\) at \(a = 0.2\)) and traces it in the \((a, I)\) plane — see Periodic points, bifurcations, continuation.

Forced Duffing oscillator#

examples/duffing.py. A periodically forced Duffing equation

\[\dot x = y, \qquad \dot y = -k y - x^3 + B_0 + B \cos t,\]

with \(k = 0.2\), \(B_0 = 0.1\), \(B = 0.1\). Time is added as a third state variable, \(\dot t = 1\), so that the system is autonomous; the stroboscopic Poincaré map samples \((x, y)\) once per forcing period \(2\pi\). The forcing must be written with sympy.cos (see Jacobian and Hessian tensor).

Mode graph:

p (R² → R³) ──▶ duffing ──[t = 2π]──▶ t_reset ──▶ pinv (R³ → R²) ──▶ p
  • p lifts \((x, y)\) to \((x, y, 0)\);

  • duffing integrates until the border \(t - 2\pi = 0\);

  • t_reset subtracts \(2\pi\) from \(t\);

  • pinv projects back onto \((x, y)\).

The trace mode follows the fixed point along \(B\) and locates period-doubling bifurcations (the first at \(B \approx 0.17169\) for \(k = 0.2\), \(B_0 = 0.1\)), then continues one of them in the \((B, B_0)\) plane. --mode bifurcation draws the one-parameter bifurcation diagram of \(x\) on the section over \(B \in [0.1, 0.375]\); the 1-periodic point is unstable between the two period doublings.

Forced Alpazur oscillator#

examples/forced_alpazur.py. A piecewise-smooth oscillator whose nonlinear element switches between two characteristics with hysteresis, under periodic forcing:

\[\dot v_1 = -k v_1 - v_2 + V_0 + V \cos \omega t, \qquad \dot v_2 = v_1 + (1 - g_i) v_2 - \frac{v_2^3}{3} + B_i, \qquad \dot t = 1,\]

where \(i \in \{1, 2\}\) is the active region. The system switches from region 1 to region 2 when \(v_2\) falls through \(-1\), and from region 2 back to region 1 when \(v_2\) rises through \(-0.1\). The example uses \(k = 0.1\), \(g_1 = 0.2\), \(g_2 = 2\), \(B_1 = 1.3\), \(B_2 = 5\), \(V_0 = 0\), \(V = 2.4\), \(\omega = 1.26\).

Mode graph (two continuous modes with two borders each — a switching border and the stroboscopic border \(t = 2\pi/\omega\)):

p1    ──▶ alp_1
alp_1 ──[border 0: v2 = -1, falling]───▶ alp_2
alp_1 ──[border 1: t = 2π/ω]───────────▶ pr1 ──▶ pinv1 ──▶ p1   (end)
p2    ──▶ alp_2
alp_2 ──[border 0: v2 = -0.1, rising]──▶ alp_1
alp_2 ──[border 1: t = 2π/ω]───────────▶ pr2 ──▶ pinv2 ──▶ p2   (end)

Because the state on the section may be in either region, the section has two pieces and the map has two end modes; mode_history records the switchings that happened within each period. Trajectories are coloured by region with per-mode LineStyle dictionaries (see Plotting). See Concept of modes for a detailed description of this mode graph.

Three-dimensional coupled logistic map#

examples/logistic_3d.py. Three cyclically coupled logistic maps

\[\begin{split}\begin{aligned} x_{k+1} &= \alpha x_k (1 - x_k) + \beta y_k^2 x_k + \gamma z_k^3, \\ y_{k+1} &= \alpha y_k (1 - y_k) + \beta z_k^2 y_k + \gamma x_k^3, \\ z_{k+1} &= \alpha z_k (1 - z_k) + \beta x_k^2 z_k + \gamma y_k^3, \end{aligned}\end{split}\]

a Diffeomorphism on \(\R^3\) (mode graph map ──▶ map). The example starts at \(\alpha = 2.7\), \(\beta = -1\), \(\gamma = 0.0146\), finds a fixed point, continues it in \(\alpha\), locates a period-doubling bifurcation (theta = np.pi) and traces it in the \((\beta, \alpha)\) plane. The interactive mode plots a two-dimensional projection of the orbit.