Skip to content

Commit 0223b82

Browse files
sawyerbfullerbnavigator
authored andcommitted
changes to enable package-wide default, 'control.default_dt')
1 parent 24eeb75 commit 0223b82

5 files changed

Lines changed: 41 additions & 45 deletions

File tree

control/config.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
# Package level default values
1717
_control_defaults = {
18-
# No package level defaults (yet)
18+
'control.default_dt':0
1919
}
2020
defaults = dict(_control_defaults)
2121

@@ -216,8 +216,6 @@ def use_legacy_defaults(version):
216216
# switched to 'array' as default for state space objects
217217
set_defaults('statesp', use_numpy_matrix=True)
218218
# switched to 0 (=continuous) as default timestep
219-
set_defaults('statesp', default_dt=None)
220-
set_defaults('xferfcn', default_dt=None)
221-
set_defaults('iosys', default_dt=None)
219+
set_defaults('control', default_dt=None)
222220

223221
return (major, minor, patch)

control/iosys.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@
4646
'linearize', 'ss2io', 'tf2io']
4747

4848
# Define module default parameter values
49-
_iosys_defaults = {
50-
'iosys.default_dt': 0}
49+
_iosys_defaults = {}
5150

5251
class InputOutputSystem(object):
5352
"""A class for representing input/output systems.
@@ -166,9 +165,13 @@ def __init__(self, inputs=None, outputs=None, states=None, params={},
166165
167166
"""
168167
# Store the input arguments
169-
self.params = params.copy() # default parameters
170-
self.dt = kwargs.get('dt', config.defaults['iosys.default_dt']) # timebase
171-
self.name = self.name_or_default(name) # system name
168+
169+
# default parameters
170+
self.params = params.copy()
171+
# timebase
172+
self.dt = kwargs.get('dt', config.defaults['control.default_dt'])
173+
# system name
174+
self.name = self.name_or_default(name)
172175

173176
# Parse and store the number of inputs, outputs, and states
174177
self.set_inputs(inputs)
@@ -724,7 +727,7 @@ def __init__(self, updfcn, outfcn=None, inputs=None, outputs=None,
724727
self.outfcn = outfcn
725728

726729
# Initialize the rest of the structure
727-
dt = kwargs.get('dt', config.defaults['iosys.default_dt'])
730+
dt = kwargs.get('dt', config.defaults['control.default_dt'])
728731
super(NonlinearIOSystem, self).__init__(
729732
inputs=inputs, outputs=outputs, states=states,
730733
params=params, dt=dt, name=name

control/statesp.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
# Define module default parameter values
7373
_statesp_defaults = {
7474
'statesp.use_numpy_matrix': False, # False is default in 0.9.0 and above
75-
'statesp.default_dt': 0,
7675
'statesp.remove_useless_states': True,
7776
}
7877

@@ -155,8 +154,8 @@ class StateSpace(LTI):
155154
Setting dt = 0 specifies a continuous system, while leaving dt = None
156155
means the system timebase is not specified. If 'dt' is set to True, the
157156
system will be treated as a discrete time system with unspecified sampling
158-
time. The default value of 'dt' is None and can be changed by changing the
159-
value of ``control.config.defaults['statesp.default_dt']``.
157+
time. The default value of 'dt' is 0 and can be changed by changing the
158+
value of ``control.config.defaults['control.default_dt']``.
160159
161160
"""
162161

@@ -180,10 +179,10 @@ def __init__(self, *args, **kw):
180179
if len(args) == 4:
181180
# The user provided A, B, C, and D matrices.
182181
(A, B, C, D) = args
183-
if _isstaticgain(A, B, C, D):
182+
if _isstaticgain(A, B, C, D):
184183
dt = None
185184
else:
186-
dt = config.defaults['statesp.default_dt']
185+
dt = config.defaults['control.default_dt']
187186
elif len(args) == 5:
188187
# Discrete time system
189188
(A, B, C, D, dt) = args
@@ -199,10 +198,10 @@ def __init__(self, *args, **kw):
199198
try:
200199
dt = args[0].dt
201200
except NameError:
202-
if _isstaticgain(A, B, C, D):
201+
if _isstaticgain(A, B, C, D):
203202
dt = None
204203
else:
205-
dt = config.defaults['statesp.default_dt']
204+
dt = config.defaults['control.default_dt']
206205
else:
207206
raise ValueError("Expected 1, 4, or 5 arguments; received %i." % len(args))
208207

@@ -1268,7 +1267,7 @@ def _mimo2simo(sys, input, warn_conversion=False):
12681267
return sys
12691268

12701269
def _isstaticgain(A, B, C, D):
1271-
"""returns True if and only if the system has no dynamics, that is,
1270+
"""returns True if and only if the system has no dynamics, that is,
12721271
if A and B are zero. """
12731272
return not np.any(np.matrix(A, dtype=float)) \
12741273
and not np.any(np.matrix(B, dtype=float))

control/tests/config_test.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,17 @@ def test_legacy_defaults(self):
234234
@pytest.mark.parametrize("dt", [0, None])
235235
def test_change_default_dt(self, dt):
236236
"""Test that system with dynamics uses correct default dt"""
237-
ct.set_defaults('statesp', default_dt=dt)
237+
ct.set_defaults('control', default_dt=dt)
238238
assert ct.ss(1, 0, 0, 1).dt == dt
239-
ct.set_defaults('xferfcn', default_dt=dt)
240239
assert ct.tf(1, [1, 1]).dt == dt
241-
242-
# nlsys = ct.iosys.NonlinearIOSystem(
243-
# lambda t, x, u: u * x * x,
244-
# lambda t, x, u: x, inputs=1, outputs=1)
245-
# assert nlsys.dt == dt
240+
nlsys = ct.iosys.NonlinearIOSystem(
241+
lambda t, x, u: u * x * x,
242+
lambda t, x, u: x, inputs=1, outputs=1)
243+
assert nlsys.dt == dt
246244

247245
def test_change_default_dt_static(self):
248246
"""Test that static gain systems always have dt=None"""
249-
ct.set_defaults('xferfcn', default_dt=0)
247+
ct.set_defaults('control', default_dt=0)
250248
assert ct.tf(1, 1).dt is None
251-
ct.set_defaults('statesp', default_dt=0)
252249
assert ct.ss(0, 0, 0, 1).dt is None
253250
# TODO: add in test for static gain iosys

control/xferfcn.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@
7070

7171

7272
# Define module default parameter values
73-
_xferfcn_defaults = {
74-
'xferfcn.default_dt': 0}
73+
_xferfcn_defaults = {}
7574

7675
class TransferFunction(LTI):
7776

@@ -95,8 +94,8 @@ class TransferFunction(LTI):
9594
has a non-zero value, then it must match whenever two transfer functions
9695
are combined. If 'dt' is set to True, the system will be treated as a
9796
discrete time system with unspecified sampling time. The default value of
98-
'dt' is None and can be changed by changing the value of
99-
``control.config.defaults['xferfcn.default_dt']``.
97+
'dt' is 0 and can be changed by changing the value of
98+
``control.config.defaults['control.default_dt']``.
10099
101100
The TransferFunction class defines two constants ``s`` and ``z`` that
102101
represent the differentiation and delay operators in continuous and
@@ -127,8 +126,8 @@ def __init__(self, *args):
127126
(num, den) = args
128127
if _isstaticgain(num, den):
129128
dt = None
130-
else:
131-
dt = config.defaults['xferfcn.default_dt']
129+
else:
130+
dt = config.defaults['control.default_dt']
132131
elif len(args) == 3:
133132
# Discrete time transfer function
134133
(num, den, dt) = args
@@ -146,8 +145,8 @@ def __init__(self, *args):
146145
except NameError: # pragma: no coverage
147146
if _isstaticgain(num, den):
148147
dt = None
149-
else:
150-
dt = config.defaults['xferfcn.default_dt']
148+
else:
149+
dt = config.defaults['control.default_dt']
151150
else:
152151
raise ValueError("Needs 1, 2 or 3 arguments; received %i."
153152
% len(args))
@@ -421,7 +420,7 @@ def __mul__(self, other):
421420
outputs = self.outputs
422421

423422
dt = common_timebase(self.dt, other.dt)
424-
423+
425424
# Preallocate the numerator and denominator of the sum.
426425
num = [[[0] for j in range(inputs)] for i in range(outputs)]
427426
den = [[[1] for j in range(inputs)] for i in range(outputs)]
@@ -1083,16 +1082,16 @@ def _dcgain_cont(self):
10831082
return np.squeeze(gain)
10841083

10851084
def is_static_gain(self):
1086-
"""returns True if and only if all of the numerator and denominator
1087-
polynomials of the (possibly MIMO) transfer function are zeroth order,
1085+
"""returns True if and only if all of the numerator and denominator
1086+
polynomials of the (possibly MIMO) transfer function are zeroth order,
10881087
that is, if the system has no dynamics. """
1089-
for list_of_polys in self.num, self.den:
1088+
for list_of_polys in self.num, self.den:
10901089
for row in list_of_polys:
10911090
for poly in row:
1092-
if len(poly) > 1:
1091+
if len(poly) > 1:
10931092
return False
10941093
return True
1095-
1094+
10961095
# c2d function contributed by Benjamin White, Oct 2012
10971096
def _c2d_matched(sysC, Ts):
10981097
# Pole-zero match method of continuous to discrete time conversion
@@ -1566,15 +1565,15 @@ def _clean_part(data):
15661565
return data
15671566

15681567
def _isstaticgain(num, den):
1569-
"""returns True if and only if all of the numerator and denominator
1570-
polynomials of the (possibly MIMO) transfer funnction are zeroth order,
1568+
"""returns True if and only if all of the numerator and denominator
1569+
polynomials of the (possibly MIMO) transfer funnction are zeroth order,
15711570
that is, if the system has no dynamics. """
15721571
num, den = _clean_part(num), _clean_part(den)
1573-
for list_of_polys in num, den:
1572+
for list_of_polys in num, den:
15741573
for row in list_of_polys:
15751574
for poly in row:
15761575
poly_trimmed = np.trim_zeros(poly, 'f') # trim leading zeros
1577-
if len(poly_trimmed) > 1:
1576+
if len(poly_trimmed) > 1:
15781577
return False
15791578
return True
15801579

0 commit comments

Comments
 (0)