Skip to content

Commit 7a79342

Browse files
committed
document and fix {input,output,state}_prefix parameters
1 parent 2f2e372 commit 7a79342

7 files changed

Lines changed: 90 additions & 15 deletions

File tree

control/flatsys/flatsys.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ def flatsys(*args, updfcn=None, outfcn=None, **kwargs):
236236
sys: :class:`FlatSystem`
237237
Flat system.
238238
239+
Other Parameters
240+
----------------
241+
input_prefix, output_prefix, state_prefix : string, optional
242+
Set the prefix for input, output, and state signals. Defaults =
243+
'u', 'y', 'x'.
244+
239245
"""
240246
from .linflat import LinearFlatSystem
241247
from ..statesp import StateSpace

control/frdata.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,9 @@ def __init__(self, *args, **kwargs):
299299

300300
# Process signal names
301301
name, inputs, outputs, states, dt = _process_iosys_keywords(
302-
kwargs, defaults, end=True)
302+
kwargs, defaults)
303303
InputOutputSystem.__init__(
304-
self, name=name, inputs=inputs, outputs=outputs, dt=dt)
304+
self, name=name, inputs=inputs, outputs=outputs, dt=dt, **kwargs)
305305

306306
# create interpolation functions
307307
if smooth:
@@ -972,6 +972,8 @@ def frd(*args, **kwargs):
972972
List of strings that name the individual signals of the transformed
973973
system. If not given, the inputs and outputs are the same as the
974974
original system.
975+
input_prefix, output_prefix : string, optional
976+
Set the prefix for input and output signals. Defaults = 'u', 'y'.
975977
name : string, optional
976978
System name. If unspecified, a generic name <sys[id]> is generated
977979
with a unique integer id.

control/nlsys.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,12 @@ def nlsys(updfcn, outfcn=None, **kwargs):
12851285
sys : :class:`NonlinearIOSystem`
12861286
Nonlinear input/output system.
12871287
1288+
Other Parameters
1289+
----------------
1290+
input_prefix, output_prefix, state_prefix : string, optional
1291+
Set the prefix for input, output, and state signals. Defaults =
1292+
'u', 'y', 'x'.
1293+
12881294
See Also
12891295
--------
12901296
ss, tf

control/statesp.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1577,7 +1577,6 @@ def ss(*args, **kwargs):
15771577
out: StateSpace
15781578
Linear input/output system.
15791579
1580-
>>>>>>> 1f609a56 (updated iosys class/factory function documentation + docstring unit testing)
15811580
Raises
15821581
------
15831582
ValueError

control/tests/docstrings_test.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,13 @@ def test_deprecated_functions(module, prefix):
281281
ct.TransferFunction: ct.tf,
282282
}
283283

284+
#
284285
# List of arguments described in class docstrings
286+
#
287+
# These are the minimal arguments needed to initialized the class. Optional
288+
# arguments should be documented in the factory functions and do not need
289+
# to be duplicated in the class documentation.
290+
#
285291
class_args = {
286292
fs.FlatSystem: ['forward', 'reverse'],
287293
ct.FrequencyResponseData: ['response', 'omega', 'dt'],
@@ -291,15 +297,27 @@ def test_deprecated_functions(module, prefix):
291297
ct.TransferFunction: ['num', 'den', 'dt'],
292298
}
293299

294-
# List of attributes defined for all I/O systems
300+
#
301+
# List of attributes described in class docstrings
302+
#
303+
# This is the list of attributes for the class that are not already listed
304+
# as parameters used to inialize the class. These should all be defined
305+
# in the class docstring.
306+
#
307+
# Attributes that are part of all I/O system classes should be listed in
308+
# `std_class_attributes`. Attributes that are not commonly needed are
309+
# defined as part of a parent class can just be documented there, and
310+
# should be listed in `iosys_parent_attributes` (these will be searched
311+
# using the MRO).
312+
295313
std_class_attributes = [
296314
'ninputs', 'noutputs', 'input_labels', 'output_labels', 'name', 'shape']
297315

298316
# List of attributes defined for specific I/O systems
299317
class_attributes = {
300318
fs.FlatSystem: [],
301319
ct.FrequencyResponseData: [],
302-
ct.NonlinearIOSystem: [],
320+
ct.NonlinearIOSystem: ['nstates', 'state_labels'],
303321
ct.StateSpace: ['nstates', 'state_labels'],
304322
ct.TransferFunction: [],
305323
}
@@ -312,13 +330,22 @@ def test_deprecated_functions(module, prefix):
312330
'params', 'outfcn', 'updfcn' # NL I/O, SS overlap
313331
]
314332

333+
#
315334
# List of arguments described (only) in factory function docstrings
316-
std_factory_args = ['inputs', 'outputs', 'name']
335+
#
336+
# These lists consist of the arguments that should be documented in the
337+
# factory functions and should not be duplicated in the class
338+
# documentation, even though in some cases they are actually processed in
339+
# the class __init__ function.
340+
#
341+
std_factory_args = [
342+
'inputs', 'outputs', 'name', 'input_prefix', 'output_prefix']
343+
317344
factory_args = {
318-
fs.flatsys: [],
345+
fs.flatsys: ['states', 'state_prefix'],
319346
ct.frd: ['sys'],
320-
ct.nlsys: [],
321-
ct.ss: ['sys', 'states'],
347+
ct.nlsys: ['state_prefix'],
348+
ct.ss: ['sys', 'states', 'state_prefix'],
322349
ct.tf: ['sys'],
323350
}
324351

@@ -343,7 +370,7 @@ def test_iosys_primary_classes(cls, fcn, args):
343370
f"{cls.__name__} does not reference factory function "
344371
f"{fcn.__name__}")
345372

346-
# Make sure we don't reference parameters in the factory function
373+
# Make sure we don't reference parameters from the factory function
347374
for argname in factory_args[fcn]:
348375
if re.search(f"[\\s]+{argname}(, .*)*[\\s]*:", docstring) is not None:
349376
pytest.fail(
@@ -448,7 +475,7 @@ def test_iosys_factory_functions(fcn):
448475
list(class_factory_function.values()).index(fcn)]
449476

450477
# Make sure we reference parameters in class and factory function docstring
451-
for argname in class_args[cls] + factory_args[fcn]:
478+
for argname in class_args[cls] + std_factory_args + factory_args[fcn]:
452479
_check_parameter_docs(fcn.__name__, argname, docstring)
453480

454481
# Make sure we don't reference any class attributes
@@ -516,4 +543,3 @@ def _check_parameter_docs(
516543
pytest.fail(f"{funcname} '{argname}' documented twice")
517544

518545
return True
519-

control/tests/iosys_test.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,3 +2303,37 @@ def test_relabeling(fcn):
23032303
if sys.nstates:
23042304
assert sys.state_labels == ['x']
23052305
assert sys.name == 'new'
2306+
2307+
2308+
@pytest.mark.parametrize("fcn", [ct.ss, ct.tf, ct.frd, ct.nlsys, fs.flatsys])
2309+
def test_signal_prefixing(fcn):
2310+
sys = ct.rss(2, 1, 1)
2311+
2312+
# Recreate the system in different forms, with non-standard prefixes
2313+
match fcn:
2314+
case ct.ss:
2315+
sys = ct.ss(
2316+
sys.A, sys.B, sys.C, sys.D, state_prefix='xx',
2317+
input_prefix='uu', output_prefix='yy')
2318+
case ct.tf:
2319+
sys = ct.tf(sys)
2320+
sys = fcn(sys.num, sys.den, input_prefix='uu', output_prefix='yy')
2321+
case ct.frd:
2322+
freq = [0.1, 1, 10]
2323+
data = [sys(w * 1j) for w in freq]
2324+
sys = fcn(data, freq, input_prefix='uu', output_prefix='yy')
2325+
case ct.nlsys:
2326+
sys = ct.nlsys(sys)
2327+
sys = fcn(
2328+
sys.updfcn, sys.outfcn, inputs=1, outputs=1, states=2,
2329+
state_prefix='xx', input_prefix='uu', output_prefix='yy')
2330+
case fs.flatsys:
2331+
sys = fs.flatsys(sys)
2332+
sys = fcn(
2333+
sys.forward, sys.reverse, inputs=1, outputs=1, states=2,
2334+
state_prefix='xx', input_prefix='uu', output_prefix='yy')
2335+
2336+
assert sys.input_labels == ['uu[0]']
2337+
assert sys.output_labels == ['yy[0]']
2338+
if sys.nstates:
2339+
assert sys.state_labels == ['xx[0]', 'xx[1]']

control/xferfcn.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020

2121
import numpy as np
2222
import scipy as sp
23-
from numpy import angle, array, delete, empty, exp, finfo, ndarray, nonzero, \
24-
ones, pi, poly, polyadd, polymul, polyval, real, roots, sqrt, squeeze, \
25-
where, zeros
23+
from numpy import angle, array, delete, empty, exp, finfo, float64, ndarray, \
24+
nonzero, ones, pi, poly, polyadd, polymul, polyval, real, roots, sqrt, \
25+
squeeze, where, zeros
2626
from scipy.signal import TransferFunction as signalTransferFunction
2727
from scipy.signal import cont2discrete, tf2zpk, zpk2tf
2828

@@ -1595,6 +1595,8 @@ def tf(*args, **kwargs):
15951595
List of strings that name the individual signals of the transformed
15961596
system. If not given, the inputs and outputs are the same as the
15971597
original system.
1598+
input_prefix, output_prefix : string, optional
1599+
Set the prefix for input and output signals. Defaults = 'u', 'y'.
15981600
name : string, optional
15991601
System name. If unspecified, a generic name <sys[id]> is generated
16001602
with a unique integer id.

0 commit comments

Comments
 (0)