Conversation
|
Fixes error [ 58s] ==================================== ERRORS ====================================
[ 58s] ___ ERROR at setup of TestTimeresp.test_step_response_siso[siso_ss1-kwargs0] ___
[ 58s] [gw0] linux -- Python 3.10.14 /usr/bin/python3.10
[ 58s]
[ 58s] self = <control.tests.timeresp_test.TestTimeresp object at 0x7fed247aa830>
[ 58s] request = <SubRequest 'tsystem' for <Function test_step_response_siso[siso_ss1-kwargs0]>>
[ 58s]
[ 58s] @pytest.fixture
[ 58s] def tsystem(self, request):
[ 58s] """Define some test systems"""
[ 58s]
[ 58s] """continuous"""
[ 58s] A = np.array([[1., -2.], [3., -4.]])
[ 58s] B = np.array([[5.], [7.]])
[ 58s] C = np.array([[6., 8.]])
[ 58s] D = np.array([[9.]])
[ 58s] siso_ss1 = TSys(StateSpace(A, B, C, D, 0))
[ 58s] siso_ss1.t = np.linspace(0, 1, 10)
[ 58s] siso_ss1.ystep = np.array([9., 17.6457, 24.7072, 30.4855, 35.2234,
[ 58s] 39.1165, 42.3227, 44.9694, 47.1599,
[ 58s] 48.9776])
[ 58s] siso_ss1.X0 = np.array([[.5], [1.]])
[ 58s] siso_ss1.yinitial = np.array([11., 8.1494, 5.9361, 4.2258, 2.9118,
[ 58s] 1.9092, 1.1508, 0.5833, 0.1645, -0.1391])
[ 58s] ss1 = siso_ss1.sys
[ 58s]
[ 58s] """D=0, continuous"""
[ 58s] siso_ss2 = TSys(StateSpace(ss1.A, ss1.B, ss1.C, 0, 0))
[ 58s] siso_ss2.t = siso_ss1.t
[ 58s] siso_ss2.ystep = siso_ss1.ystep - 9
[ 58s] siso_ss2.initial = siso_ss1.yinitial - 9
[ 58s] siso_ss2.yimpulse = np.array([86., 70.1808, 57.3753, 46.9975, 38.5766,
[ 58s] 31.7344, 26.1668, 21.6292, 17.9245,
[ 58s] 14.8945])
[ 58s]
[ 58s] """System with unspecified timebase"""
[ 58s] siso_ss2_dtnone = TSys(StateSpace(ss1.A, ss1.B, ss1.C, 0, None))
[ 58s] siso_ss2_dtnone.t = np.arange(0, 10, 1.)
[ 58s] siso_ss2_dtnone.ystep = np.array([0., 86., -72., 230., -360., 806.,
[ 58s] -1512., 3110., -6120., 12326.])
[ 58s]
[ 58s] siso_tf1 = TSys(TransferFunction([1], [1, 2, 1], 0))
[ 58s]
[ 58s] siso_tf2 = copy(siso_ss1)
[ 58s] siso_tf2.sys = ss2tf(siso_ss1.sys)
[ 58s]
[ 58s] """MIMO system, contains ``siso_ss1`` twice"""
[ 58s] mimo_ss1 = copy(siso_ss1)
[ 58s] A = np.zeros((4, 4))
[ 58s] A[:2, :2] = siso_ss1.sys.A
[ 58s] A[2:, 2:] = siso_ss1.sys.A
[ 58s] B = np.zeros((4, 2))
[ 58s] B[:2, :1] = siso_ss1.sys.B
[ 58s] B[2:, 1:] = siso_ss1.sys.B
[ 58s] C = np.zeros((2, 4))
[ 58s] C[:1, :2] = siso_ss1.sys.C
[ 58s] C[1:, 2:] = siso_ss1.sys.C
[ 58s] D = np.zeros((2, 2))
[ 58s] D[:1, :1] = siso_ss1.sys.D
[ 58s] D[1:, 1:] = siso_ss1.sys.D
[ 58s] mimo_ss1.sys = StateSpace(A, B, C, D)
[ 58s]
[ 58s] """MIMO system, contains ``siso_ss2`` twice"""
[ 58s] mimo_ss2 = copy(siso_ss2)
[ 58s] A = np.zeros((4, 4))
[ 58s] A[:2, :2] = siso_ss2.sys.A
[ 58s] A[2:, 2:] = siso_ss2.sys.A
[ 58s] B = np.zeros((4, 2))
[ 58s] B[:2, :1] = siso_ss2.sys.B
[ 58s] B[2:, 1:] = siso_ss2.sys.B
[ 58s] C = np.zeros((2, 4))
[ 58s] C[:1, :2] = siso_ss2.sys.C
[ 58s] C[1:, 2:] = siso_ss2.sys.C
[ 58s] D = np.zeros((2, 2))
[ 58s] mimo_ss2.sys = StateSpace(A, B, C, D, 0)
[ 58s]
[ 58s] """discrete"""
[ 58s] siso_dtf0 = TSys(TransferFunction([1.], [1., 0.], 1.))
[ 58s] siso_dtf0.t = np.arange(4)
[ 58s] siso_dtf0.yimpulse = [0., 1., 0., 0.]
[ 58s]
[ 58s] siso_dtf1 = TSys(TransferFunction([1], [1, 1, 0.25], True))
[ 58s] siso_dtf1.t = np.arange(0, 5, 1)
[ 58s] siso_dtf1.ystep = np.array([0. , 0. , 1. , 0. , 0.75])
[ 58s]
[ 58s] siso_dtf2 = TSys(TransferFunction([1], [1, 1, 0.25], 0.2))
[ 58s] siso_dtf2.t = np.arange(0, 5, 0.2)
[ 58s] siso_dtf2.ystep = np.array(
[ 58s] [0. , 0. , 1. , 0. , 0.75 , 0.25 ,
[ 58s] 0.5625, 0.375 , 0.4844, 0.4219, 0.457 , 0.4375,
[ 58s] 0.4482, 0.4424, 0.4456, 0.4438, 0.4448, 0.4443,
[ 58s] 0.4445, 0.4444, 0.4445, 0.4444, 0.4445, 0.4444,
[ 58s] 0.4444])
[ 58s]
[ 58s] """Time step which leads to rounding errors for time vector length"""
[ 58s] num = [-0.10966442, 0.12431949]
[ 58s] den = [1., -1.86789511, 0.88255018]
[ 58s] dt = 0.12493963338370018
[ 58s] siso_dtf3 = TSys(TransferFunction(num, den, dt))
[ 58s] siso_dtf3.t = np.linspace(0, 9*dt, 10)
[ 58s] siso_dtf3.ystep = np.array(
[ 58s] [ 0. , -0.1097, -0.1902, -0.2438, -0.2729,
[ 58s] -0.2799, -0.2674, -0.2377, -0.1934, -0.1368])
[ 58s]
[ 58s] """dtf1 converted statically, because Slycot and Scipy produce
[ 58s] different realizations, wich means different initial condtions,"""
[ 58s] siso_dss1 = copy(siso_dtf1)
[ 58s] siso_dss1.sys = StateSpace([[-1., -0.25],
[ 58s] [ 1., 0.]],
[ 58s] [[1.],
[ 58s] [0.]],
[ 58s] [[0., 1.]],
[ 58s] [[0.]],
[ 58s] True)
[ 58s] siso_dss1.X0 = [0.5, 1.]
[ 58s] siso_dss1.yinitial = np.array([1., 0.5, -0.75, 0.625, -0.4375])
[ 58s]
[ 58s] siso_dss2 = copy(siso_dtf2)
[ 58s] siso_dss2.sys = tf2ss(siso_dtf2.sys)
[ 58s]
[ 58s] mimo_dss1 = TSys(StateSpace(ss1.A, ss1.B, ss1.C, ss1.D, True))
[ 58s] mimo_dss1.t = np.arange(0, 5, 0.2)
[ 58s]
[ 58s] mimo_dss2 = copy(mimo_ss1)
[ 58s] mimo_dss2.sys = c2d(mimo_ss1.sys, mimo_ss1.t[1]-mimo_ss1.t[0])
[ 58s]
[ 58s] mimo_tf2 = copy(mimo_ss2)
[ 58s] tf_ = ss2tf(siso_ss2.sys)
[ 58s] mimo_tf2.sys = TransferFunction(
[ 58s] [[tf_.num[0][0], [0]], [[0], tf_.num[0][0]]],
[ 58s] [[tf_.den[0][0], [1]], [[1], tf_.den[0][0]]],
[ 58s] 0)
[ 58s]
[ 58s] mimo_dtf1 = copy(siso_dtf1)
[ 58s] tf_ = siso_dtf1.sys
[ 58s] mimo_dtf1.sys = TransferFunction(
[ 58s] [[tf_.num[0][0], [0]], [[0], tf_.num[0][0]]],
[ 58s] [[tf_.den[0][0], [1]], [[1], tf_.den[0][0]]],
[ 58s] True)
[ 58s]
[ 58s] # for pole cancellation tests
[ 58s] pole_cancellation = TSys(TransferFunction(
[ 58s] [1.067e+05, 5.791e+04],
[ 58s] [10.67, 1.067e+05, 5.791e+04]))
[ 58s]
[ 58s] no_pole_cancellation = TSys(TransferFunction(
[ 58s] [1.881e+06],
[ 58s] [188.1, 1.881e+06]))
[ 58s]
[ 58s] # System Type 1 - Step response not stationary: G(s)=1/s(s+1)
[ 58s] siso_tf_type1 = TSys(TransferFunction(1, [1, 1, 0]))
[ 58s] siso_tf_type1.step_info = {
[ 58s] > 'RiseTime': np.NaN,
[ 58s] 'SettlingTime': np.NaN,
[ 58s] 'SettlingMin': np.NaN,
[ 58s] 'SettlingMax': np.NaN,
[ 58s] 'Overshoot': np.NaN,
[ 58s] 'Undershoot': np.NaN,
[ 58s] 'Peak': np.Inf,
[ 58s] 'PeakTime': np.Inf,
[ 58s] 'SteadyStateValue': np.NaN}
[ 58s]
[ 58s] control/tests/timeresp_test.py:176:
[ 58s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[ 58s]
[ 58s] attr = 'NaN'
[ 58s]
[ 58s] def __getattr__(attr):
[ 58s] # Warn for expired attributes
[ 58s] import warnings
[ 58s]
[ 58s] if attr == "linalg":
[ 58s] import numpy.linalg as linalg
[ 58s] return linalg
[ 58s] elif attr == "fft":
[ 58s] import numpy.fft as fft
[ 58s] return fft
[ 58s] elif attr == "dtypes":
[ 58s] import numpy.dtypes as dtypes
[ 58s] return dtypes
[ 58s] elif attr == "random":
[ 58s] import numpy.random as random
[ 58s] return random
[ 58s] elif attr == "polynomial":
[ 58s] import numpy.polynomial as polynomial
[ 58s] return polynomial
[ 58s] elif attr == "ma":
[ 58s] import numpy.ma as ma
[ 58s] return ma
[ 58s] elif attr == "ctypeslib":
[ 58s] import numpy.ctypeslib as ctypeslib
[ 58s] return ctypeslib
[ 58s] elif attr == "exceptions":
[ 58s] import numpy.exceptions as exceptions
[ 58s] return exceptions
[ 58s] elif attr == "testing":
[ 58s] import numpy.testing as testing
[ 58s] return testing
[ 58s] elif attr == "matlib":
[ 58s] import numpy.matlib as matlib
[ 58s] return matlib
[ 58s] elif attr == "f2py":
[ 58s] import numpy.f2py as f2py
[ 58s] return f2py
[ 58s] elif attr == "typing":
[ 58s] import numpy.typing as typing
[ 58s] return typing
[ 58s] elif attr == "rec":
[ 58s] import numpy.rec as rec
[ 58s] return rec
[ 58s] elif attr == "char":
[ 58s] import numpy.char as char
[ 58s] return char
[ 58s] elif attr == "array_api":
[ 58s] raise AttributeError("`numpy.array_api` is not available from "
[ 58s] "numpy 2.0 onwards")
[ 58s] elif attr == "core":
[ 58s] import numpy.core as core
[ 58s] return core
[ 58s] elif attr == "strings":
[ 58s] import numpy.strings as strings
[ 58s] return strings
[ 58s] elif attr == "distutils":
[ 58s] if 'distutils' in __numpy_submodules__:
[ 58s] import numpy.distutils as distutils
[ 58s] return distutils
[ 58s] else:
[ 58s] raise AttributeError("`numpy.distutils` is not available from "
[ 58s] "Python 3.12 onwards")
[ 58s]
[ 58s] if attr in __future_scalars__:
[ 58s] # And future warnings for those that will change, but also give
[ 58s] # the AttributeError
[ 58s] warnings.warn(
[ 58s] f"In the future `np.{attr}` will be defined as the "
[ 58s] "corresponding NumPy scalar.", FutureWarning, stacklevel=2)
[ 58s]
[ 58s] if attr in __former_attrs__:
[ 58s] raise AttributeError(__former_attrs__[attr])
[ 58s]
[ 58s] if attr in __expired_attributes__:
[ 58s] > raise AttributeError(
[ 58s] f"`np.{attr}` was removed in the NumPy 2.0 release. "
[ 58s] f"{__expired_attributes__[attr]}"
[ 58s] )
[ 58s] E AttributeError: `np.NaN` was removed in the NumPy 2.0 release. Use `np.nan` instead.. Did you mean: 'nan'?
[ 58s]
[ 58s] /usr/lib64/python3.10/site-packages/numpy/__init__.py:397: AttributeError |
|
We don't have a CI job with numpy 2.0.0rc1 set up and I don't think we need to, but tests are executed here: |
|
These changes look good to me. @bnavigator Any reason to wait before merging? If not, I'll merge in a day or so. |
|
No reason to wait. Thanks for the review. I suggest releasing a 0.10.1 soon, so that our users don't get caught by surprise after the numpy 2 release. |
slivingston
left a comment
There was a problem hiding this comment.
For posterity, I verified these changes with the migration guide at https://numpy.org/devdocs/numpy_2_0_migration_guide.html and https://numpy.org/devdocs/release/2.0.0-notes.html#numpy-linalg-linalg-made-private.
https://build.opensuse.org/request/show/1169382 by user bnavigator + anag+factory - Add control-pr994-numpy2.patch gh#python-control/python-control#994 (forwarded request 1169381 from bnavigator)
Numpy 2.0.0rc1 is out and a release is coming soon.