.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/ode_dynamics/limit_cycles/plot_02_bendixson_criterion.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_ode_dynamics_limit_cycles_plot_02_bendixson_criterion.py: Bendixson's negative criterion ==================================== If the divergence of a planar vector field keeps one sign on a simply connected region, no closed orbit fits inside it. A damped oscillator passes the test everywhere; the Van der Pol field fails it because its divergence :math:`\mu(1 - x^2)` changes sign at :math:`|x| = 1` -- and indeed its limit cycle must cross those lines. .. GENERATED FROM PYTHON SOURCE LINES 13-22 .. code-block:: Python import matplotlib.pyplot as plt from mathematicskit.ode_dynamics.systems.limit_cycles import VanDerPolOscillator, bendixson_criterion systems = { "damped oscillator": lambda x, y: (y, -x - 0.4 * y), "Van der Pol (mu=1)": lambda x, y: (y, (1.0 - x**2) * y - x), } .. GENERATED FROM PYTHON SOURCE LINES 23-25 Divergence maps --------------------- .. GENERATED FROM PYTHON SOURCE LINES 25-42 .. code-block:: Python fig, axes = plt.subplots(1, 2, figsize=(11, 4.5)) for ax, (name, f) in zip(axes, systems.items()): res = bendixson_criterion(f, (-3, 3), (-3, 3), n=201) lim = max(abs(res.divergence.min()), abs(res.divergence.max())) mesh = ax.pcolormesh(res.X, res.Y, res.divergence, cmap="RdBu_r", vmin=-lim, vmax=lim, shading="auto") fig.colorbar(mesh, ax=ax, label="divergence") ax.set_title(f"{name}: cycles ruled out = {res.rules_out_periodic_orbits}") print(f"{name}: rules out periodic orbits -> {res.rules_out_periodic_orbits}") traj = VanDerPolOscillator([0.5, 0.0], mu=1.0).integrate((0.0, 40.0), dt=1e-3, method="rk4") axes[1].plot(traj.y[:, 0], traj.y[:, 1], "k", lw=1) axes[1].set_xlim(-3, 3) axes[1].set_ylim(-3, 3) fig.tight_layout() plt.show() .. image-sg:: /api/gallery/ode_dynamics/limit_cycles/images/sphx_glr_plot_02_bendixson_criterion_001.png :alt: damped oscillator: cycles ruled out = True, Van der Pol (mu=1): cycles ruled out = False :srcset: /api/gallery/ode_dynamics/limit_cycles/images/sphx_glr_plot_02_bendixson_criterion_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none damped oscillator: rules out periodic orbits -> True Van der Pol (mu=1): rules out periodic orbits -> False .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.103 seconds) .. _sphx_glr_download_api_gallery_ode_dynamics_limit_cycles_plot_02_bendixson_criterion.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_bendixson_criterion.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_bendixson_criterion.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_bendixson_criterion.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_