-
Notifications
You must be signed in to change notification settings - Fork 438
Support NumPy 2 #994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support NumPy 2 #994
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: https://build.opensuse.org/package/show/home:bnavigator:numpy/python-control |
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.