Accepting request 979682 from devel:languages:python:numeric
- 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 (forwarded request 979680 from bnavigator)
OBS-URL: https://build.opensuse.org/request/show/979682
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-control?expand=0&rev=16
This commit is contained in:
263
688.patch
263
688.patch
@@ -1,263 +0,0 @@
|
||||
From 58d8cd6e4fe77fd5a18f91c791532e3e259b1949 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Greiner <code@bnavigator.de>
|
||||
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 <code@bnavigator.de>
|
||||
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 <code@bnavigator.de>
|
||||
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 <code@bnavigator.de>
|
||||
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.
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8c9084bf386eafcf5d74008f780fae6dec68d243d18a380c866ac10a3549f8d3
|
||||
size 357890
|
||||
3
control-0.9.2.tar.gz
Normal file
3
control-0.9.2.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0891d2d32d6006ac1faa4e238ed8223ca342a4721d202dfeccae24fb02563183
|
||||
size 398165
|
||||
@@ -1,3 +1,29 @@
|
||||
-------------------------------------------------------------------
|
||||
Sun May 29 10:07:56 UTC 2022 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
- 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 <code@bnavigator.de>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user