.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/complex_analysis/residues/plot_05_rouche_theorem.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 or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_complex_analysis_residues_plot_05_rouche_theorem.py: Rouché's theorem: counting zeros by domination ============================================== Eugène Rouché (1862): if :math:`|g| < |f|` on a closed contour, then :math:`f` and :math:`f + g` have the same number of zeros inside it. Picture :math:`f(\gamma)` as a person walking around a lamppost at 0 and :math:`g` as the leash to a dog at :math:`f + g`: a leash shorter than the distance to the post means the dog circles it the same number of times. Here :math:`z^5 + 3z + 1` has all five zeros in :math:`|z| < 2` (dominated by :math:`z^5`) and exactly one in :math:`|z| < 1` (dominated by :math:`3z`). .. GENERATED FROM PYTHON SOURCE LINES 16-28 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from mathematicskit.complex_analysis import argument_principle, circle_contour def h(z): return z**5 + 3 * z + 1 roots = np.roots([1, 0, 0, 0, 3, 1]) .. GENERATED FROM PYTHON SOURCE LINES 29-31 Two contours, two dominant terms -------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 31-52 .. code-block:: Python fig, axes = plt.subplots(1, 2, figsize=(11, 5)) for ax, (R, f, name) in zip(axes, [(2.0, lambda z: z**5, "z^5"), (1.0, lambda z: 3 * z, "3z")], strict=False): contour = circle_contour(0.0, R) z = contour.points(2000) g = h(z) - f(z) print(f"|z| = {R}: min |{name}| = {np.min(np.abs(f(z))):.2f} > max |rest| = {np.max(np.abs(g)):.2f}") print( f" zeros of {name}: {argument_principle(f, contour)}, zeros of z^5+3z+1: {argument_principle(h, contour)}, " f"numpy.roots inside: {int(np.sum(np.abs(roots) < R))}" ) ax.plot(f(z).real, f(z).imag, lw=1, label=f"walker: {name}") ax.plot(h(z).real, h(z).imag, lw=1, label="dog: z^5 + 3z + 1") ax.plot(0, 0, "k*", ms=12, label="lamppost 0") ax.set_aspect("equal") ax.set_title(f"|z| = {R}") ax.legend(fontsize=8) fig.suptitle("Rouché's theorem as dog walking") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/complex_analysis/residues/images/sphx_glr_plot_05_rouche_theorem_001.png :alt: Rouché's theorem as dog walking, |z| = 2.0, |z| = 1.0 :srcset: /api/gallery/complex_analysis/residues/images/sphx_glr_plot_05_rouche_theorem_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none |z| = 2.0: min |z^5| = 32.00 > max |rest| = 7.00 zeros of z^5: 5, zeros of z^5+3z+1: 5, numpy.roots inside: 5 |z| = 1.0: min |3z| = 3.00 > max |rest| = 2.00 zeros of 3z: 1, zeros of z^5+3z+1: 1, numpy.roots inside: 1 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.250 seconds) .. _sphx_glr_download_api_gallery_complex_analysis_residues_plot_05_rouche_theorem.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/complex_analysis/residues/plot_05_rouche_theorem.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_05_rouche_theorem.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_05_rouche_theorem.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_05_rouche_theorem.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_