Merge pull request #1019 from murrayrm/nlsys_improvements-24May2024 · python-control/python-control@6406868
@@ -54,17 +54,19 @@
5454"""
55555656from functools import reduce
57-import numpy as np
5857from warnings import warn
59-from . import xferfcn as tf
60-from . import statesp as ss
58+59+import numpy as np
60+6161from . import frdata as frd
62+from . import statesp as ss
63+from . import xferfcn as tf
6264from .iosys import InputOutputSystem
63656466__all__ = ['series', 'parallel', 'negate', 'feedback', 'append', 'connect']
6567666867-def series(sys1, *sysn):
69+def series(sys1, *sysn, **kwargs):
6870r"""series(sys1, sys2, [..., sysn])
69717072 Return the series connection (`sysn` \* ...\ \*) `sys2` \* `sys1`.
@@ -79,6 +81,20 @@ def series(sys1, *sysn):
7981 out : scalar, array, or :class:`InputOutputSystem`
8082 Series interconnection of the systems.
818384+ Other Parameters
85+ ----------------
86+ inputs, outputs : str, or list of str, optional
87+ List of strings that name the individual signals. If not given,
88+ signal names will be of the form `s[i]` (where `s` is one of `u`,
89+ or `y`). See :class:`InputOutputSystem` for more information.
90+ states : str, or list of str, optional
91+ List of names for system states. If not given, state names will be
92+ of of the form `x[i]` for interconnections of linear systems or
93+ '<subsys_name>.<state_name>' for interconnected nonlinear systems.
94+ name : string, optional
95+ System name (used for specifying signals). If unspecified, a generic
96+ name <sys[id]> is generated with a unique integer id.
97+8298 Raises
8399 ------
84100 ValueError
@@ -117,10 +133,12 @@ def series(sys1, *sysn):
117133 (2, 1, 5)
118134119135 """
120-return reduce(lambda x, y: y * x, sysn, sys1)
136+sys = reduce(lambda x, y: y * x, sysn, sys1)
137+sys.update_names(**kwargs)
138+return sys
121139122140123-def parallel(sys1, *sysn):
141+def parallel(sys1, *sysn, **kwargs):
124142r"""parallel(sys1, sys2, [..., sysn])
125143126144 Return the parallel connection `sys1` + `sys2` (+ ...\ + `sysn`).
@@ -135,6 +153,20 @@ def parallel(sys1, *sysn):
135153 out : scalar, array, or :class:`InputOutputSystem`
136154 Parallel interconnection of the systems.
137155156+ Other Parameters
157+ ----------------
158+ inputs, outputs : str, or list of str, optional
159+ List of strings that name the individual signals. If not given,
160+ signal names will be of the form `s[i]` (where `s` is one of `u`,
161+ or `y`). See :class:`InputOutputSystem` for more information.
162+ states : str, or list of str, optional
163+ List of names for system states. If not given, state names will be
164+ of of the form `x[i]` for interconnections of linear systems or
165+ '<subsys_name>.<state_name>' for interconnected nonlinear systems.
166+ name : string, optional
167+ System name (used for specifying signals). If unspecified, a generic
168+ name <sys[id]> is generated with a unique integer id.
169+138170 Raises
139171 ------
140172 ValueError
@@ -171,10 +203,11 @@ def parallel(sys1, *sysn):
171203 (3, 4, 7)
172204173205 """
174-return reduce(lambda x, y: x + y, sysn, sys1)
175-206+sys = reduce(lambda x, y: x + y, sysn, sys1)
207+sys.update_names(**kwargs)
208+return sys
176209177-def negate(sys):
210+def negate(sys, **kwargs):
178211"""
179212 Return the negative of a system.
180213@@ -188,15 +221,29 @@ def negate(sys):
188221 out : scalar, array, or :class:`InputOutputSystem`
189222 Negated system.
190223191- Notes
192- -----
193- This function is a wrapper for the __neg__ function in the StateSpace and
194- TransferFunction classes. The output type is the same as the input type.
224+ Other Parameters
225+ ----------------
226+ inputs, outputs : str, or list of str, optional
227+ List of strings that name the individual signals. If not given,
228+ signal names will be of the form `s[i]` (where `s` is one of `u`,
229+ or `y`). See :class:`InputOutputSystem` for more information.
230+ states : str, or list of str, optional
231+ List of names for system states. If not given, state names will be
232+ of of the form `x[i]` for interconnections of linear systems or
233+ '<subsys_name>.<state_name>' for interconnected nonlinear systems.
234+ name : string, optional
235+ System name (used for specifying signals). If unspecified, a generic
236+ name <sys[id]> is generated with a unique integer id.
195237196238 See Also
197239 --------
198240 append, feedback, interconnect, parallel, series
199241242+ Notes
243+ -----
244+ This function is a wrapper for the __neg__ function in the StateSpace and
245+ TransferFunction classes. The output type is the same as the input type.
246+200247 Examples
201248 --------
202249 >>> G = ct.tf([2], [1, 1])
@@ -208,11 +255,12 @@ def negate(sys):
208255 np.float64(-2.0)
209256210257 """
211-return -sys
258+sys = -sys
259+sys.update_names(**kwargs)
260+return sys
212261213262#! TODO: expand to allow sys2 default to work in MIMO case?
214-#! TODO: allow renaming of signals (for all bdalg operations)
215-def feedback(sys1, sys2=1, sign=-1):
263+def feedback(sys1, sys2=1, sign=-1, **kwargs):
216264"""Feedback interconnection between two I/O systems.
217265218266 Parameters
@@ -229,6 +277,20 @@ def feedback(sys1, sys2=1, sign=-1):
229277 out : scalar, array, or :class:`InputOutputSystem`
230278 Feedback interconnection of the systems.
231279280+ Other Parameters
281+ ----------------
282+ inputs, outputs : str, or list of str, optional
283+ List of strings that name the individual signals. If not given,
284+ signal names will be of the form `s[i]` (where `s` is one of `u`,
285+ or `y`). See :class:`InputOutputSystem` for more information.
286+ states : str, or list of str, optional
287+ List of names for system states. If not given, state names will be
288+ of of the form `x[i]` for interconnections of linear systems or
289+ '<subsys_name>.<state_name>' for interconnected nonlinear systems.
290+ name : string, optional
291+ System name (used for specifying signals). If unspecified, a generic
292+ name <sys[id]> is generated with a unique integer id.
293+232294 Raises
233295 ------
234296 ValueError
@@ -261,7 +323,7 @@ def feedback(sys1, sys2=1, sign=-1):
261323# Allow anything with a feedback function to call that function
262324# TODO: rewrite to allow __rfeedback__
263325try:
264-return sys1.feedback(sys2, sign)
326+return sys1.feedback(sys2, sign, **kwargs)
265327except (AttributeError, TypeError):
266328pass
267329@@ -284,9 +346,11 @@ def feedback(sys1, sys2=1, sign=-1):
284346else:
285347sys1 = ss._convert_to_statespace(sys1)
286348287-return sys1.feedback(sys2, sign)
349+sys = sys1.feedback(sys2, sign)
350+sys.update_names(**kwargs)
351+return sys
288352289-def append(*sys):
353+def append(*sys, **kwargs):
290354"""append(sys1, sys2, [..., sysn])
291355292356 Group LTI state space models by appending their inputs and outputs.
@@ -299,6 +363,20 @@ def append(*sys):
299363 sys1, sys2, ..., sysn: scalar, array, or :class:`StateSpace`
300364 I/O systems to combine.
301365366+ Other Parameters
367+ ----------------
368+ inputs, outputs : str, or list of str, optional
369+ List of strings that name the individual signals. If not given,
370+ signal names will be of the form `s[i]` (where `s` is one of `u`,
371+ or `y`). See :class:`InputOutputSystem` for more information.
372+ states : str, or list of str, optional
373+ List of names for system states. If not given, state names will be
374+ of of the form `x[i]` for interconnections of linear systems or
375+ '<subsys_name>.<state_name>' for interconnected nonlinear systems.
376+ name : string, optional
377+ System name (used for specifying signals). If unspecified, a generic
378+ name <sys[id]> is generated with a unique integer id.
379+302380 Returns
303381 -------
304382 out: :class:`StateSpace`
@@ -327,6 +405,7 @@ def append(*sys):
327405s1 = ss._convert_to_statespace(sys[0])
328406for s in sys[1:]:
329407s1 = s1.append(s)
408+s1.update_names(**kwargs)
330409return s1
331410332411def connect(sys, Q, inputv, outputv):
@@ -370,6 +449,12 @@ def connect(sys, Q, inputv, outputv):
370449 --------
371450 append, feedback, interconnect, negate, parallel, series
372451452+ Notes
453+ -----
454+ The :func:`~control.interconnect` function in the :ref:`input/output
455+ systems <iosys-module>` module allows the use of named signals and
456+ provides an alternative method for interconnecting multiple systems.
457+373458 Examples
374459 --------
375460 >>> G = ct.rss(7, inputs=2, outputs=2)
@@ -378,12 +463,6 @@ def connect(sys, Q, inputv, outputv):
378463 >>> T.ninputs, T.noutputs, T.nstates
379464 (1, 2, 7)
380465381- Notes
382- -----
383- The :func:`~control.interconnect` function in the :ref:`input/output
384- systems <iosys-module>` module allows the use of named signals and
385- provides an alternative method for interconnecting multiple systems.
386-387466 """
388467# TODO: maintain `connect` for use in MATLAB submodule (?)
389468warn("`connect` is deprecated; use `interconnect`", DeprecationWarning)