.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/control_systems/stability/plot_02_routh_stability_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 or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_control_systems_stability_plot_02_routh_stability_criterion.py: Routh's stability criterion =========================== Maxwell could not state a test for polynomials above fourth order. Edward Routh's Adams Prize essay (1877) solved the problem with a table built from the coefficients alone: the number of sign changes down its first column (:func:`~engineeringkit.control_systems.routh_first_column`) equals the number of roots in the right half-plane. For the closed loop of :math:`K/(s(s+1)(s+2))`, :math:`s^3 + 3s^2 + 2s + K`, the table shows the loop is stable only for :math:`0 < K < 6`. .. GENERATED FROM PYTHON SOURCE LINES 15-20 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from engineeringkit.control_systems import routh_first_column, routh_stable .. GENERATED FROM PYTHON SOURCE LINES 21-23 Sign changes count right-half-plane roots ----------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 23-36 .. code-block:: Python gains = np.linspace(0.05, 15.05, 151) # avoids the marginal K = 6 changes, unstable_roots = [], [] for K in gains: column = routh_first_column([1, 3, 2, K]) changes.append(int(np.sum(np.diff(np.sign(column)) != 0))) unstable_roots.append(int(np.sum(np.roots([1, 3, 2, K]).real > 0))) assert changes == unstable_roots assert all(routh_stable([1, 3, 2, K]) == (K < 6) for K in gains) for K in [2.0, 10.0]: print(f"K = {K:4.1f}: first column {np.round(routh_first_column([1, 3, 2, K]), 3)}") .. rst-class:: sphx-glr-script-out .. code-block:: none K = 2.0: first column [1. 3. 1.333 2. ] K = 10.0: first column [ 1. 3. -1.333 10. ] .. GENERATED FROM PYTHON SOURCE LINES 37-39 A fifth-order example --------------------- .. GENERATED FROM PYTHON SOURCE LINES 39-53 .. code-block:: Python p = np.poly([-1, -2, 0.5 + 1j, 0.5 - 1j, -3]).real column = routh_first_column(p) print("fifth order:", np.round(column, 3), "->", int(np.sum(np.diff(np.sign(column)) != 0)), "sign changes") assert int(np.sum(np.diff(np.sign(column)) != 0)) == 2 fig, ax = plt.subplots() ax.step(gains, changes, where="mid", label="Routh sign changes") ax.plot(gains, unstable_roots, "o", ms=3, mfc="none", label="right-half-plane roots") ax.axvline(6, color="C3", ls="--", lw=0.8) ax.set(xlabel="loop gain $K$", ylabel="count", title="$s^3 + 3s^2 + 2s + K$") ax.legend() plt.show() .. image-sg:: /api/gallery/control_systems/stability/images/sphx_glr_plot_02_routh_stability_criterion_001.png :alt: $s^3 + 3s^2 + 2s + K$ :srcset: /api/gallery/control_systems/stability/images/sphx_glr_plot_02_routh_stability_criterion_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none fifth order: [ 1. 5. 5.75 -2.935 20.944 7.5 ] -> 2 sign changes .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.119 seconds) .. _sphx_glr_download_api_gallery_control_systems_stability_plot_02_routh_stability_criterion.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/control_systems/stability/plot_02_routh_stability_criterion.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_routh_stability_criterion.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_routh_stability_criterion.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_routh_stability_criterion.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_