From 2dac8b8071015ad1c00253d49586a52b6d5e8c44 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 28 Dec 2020 14:27:12 -0800 Subject: [PATCH 1/2] updated parsing for use_legacy_defaults --- control/config.py | 54 +++++++++++++++++++++++++++--------- control/tests/config_test.py | 16 ++++++++++- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/control/config.py b/control/config.py index 21840231b..ad9ffb235 100644 --- a/control/config.py +++ b/control/config.py @@ -171,17 +171,45 @@ def use_legacy_defaults(version): Parameters ---------- version : string - version number of the defaults desired. ranges from '0.1' to '0.8.4'. + Version number of the defaults desired. Ranges from '0.1' to '0.8.4'. """ - numbers_list = version.split(".") - first_digit = int(numbers_list[0]) - second_digit = int(numbers_list[1].strip('abcdef')) # remove trailing letters - if second_digit < 8: - # TODO: anything for 0.7 and below if needed - pass - elif second_digit == 8: - if len(version) > 4: - third_digit = int(version[4]) - use_numpy_matrix(True) # alternatively: set_defaults('statesp', use_numpy_matrix=True) - else: - raise ValueError('''version number not recognized. Possible values range from '0.1' to '0.8.4'.''') + import re + (major, minor, patch) = (None, None, None) # default values + + # Early release tag format: REL-0.N + match = re.match("REL-0.([12])", version) + if match: (major, minor, patch) = (0, int(match.group(1)), 0) + + # Early release tag format: control-0.Np + match = re.match("control-0.([3-6])([a-d])", version) + if match: (major, minor, patch) = \ + (0, int(match.group(1)), ord(match.group(2)) - ord('a') + 1) + + # Early release tag format: v0.Np + match = re.match("[vV]?0.([3-6])([a-d])", version) + if match: (major, minor, patch) = \ + (0, int(match.group(1)), ord(match.group(2)) - ord('a') + 1) + + # Abbreviated version format: vM.N or M.N + match = re.match("([vV]?[0-9]).([0-9])", version) + if match: (major, minor, patch) = \ + (int(match.group(1)), int(match.group(2)), 0) + + # Standard version format: vM.N.P or M.N.P + match = re.match("[vV]?([0-9]).([0-9]).([0-9])", version) + if match: (major, minor, patch) = \ + (int(match.group(1)), int(match.group(2)), int(match.group(3))) + + # Make sure we found match + if major is None or minor is None: + raise ValueError("Version number not recognized. Try M.N.P format.") + + # + # Go backwards through releases and reset defaults + # + + # Version 0.9.0: switched to 'array' as default for state space objects + if major == 0 and minor < 9: + set_defaults('statesp', use_numpy_matrix=True) + + return (major, minor, patch) diff --git a/control/tests/config_test.py b/control/tests/config_test.py index 667a7e3c4..a8e86d1ff 100644 --- a/control/tests/config_test.py +++ b/control/tests/config_test.py @@ -214,14 +214,28 @@ def test_reset_defaults(self): def test_legacy_defaults(self): ct.use_legacy_defaults('0.8.3') assert(isinstance(ct.ss(0,0,0,1).D, np.matrix)) + ct.reset_defaults() assert(isinstance(ct.ss(0,0,0,1).D, np.ndarray)) + assert(not isinstance(ct.ss(0,0,0,1).D, np.matrix)) + + ct.use_legacy_defaults('0.9.0') + assert(isinstance(ct.ss(0,0,0,1).D, np.ndarray)) + assert(not isinstance(ct.ss(0,0,0,1).D, np.matrix)) + # test that old versions don't raise a problem + ct.use_legacy_defaults('REL-0.1') + ct.use_legacy_defaults('control-0.3a') ct.use_legacy_defaults('0.6c') ct.use_legacy_defaults('0.8.2') ct.use_legacy_defaults('0.1') + + # Make sure that nonsense versions generate an error + self.assertRaises(ValueError, ct.use_legacy_defaults, "a.b.c") + self.assertRaises(ValueError, ct.use_legacy_defaults, "1.x.3") + + # Leave everything like we found it ct.config.reset_defaults() - def test_change_default_dt(self): ct.set_defaults('statesp', default_dt=0) From 2849413798b394467fbe47dd70bbbfa2a2790fa1 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 28 Dec 2020 14:27:48 -0800 Subject: [PATCH 2/2] change statesp to use ndarray by default --- control/statesp.py | 2 +- control/tests/{modelsimp_test.py => modelsimp_matrix_test.py} | 0 control/tests/{robust_test.py => robust_matrix_test.py} | 0 control/tests/{statefbk_test.py => statefbk_matrix_test.py} | 0 control/tests/{statesp_test.py => statesp_matrix_test.py} | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename control/tests/{modelsimp_test.py => modelsimp_matrix_test.py} (100%) rename control/tests/{robust_test.py => robust_matrix_test.py} (100%) rename control/tests/{statefbk_test.py => statefbk_matrix_test.py} (100%) rename control/tests/{statesp_test.py => statesp_matrix_test.py} (100%) diff --git a/control/statesp.py b/control/statesp.py index dd0ea6f5e..5af916bf0 100644 --- a/control/statesp.py +++ b/control/statesp.py @@ -70,7 +70,7 @@ # Define module default parameter values _statesp_defaults = { - 'statesp.use_numpy_matrix': True, + 'statesp.use_numpy_matrix': False, # False is default in 0.9.0 and above 'statesp.default_dt': None, 'statesp.remove_useless_states': True, } diff --git a/control/tests/modelsimp_test.py b/control/tests/modelsimp_matrix_test.py similarity index 100% rename from control/tests/modelsimp_test.py rename to control/tests/modelsimp_matrix_test.py diff --git a/control/tests/robust_test.py b/control/tests/robust_matrix_test.py similarity index 100% rename from control/tests/robust_test.py rename to control/tests/robust_matrix_test.py diff --git a/control/tests/statefbk_test.py b/control/tests/statefbk_matrix_test.py similarity index 100% rename from control/tests/statefbk_test.py rename to control/tests/statefbk_matrix_test.py diff --git a/control/tests/statesp_test.py b/control/tests/statesp_matrix_test.py similarity index 100% rename from control/tests/statesp_test.py rename to control/tests/statesp_matrix_test.py