diff --git a/688.patch b/688.patch deleted file mode 100644 index 7a2ab27..0000000 --- a/688.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 58d8cd6e4fe77fd5a18f91c791532e3e259b1949 Mon Sep 17 00:00:00 2001 -From: Ben Greiner -Date: Tue, 4 Jan 2022 20:09:23 +0100 -Subject: [PATCH 1/4] round to nearest integer for default omega - ---- - control/freqplot.py | 16 +++++++--------- - control/tests/sisotool_test.py | 4 ++-- - 2 files changed, 9 insertions(+), 11 deletions(-) - -diff --git a/control/freqplot.py b/control/freqplot.py -index 881ec93d..7225afe9 100644 ---- a/control/freqplot.py -+++ b/control/freqplot.py -@@ -1326,7 +1326,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None, - features_ = np.concatenate((np.abs(sys.pole()), - np.abs(sys.zero()))) - # Get rid of poles and zeros at the origin -- toreplace = features_ == 0.0 -+ toreplace = np.isclose(features_, 0.0) - if np.any(toreplace): - features_ = features_[~toreplace] - elif sys.isdtime(strict=True): -@@ -1339,7 +1339,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None, - # Get rid of poles and zeros on the real axis (imag==0) - # * origin and real < 0 - # * at 1.: would result in omega=0. (logaritmic plot!) -- toreplace = (features_.imag == 0.0) & ( -+ toreplace = np.isclose(features_.imag, 0.0) & ( - (features_.real <= 0.) | - (np.abs(features_.real - 1.0) < 1.e-10)) - if np.any(toreplace): -@@ -1360,15 +1360,13 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None, - - if Hz: - features /= 2. * math.pi -- features = np.log10(features) -- lsp_min = np.floor(np.min(features) - feature_periphery_decades) -- lsp_max = np.ceil(np.max(features) + feature_periphery_decades) -+ features = np.log10(features) -+ lsp_min = np.rint(np.min(features) - feature_periphery_decades) -+ lsp_max = np.rint(np.max(features) + feature_periphery_decades) -+ if Hz: - lsp_min += np.log10(2. * math.pi) - lsp_max += np.log10(2. * math.pi) -- else: -- features = np.log10(features) -- lsp_min = np.floor(np.min(features) - feature_periphery_decades) -- lsp_max = np.ceil(np.max(features) + feature_periphery_decades) -+ - if freq_interesting: - lsp_min = min(lsp_min, np.log10(min(freq_interesting))) - lsp_max = max(lsp_max, np.log10(max(freq_interesting))) -diff --git a/control/tests/sisotool_test.py b/control/tests/sisotool_test.py -index 6b8c6d14..d5e9dd01 100644 ---- a/control/tests/sisotool_test.py -+++ b/control/tests/sisotool_test.py -@@ -102,8 +102,8 @@ def test_sisotool(self, tsys): - - # Check if the bode_mag line has moved - bode_mag_moved = np.array( -- [674.0242, 667.8354, 661.7033, 655.6275, 649.6074, 643.6426, -- 637.7324, 631.8765, 626.0742, 620.3252]) -+ [69.0065, 68.6749, 68.3448, 68.0161, 67.6889, 67.3631, 67.0388, -+ 66.7159, 66.3944, 66.0743]) - assert_array_almost_equal(ax_mag.lines[0].get_data()[1][10:20], - bode_mag_moved, 4) - - -From 19801e6deac560e72ee9593f81be2d24e8df14e6 Mon Sep 17 00:00:00 2001 -From: Ben Greiner -Date: Tue, 4 Jan 2022 21:07:35 +0100 -Subject: [PATCH 2/4] split up nyquist indent tests - ---- - control/tests/nyquist_test.py | 36 ++++++++++++++++++++++++----------- - 1 file changed, 25 insertions(+), 11 deletions(-) - -diff --git a/control/tests/nyquist_test.py b/control/tests/nyquist_test.py -index 4667c621..c77d94c8 100644 ---- a/control/tests/nyquist_test.py -+++ b/control/tests/nyquist_test.py -@@ -182,42 +182,56 @@ def test_nyquist_encirclements(): - assert _Z(sys) == count + _P(sys) - - --def test_nyquist_indent(): -+@pytest.fixture -+def indentsys(): - # FBS Figure 10.10 -- s = ct.tf('s') -- sys = 3 * (s+6)**2 / (s * (s+1)**2) - # poles: [-1, -1, 0] -+ s = ct.tf('s') -+ return 3 * (s+6)**2 / (s * (s+1)**2) - -+ -+def test_nyquist_indent_default(indentsys): - plt.figure(); -- count = ct.nyquist_plot(sys) -+ count = ct.nyquist_plot(indentsys) - plt.title("Pole at origin; indent_radius=default") -- assert _Z(sys) == count + _P(sys) -+ assert _Z(indentsys) == count + _P(indentsys) - -+ -+def test_nyquist_indent_dont(indentsys): - # first value of default omega vector was 0.1, replaced by 0. for contour - # indent_radius is larger than 0.1 -> no extra quater circle around origin -- count, contour = ct.nyquist_plot(sys, plot=False, indent_radius=.1007, -+ count, contour = ct.nyquist_plot(indentsys, -+ plot=False, -+ indent_radius=.1007, - return_contour=True) - np.testing.assert_allclose(contour[0], .1007+0.j) - # second value of omega_vector is larger than indent_radius: not indented - assert np.all(contour.real[2:] == 0.) - -+ -+def test_nyquist_indent_do(indentsys): - plt.figure(); -- count, contour = ct.nyquist_plot(sys, indent_radius=0.01, -+ count, contour = ct.nyquist_plot(indentsys, -+ indent_radius=0.01, - return_contour=True) - plt.title("Pole at origin; indent_radius=0.01; encirclements = %d" % count) -- assert _Z(sys) == count + _P(sys) -+ assert _Z(indentsys) == count + _P(indentsys) - # indent radius is smaller than the start of the default omega vector - # check that a quarter circle around the pole at origin has been added. - np.testing.assert_allclose(contour[:50].real**2 + contour[:50].imag**2, - 0.01**2) - -+ -+def test_nyquist_indent_left(indentsys): - plt.figure(); -- count = ct.nyquist_plot(sys, indent_direction='left') -+ count = ct.nyquist_plot(indentsys, indent_direction='left') - plt.title( - "Pole at origin; indent_direction='left'; encirclements = %d" % count) -- assert _Z(sys) == count + _P(sys, indent='left') -+ assert _Z(indentsys) == count + _P(indentsys, indent='left') -+ - -- # System with poles on the imaginary axis -+def test_nyquist_indent_im(): -+ """Test system with poles on the imaginary axis.""" - sys = ct.tf([1, 1], [1, 0, 1]) - - # Imaginary poles with standard indentation - -From c44b901d3af030187d4c2c75dbee75f2bedcf29a Mon Sep 17 00:00:00 2001 -From: Ben Greiner -Date: Tue, 4 Jan 2022 21:08:06 +0100 -Subject: [PATCH 3/4] passthrough Hz parameter for omega vector - ---- - control/freqplot.py | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - -diff --git a/control/freqplot.py b/control/freqplot.py -index 7225afe9..18b9a448 100644 ---- a/control/freqplot.py -+++ b/control/freqplot.py -@@ -209,7 +209,7 @@ def bode_plot(syslist, omega=None, - syslist = (syslist,) - - omega, omega_range_given = _determine_omega_vector( -- syslist, omega, omega_limits, omega_num) -+ syslist, omega, omega_limits, omega_num, Hz=Hz) - - if plot: - # Set up the axes with labels so that multiple calls to -@@ -965,7 +965,7 @@ def gangof4_plot(P, C, omega=None, **kwargs): - # Select a default range if none is provided - # TODO: This needs to be made more intelligent - if omega is None: -- omega = _default_frequency_range((P, C, S)) -+ omega = _default_frequency_range((P, C, S), Hz=Hz) - - # Set up the axes with labels so that multiple calls to - # gangof4_plot will superimpose the data. See details in bode_plot. -@@ -1115,7 +1115,7 @@ def singular_values_plot(syslist, omega=None, - syslist = (syslist,) - - omega, omega_range_given = _determine_omega_vector( -- syslist, omega, omega_limits, omega_num) -+ syslist, omega, omega_limits, omega_num, Hz=Hz) - - omega = np.atleast_1d(omega) - -@@ -1210,7 +1210,8 @@ def singular_values_plot(syslist, omega=None, - - - # Determine the frequency range to be used --def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num): -+def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num, -+ Hz=None): - """Determine the frequency range for a frequency-domain plot - according to a standard logic. - -@@ -1236,6 +1237,10 @@ def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num): - omega_num : int - Number of points to be used for the frequency - range (if the frequency range is not user-specified) -+ Hz : bool. optional -+ If True, the limits (first and last value) of the frequencies -+ are set to full decades in Hz so it fits plotting with logarithmic -+ scale in Hz otherwise in rad/s. Omega is always returned in rad/sec. - - Returns - ------- -@@ -1253,7 +1258,8 @@ def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num): - omega_range_given = False - # Select a default range if none is provided - omega_out = _default_frequency_range(syslist, -- number_of_samples=omega_num) -+ number_of_samples=omega_num, -+ Hz=Hz) - else: - omega_limits = np.asarray(omega_limits) - if len(omega_limits) != 2: -@@ -1280,7 +1286,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None, - ---------- - syslist : list of LTI - List of linear input/output systems (single system is OK) -- Hz : bool -+ Hz : bool. optional - If True, the limits (first and last value) of the frequencies - are set to full decades in Hz so it fits plotting with logarithmic - scale in Hz otherwise in rad/s. Omega is always returned in rad/sec. - -From 021372f4cd821907fee913ceef6d46af899a9bcd Mon Sep 17 00:00:00 2001 -From: Ben Greiner -Date: Tue, 4 Jan 2022 21:37:10 +0100 -Subject: [PATCH 4/4] docstring punctuation - ---- - control/freqplot.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/control/freqplot.py b/control/freqplot.py -index 18b9a448..a8324e06 100644 ---- a/control/freqplot.py -+++ b/control/freqplot.py -@@ -1237,7 +1237,7 @@ def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num, - omega_num : int - Number of points to be used for the frequency - range (if the frequency range is not user-specified) -- Hz : bool. optional -+ Hz : bool, optional - If True, the limits (first and last value) of the frequencies - are set to full decades in Hz so it fits plotting with logarithmic - scale in Hz otherwise in rad/s. Omega is always returned in rad/sec. -@@ -1286,7 +1286,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None, - ---------- - syslist : list of LTI - List of linear input/output systems (single system is OK) -- Hz : bool. optional -+ Hz : bool, optional - If True, the limits (first and last value) of the frequencies - are set to full decades in Hz so it fits plotting with logarithmic - scale in Hz otherwise in rad/s. Omega is always returned in rad/sec. diff --git a/control-0.9.1.tar.gz b/control-0.9.1.tar.gz deleted file mode 100644 index dd301db..0000000 --- a/control-0.9.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c9084bf386eafcf5d74008f780fae6dec68d243d18a380c866ac10a3549f8d3 -size 357890 diff --git a/control-0.9.2.tar.gz b/control-0.9.2.tar.gz new file mode 100644 index 0000000..8c84774 --- /dev/null +++ b/control-0.9.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0891d2d32d6006ac1faa4e238ed8223ca342a4721d202dfeccae24fb02563183 +size 398165 diff --git a/python-control.changes b/python-control.changes index cc2cc60..fa21994 100644 --- a/python-control.changes +++ b/python-control.changes @@ -1,3 +1,29 @@ +------------------------------------------------------------------- +Sun May 29 10:07:56 UTC 2022 - Ben Greiner + +- Update to 0.9.2 + * Improvements in I/O systems, stochastic systems, + optimization-based control, Nyquist plots + * Round to nearest integer decade for default omega vector by + @bnavigator in #688 + * Fix in documentation of ss2tf by @miroslavfikar in #695 + * Interpret str-type args to interconnect as non-sequence by + @roryyorke in #698 + * Fixes to various optimization-based control functions by + @murrayrm in #709 + * I/O system enhancements by @murrayrm in #710 + * Optimal control enhancements by @murrayrm in #712 + * Keyword argument checking by @murrayrm in #713 + * Stochastic systems additions by @murrayrm in #714 + * Updated system class functionality by @murrayrm in #721 + * Bug fix and improvements to Nyquist plots by @murrayrm in #722 + * Add linform to compute linear system L-infinity norm by + @roryyorke in #729 + * Improvements to Nichols chart plotting by @roryyorke in #723 + * Add envs to gitignore by @s35t in #731 + * Fix README.rst for twine by @murrayrm in #738 +- Drop 688.patch fixed upstream + ------------------------------------------------------------------- Sat Feb 12 18:42:24 UTC 2022 - Ben Greiner diff --git a/python-control.spec b/python-control.spec index 45754bd..60f23ad 100644 --- a/python-control.spec +++ b/python-control.spec @@ -18,15 +18,13 @@ %define skip_python2 1 Name: python-control -Version: 0.9.1 +Version: 0.9.2 Release: 0 Summary: Python control systems library License: BSD-3-Clause -URL: http://python-control.org +URL: https://python-control.org Source: https://files.pythonhosted.org/packages/source/c/control/control-%{version}.tar.gz Source1: %{name}-rpmlintrc -# PATCH-FIX-UPSTREAM - https://github.com/python-control/python-control/pull/688 -Patch1: 688.patch BuildRequires: %{python_module base >= 3.7} BuildRequires: %{python_module setuptools} BuildRequires: fdupes @@ -71,10 +69,8 @@ export MPLBACKEND="Qt5Agg" # preload malloc library to avoid free() error on i586 architecture if [[ $(getconf LONG_BIT) == 32 ]]; then export LD_PRELOAD="%{_libdir}/libjemalloc.so.2" -# segfault on i586 (?) -donttest=" or test_nichols" fi -%pytest -k "not (ifanything $donttest)" +%pytest %files %{python_files} %doc ChangeLog README.rst