.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/chaos/chaos_metrics/plot_recurrence.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_chaos_chaos_metrics_plot_recurrence.py: Poincare Recurrence and Kac's Lemma ======================================= The Poincare recurrence theorem guarantees that, for a measure-preserving system, almost every trajectory returns arbitrarily close to its starting point infinitely often. A trajectory's recurrence structure is captured by the pairwise recurrence matrix .. math:: R_{ij} = \begin{cases} 1 & \|\mathbf{x}_i - \mathbf{x}_j\| < \epsilon \\ 0 & \text{otherwise} \end{cases} Kac's lemma sharpens the recurrence theorem into a quantitative statement: the *mean* time :math:`\langle \tau \rangle` between returns to a region :math:`A` equals the reciprocal of that region's invariant measure :math:`\mu(A)`, :math:`\langle \tau \rangle \approx 1/\mu(A)`. This example visualizes recurrence structure with the classic "recurrence plot" (an image of :math:`R_{ij}`) for the Lorenz attractor, :math:`\dot{x}=\sigma(y-x)`, :math:`\dot{y}=x(\rho-z)-y`, :math:`\dot{z}=xy-\beta z`, then numerically validates Kac's lemma on the Henon map's attractor, :math:`x_{n+1}=1-ax_n^2+y_n`, :math:`y_{n+1}=bx_n`. .. GENERATED FROM PYTHON SOURCE LINES 25-34 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from physicskit.chaos.systems.continuous import Lorenz from physicskit.chaos.systems.maps import HenonMap from physicskit.chaos.utils.recurrence import kac_lemma_estimate from physicskit.chaos.visualizers.recurrence import plot_recurrence_matrix, plot_recurrence_times .. GENERATED FROM PYTHON SOURCE LINES 35-42 Recurrence plot --------------- A recurrence plot marks ``(i, j)`` black whenever states `i` and `j` are within `epsilon` of each other. The diagonal lines and textured blocks visible here reflect the Lorenz attractor's structure: near-diagonal bands are the smooth short-time dynamics, while the broader checkerboard pattern reflects the trajectory's switching between the attractor's two lobes. .. GENERATED FROM PYTHON SOURCE LINES 42-47 .. code-block:: Python lorenz = Lorenz() _, states = lorenz.trajectory(n_steps=1500, dt=0.05) fig, ax = plot_recurrence_matrix(states, epsilon=3.0) .. image-sg:: /api/gallery/chaos/chaos_metrics/images/sphx_glr_plot_recurrence_001.png :alt: Recurrence plot ($\epsilon$ = 3) :srcset: /api/gallery/chaos/chaos_metrics/images/sphx_glr_plot_recurrence_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 48-55 Recurrence-time distribution -------------------------------- For a chaotic map, the distribution of times between successive returns to a small neighborhood is itself informative -- and its *mean* is exactly what Kac's lemma predicts. This example uses the Henon map, whose returns are quick to sample well (its attractor is chaotic but not fractally stretched across wildly different length scales the way Lorenz's is). .. GENERATED FROM PYTHON SOURCE LINES 55-61 .. code-block:: Python henon = HenonMap(a=1.4, b=0.3) traj = henon.trajectory(np.array([0.1, 0.1]), n_iter=100000) traj = traj[500:] # discard transient fig2, ax2 = plot_recurrence_times(traj, epsilon=0.05, reference_idx=0) .. image-sg:: /api/gallery/chaos/chaos_metrics/images/sphx_glr_plot_recurrence_002.png :alt: Recurrence-time distribution ($\epsilon$ = 0.05) :srcset: /api/gallery/chaos/chaos_metrics/images/sphx_glr_plot_recurrence_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 62-65 Validating Kac's lemma -------------------------- ``mean_recurrence_time * measure(epsilon-ball)`` should be close to 1. .. GENERATED FROM PYTHON SOURCE LINES 65-71 .. code-block:: Python mean_time, measure, kac_product = kac_lemma_estimate(traj, epsilon=0.05, reference_idx=0) print(f"mean recurrence time: {mean_time:.2f} iterations") print(f"measure of the epsilon-ball: {measure:.5f}") print(f"Kac's lemma product (should be close to 1): {kac_product:.4f}") plt.show() .. rst-class:: sphx-glr-script-out .. code-block:: none mean recurrence time: 43.06 iterations measure of the epsilon-ball: 0.02321 Kac's lemma product (should be close to 1): 0.9993 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.142 seconds) .. _sphx_glr_download_api_gallery_chaos_chaos_metrics_plot_recurrence.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_recurrence.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_recurrence.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_recurrence.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_