8000 return_y -> return_outputs + related updates · python-control/python-control@1a2770c · GitHub
[go: up one dir, main page]

Skip to content

Commit 1a2770c

Browse files
committed
return_y -> return_outputs + related updates
1 parent aed5706 commit 1a2770c

File tree

4 files changed

+65
-19
lines changed

4 files changed

+65
-19
lines changed

control/nlsys.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,14 +1694,14 @@ class OperatingPoint(object):
16941694
"""
16951695
def __init__(
16961696
self, states, inputs=None, outputs=None, result=None,
1697-
return_y=False, return_result=False):
1697+
return_outputs=False, return_result=False):
16981698
self.states = states
16991699
self.inputs = inputs
17001700

1701-
if outputs is None and return_y and not return_result:
1702-
raise SystemError("return_y specified by no y0 value")
1701+
if outputs is None and return_outputs and not return_result:
1702+
raise SystemError("return_outputs specified by no y0 value")
17031703
self.outputs = outputs
1704-
self.return_y = return_y
1704+
self.return_outputs = return_outputs
17051705

17061706
if result is None and return_result:
17071707
raise SystemError("return_result specified by no result value")
@@ -1710,9 +1710,9 @@ def __init__(
17101710

17111711
# Implement iter to allow assigning to a tuple
17121712
def __iter__(self):
1713-
if self.return_y and self.return_result:
1713+
if self.return_outputs and self.return_result:
17141714
return iter((self.states, self.inputs, self.outputs, self.result))
1715-
elif self.return_y:
1715+
elif self.return_outputs:
17161716
return iter((self.states, self.inputs, self.outputs))
17171717
elif self.return_result:
17181718
return iter((self.states, self.inputs, self.result))
@@ -1729,9 +1729,9 @@ def __len__(self):
17291729

17301730

17311731
def find_operating_point(
1732-
sys, x0, u0=None, y0=None, t=0, params=None,
1733-
iu=None, iy=None, ix=None, idx=None, dx0=None, root_method=None,
1734-
root_kwargs=None, return_y=False, return_result=False):
1732+
sys, x0, u0=None, y0=None, t=0, params=None, iu=None, iy=None,
1733+
ix=None, idx=None, dx0=None, root_method=None, root_kwargs=None,
1734+
return_outputs=None, return_result=None, **kwargs):
17351735
"""Find an operating point for an input/output system.
17361736
17371737
An operating point for a nonlinear system is a state and input around
@@ -1804,8 +1804,8 @@ def find_operating_point(
18041804
is passed to the :func:`scipy.optimize.root` function.
18051805
root_kwargs : dict, optional
18061806
Additional keyword arguments to pass :func:`scipy.optimize.root`.
1807-
return_y : bool, optional
1808-
If True, return the value of output at the operating point.
1807+
return_outputs : bool, optional
1808+
If True, return the value of outputs at the operating point.
18091809
return_result : bool, optional
18101810
If True, return the `result` option from the
18111811
:func:`scipy.optimize.root` function used to compute the
@@ -1820,8 +1820,8 @@ def find_operating_point(
18201820
:class:`OperatingPoint` for a description of other attributes.
18211821
18221822
If accessed as a tuple, returns `states`, `inputs`, and optionally
1823-
`outputs` and `result` based on the `return_y` and `return_result`
1824-
parameters.
1823+
`outputs` and `result` based on the `return_outputs` and
1824+
`return_result` parameters.
18251825
18261826
Notes
18271827
-----
@@ -1844,6 +1844,12 @@ def find_operating_point(
18441844
"""
18451845
from scipy.optimize import root
18461846

1847+
# Process keyword arguments
1848+
return_outputs = config._process_legacy_keyword(
1849+
kwargs, 'return_y', 'return_outputs', return_outputs)
1850+
if kwargs:
1851+
raise TypeError("unrecognized keyword(s): " + str(kwargs))
1852+
18471853
# Process arguments for the root function
18481854
root_kwargs = dict() if root_kwargs is None else root_kwargs
18491855
if root_method:
@@ -2019,14 +2025,14 @@ def rootfun(z):
20192025
# Return the result based on what the user wants and what we found
20202026
if return_result or result.success:
20212027
return OperatingPoint(
2022-
z[0], z[1], z[2], result, return_y, return_result)
2028+
z[0], z[1], z[2], result, return_outputs, return_result)
20232029
else:
20242030
# Something went wrong, don't return anything
20252031
return OperatingPoint(
2026-
None, None, None, result, return_y, return_result)
2032+
None, None, None, result, return_outputs, return_result)
20272033

20282034
# TODO: remove code when ready
2029-
if not return_y:
2035+
if not return_outputs:
20302036
z = z[0:2] # Strip y from result if not desired
20312037
if return_result:
20322038
# Return whatever we got, along with the result dictionary
@@ -2036,7 +2042,7 @@ def rootfun(z):
20362042
return z
20372043
else:
20382044
# Something went wrong, don't return anything
2039-
return (None, None, None) if return_y else (None, None)
2045+
return (None, None, None) if return_outputs else (None, None)
20402046

20412047

20422048
# Linearize an input/output system

control/tests/docstrings_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
control.create_estimator_iosystem: ['state_labels'], # deprecated
5454
control.bode_plot: ['sharex', 'sharey', 'margin_info'], # deprecated
5555
control.eigensys_realization: ['arg'], # quasi-positional
56+
control.find_operating_point: ['method'], # internal use
5657
}
5758

5859
# Decide on the level of verbosity (use -rP when running pytest)

control/tests/iosys_test.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010

1111
import re
1212
import warnings
13-
import pytest
13+
from math import sqrt
1414

1515
import numpy as np
16-
from math import sqrt
16+
import pytest
17+
import scipy
1718

1819
import control as ct
1920

@@ -2088,6 +2089,7 @@ def test_find_eqpt(x0, ix, u0, iu, y0, iy, dx0, idx, dt, x_expect, u_expect):
20882089

20892090

20902091
# Test out new operating point version of find_eqpt
2092+
# TODO: add return_)y tests
20912093
def test_find_operating_point():
20922094
dt = 1
20932095
sys = ct.NonlinearIOSystem(
@@ -2122,6 +2124,10 @@ def test_find_operating_point():
21222124
assert op_point.inputs is not None
21232125
assert op_point.result.success is False
21242126

2127+
# Check to make sure unknown keywords are caught
2128+
with pytest.raises(TypeError, match="unrecognized keyword"):
2129+
ct.find_operating_point(sys, x0, u0, unknown=None)
2130+
21252131

21262132
def test_operating_point():
21272133
dt = 1
@@ -2146,6 +2152,36 @@ def test_operating_point():
21462152
op_point = ct.find_operating_point(
21472153
sys, 0, 0, root_method='lm', root_kwargs={'tol': 1e-6})
21482154

2155+
# Make sure we can get back the right arguments in a tuple
2156+
op_point = ct.find_operating_point(sys, 0, 0, return_outputs=True)
2157+
assert len(op_point) == 3
2158+
assert isinstance(op_point[0], np.ndarray)
2159+
assert isinstance(op_point[1], np.ndarray)
2160+
assert isinstance(op_point[2], np.ndarray)
2161+
2162+
with pytest.warns(FutureWarning, match="return_outputs"):
2163+
op_point = ct.find_operating_point(sys, 0, 0, return_y=True)
2164+
assert len(op_point) == 3
2165+
assert isinstance(op_point[0], np.ndarray)
2166+
assert isinstance(op_point[1], np.ndarray)
2167+
assert isinstance(op_point[2], np.ndarray)
2168+
2169+
# Make sure we can get back the right arguments in a tuple
2170+
op_point = ct.find_operating_point(sys, 0, 0, return_result=True)
2171+
assert len(op_point) == 3
2172+
assert isinstance(op_point[0], np.ndarray)
2173+
assert isinstance(op_point[1], np.ndarray)
2174+
assert isinstance(op_point[2], scipy.optimize.OptimizeResult)
2175+
2176+
# Make sure we can get back the right arguments in a tuple
2177+
op_point = ct.find_operating_point(
2178+
sys, 0, 0, return_result=True, return_outputs=True)
2179+
assert len(op_point) == 4
2180+
assert isinstance(op_point[0], np.ndarray)
2181+
assert isinstance(op_point[1], np.ndarray)
2182+
assert isinstance(op_point[2], np.ndarray)
2183+
assert isinstance(op_point[3], scipy.optimize.OptimizeResult)
2184+
21492185

21502186
def test_iosys_sample():
21512187
csys = ct.rss(2, 1, 1)

control/tests/kwargs_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import control.tests.frd_test as frd_test
2525
import control.tests.freqplot_test as freqplot_test
2626
import control.tests.interconnect_test as interconnect_test
27+
import control.tests.iosys_test as iosys_test
2728
import control.tests.optimal_test as optimal_test
2829
import control.tests.statefbk_test as statefbk_test
2930
import control.tests.stochsys_test as stochsys_test
@@ -252,6 +253,8 @@ def test_response_plot_kwargs(data_fcn, plot_fcn, mimo):
252253
'dlqr': test_unrecognized_kwargs,
253254
'drss': test_unrecognized_kwargs,
254255
'feedback': test_unrecognized_kwargs,
256+
'find_eqpt': iosys_test.test_find_operating_point,
257+
'find_operating_point': iosys_test.test_find_operating_point,
255258
'flatsys.flatsys': test_unrecognized_kwargs,
256259
'frd': frd_test.TestFRD.test_unrecognized_keyword,
257260
'gangof4': test_matplotlib_kwargs,

0 commit comments

Comments
 (0)
0