From 6fcf7419e7b30148a8e7a287ee6790a2806cbaf0 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Tue, 28 Jan 2025 16:28:23 -0800 Subject: [PATCH 1/2] turn off warn_infinite for phase_crossover_frequencies() calculation --- control/margins.py | 13 +++++++++---- control/tests/margin_test.py | 13 +++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/control/margins.py b/control/margins.py index 301baaf57..019c866be 100644 --- a/control/margins.py +++ b/control/margins.py @@ -81,11 +81,16 @@ def _poly_iw_sqr(pol_iw): def _poly_iw_real_crossing(num_iw, den_iw, epsw): # Return w where imag(H(iw)) == 0 + + # Compute the imaginary part of H = (num.r + j num.i)/(den.r + j den.i) test_w = np.polysub(np.polymul(num_iw.imag, den_iw.real), np.polymul(num_iw.real, den_iw.imag)) + + # Find the real-valued w > 0 where imag(H(iw)) = 0 w = np.roots(test_w) w = np.real(w[np.isreal(w)]) w = w[w >= epsw] + return w @@ -471,7 +476,7 @@ def phase_crossover_frequencies(sys): omega : ndarray 1d array of (non-negative) frequencies where Nyquist plot intersects the real axis - gain : ndarray + gains : ndarray 1d array of corresponding gains Examples @@ -493,13 +498,13 @@ def phase_crossover_frequencies(sys): omega = _poly_iw_real_crossing(num_iw, den_iw, 0.) # using real() to avoid rounding errors and results like 1+0j - gain = np.real(evalfr(sys, 1J * omega)) + gains = np.real(sys(omega * 1j, warn_infinite=False)) else: zargs = _poly_z_invz(sys) z, omega = _poly_z_real_crossing(*zargs, epsw=0.) - gain = np.real(evalfr(sys, z)) + gains = np.real(sys(z, warn_infinite=False)) - return omega, gain + return omega, gains def margin(*args): diff --git a/control/tests/margin_test.py b/control/tests/margin_test.py index 07e21114f..115475dd3 100644 --- a/control/tests/margin_test.py +++ b/control/tests/margin_test.py @@ -12,12 +12,11 @@ from numpy import inf, nan from numpy.testing import assert_allclose -from control.frdata import FrequencyResponseData -from control.margins import (margin, phase_crossover_frequencies, - stability_margins) -from control.statesp import StateSpace -from control.xferfcn import TransferFunction -from control.exception import ControlMIMONotImplemented +from ..frdata import FrequencyResponseData +from ..margins import margin, phase_crossover_frequencies, stability_margins +from ..statesp import StateSpace +from ..xferfcn import TransferFunction +from ..exception import ControlMIMONotImplemented s = TransferFunction.s @@ -119,6 +118,8 @@ def test_margin_3input(tsys): (([2], [1, 3, 3, 1]), [1.732, 0.], [-0.25, 2.]), ((np.array([3, 11, 3]) * 1e-4, [1., -2.7145, 2.4562, -0.7408], .1), [1.6235, 0.], [-0.28598, 1.88889]), + (([200.0], [1.0, 21.0, 20.0, 0.0]), + [4.47213595, 0], [-0.47619048, inf]), ]) def test_phase_crossover_frequencies(tfargs, omega_ref, gain_ref): """Test phase_crossover_frequencies() function""" From d9e44d20da53b9d4cf83d1ffe7475eac21d2316f Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Wed, 29 Jan 2025 21:57:01 -0800 Subject: [PATCH 2/2] address @slivingston review comments --- control/tests/margin_test.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/control/tests/margin_test.py b/control/tests/margin_test.py index 115475dd3..43cd68ae3 100644 --- a/control/tests/margin_test.py +++ b/control/tests/margin_test.py @@ -12,11 +12,9 @@ from numpy import inf, nan from numpy.testing import assert_allclose -from ..frdata import FrequencyResponseData -from ..margins import margin, phase_crossover_frequencies, stability_margins -from ..statesp import StateSpace -from ..xferfcn import TransferFunction -from ..exception import ControlMIMONotImplemented +from control import ControlMIMONotImplemented, FrequencyResponseData, \ + StateSpace, TransferFunction, margin, phase_crossover_frequencies, \ + stability_margins s = TransferFunction.s @@ -110,7 +108,6 @@ def test_margin_3input(tsys): out = margin((mag, phase*180/np.pi, omega_)) assert_allclose(out, np.array(refout)[[0, 1, 3, 4]], atol=1.5e-3) - @pytest.mark.parametrize( 'tfargs, omega_ref, gain_ref', [(([1], [1, 2, 3, 4]), [1.7325, 0.], [-0.5, 0.25]), @@ -121,6 +118,7 @@ def test_margin_3input(tsys): (([200.0], [1.0, 21.0, 20.0, 0.0]), [4.47213595, 0], [-0.47619048, inf]), ]) +@pytest.mark.filterwarnings("error") def test_phase_crossover_frequencies(tfargs, omega_ref, gain_ref): """Test phase_crossover_frequencies() function""" sys = TransferFunction(*tfargs) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy