Skip to content

Commit 4b7bf8a

Browse files
committed
rename _convertToX to _convert_to_x + statesp/ndarray unit tests
1 parent bd77d71 commit 4b7bf8a

8 files changed

Lines changed: 68 additions & 45 deletions

File tree

control/bdalg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ def feedback(sys1, sys2=1, sign=-1):
242242
if isinstance(sys2, tf.TransferFunction):
243243
sys1 = tf._convert_to_transfer_function(sys1)
244244
elif isinstance(sys2, ss.StateSpace):
245-
sys1 = ss._convertToStateSpace(sys1)
245+
sys1 = ss._convert_to_statespace(sys1)
246246
elif isinstance(sys2, frd.FRD):
247-
sys1 = frd._convertToFRD(sys1, sys2.omega)
247+
sys1 = frd._convert_to_FRD(sys1, sys2.omega)
248248
else: # sys2 is a scalar.
249249
sys1 = tf._convert_to_transfer_function(sys1)
250250
sys2 = tf._convert_to_transfer_function(sys2)

control/dtime.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"""
4848

4949
from .lti import isctime
50-
from .statesp import StateSpace, _convertToStateSpace
50+
from .statesp import StateSpace
5151

5252
__all__ = ['sample_system', 'c2d']
5353

control/frdata.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def __add__(self, other):
197197

198198
# Convert the second argument to a frequency response function.
199199
# or re-base the frd to the current omega (if needed)
200-
other = _convertToFRD(other, omega=self.omega)
200+
other = _convert_to_FRD(other, omega=self.omega)
201201

202202
# Check that the input-output sizes are consistent.
203203
if self.inputs != other.inputs:
@@ -232,7 +232,7 @@ def __mul__(self, other):
232232
return FRD(self.fresp * other, self.omega,
233233
smooth=(self.ifunc is not None))
234234
else:
235-
other = _convertToFRD(other, omega=self.omega)
235+
other = _convert_to_FRD(other, omega=self.omega)
236236

237237
# Check that the input-output sizes are consistent.
238238
if self.inputs != other.outputs:
@@ -259,7 +259,7 @@ def __rmul__(self, other):
259259
return FRD(self.fresp * other, self.omega,
260260
smooth=(self.ifunc is not None))
261261
else:
262-
other = _convertToFRD(other, omega=self.omega)
262+
other = _convert_to_FRD(other, omega=self.omega)
263263

264264
# Check that the input-output sizes are consistent.
265265
if self.outputs != other.inputs:
@@ -287,7 +287,7 @@ def __truediv__(self, other):
287287
return FRD(self.fresp * (1/other), self.omega,
288288
smooth=(self.ifunc is not None))
289289
else:
290-
other = _convertToFRD(other, omega=self.omega)
290+
other = _convert_to_FRD(other, omega=self.omega)
291291

292292
if (self.inputs > 1 or self.outputs > 1 or
293293
other.inputs > 1 or other.outputs > 1):
@@ -310,7 +310,7 @@ def __rtruediv__(self, other):
310310
return FRD(other / self.fresp, self.omega,
311311
smooth=(self.ifunc is not None))
312312
else:
313-
other = _convertToFRD(other, omega=self.omega)
313+
other = _convert_to_FRD(other, omega=self.omega)
314314

315315
if (self.inputs > 1 or self.outputs > 1 or
316316
other.inputs > 1 or other.outputs > 1):
@@ -450,7 +450,7 @@ def freqresp(self, omega):
450450
def feedback(self, other=1, sign=-1):
451451
"""Feedback interconnection between two FRD objects."""
452452

453-
other = _convertToFRD(other, omega=self.omega)
453+
other = _convert_to_FRD(other, omega=self.omega)
454454

455455
if (self.outputs != other.inputs or self.inputs != other.outputs):
456456
raise ValueError(
@@ -486,7 +486,7 @@ def feedback(self, other=1, sign=-1):
486486
FRD = FrequencyResponseData
487487

488488

489-
def _convertToFRD(sys, omega, inputs=1, outputs=1):
489+
def _convert_to_FRD(sys, omega, inputs=1, outputs=1):
490490
"""Convert a system to frequency response data form (if needed).
491491
492492
If sys is already an frd, and its frequency range matches or
@@ -496,8 +496,8 @@ def _convertToFRD(sys, omega, inputs=1, outputs=1):
496496
scalar, then the number of inputs and outputs can be specified
497497
manually, as in:
498498
499-
>>> frd = _convertToFRD(3., omega) # Assumes inputs = outputs = 1
500-
>>> frd = _convertToFRD(1., omegs, inputs=3, outputs=2)
499+
>>> frd = _convert_to_FRD(3., omega) # Assumes inputs = outputs = 1
500+
>>> frd = _convert_to_FRD(1., omegs, inputs=3, outputs=2)
501501
502502
In the latter example, sys's matrix transfer function is [[1., 1., 1.]
503503
[1., 1., 1.]].

control/statesp.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
# Python 3 compatibility (needs to go here)
1212
from __future__ import print_function
13-
from __future__ import division # for _convertToStateSpace
13+
from __future__ import division # for _convert_to_statespace
1414

1515
"""Copyright (c) 2010 by California Institute of Technology
1616
All rights reserved.
@@ -527,7 +527,7 @@ def __add__(self, other):
527527
D = self.D + other
528528
dt = self.dt
529529
else:
530-
other = _convertToStateSpace(other)
530+
other = _convert_to_statespace(other)
531531

532532
# Check to make sure the dimensions are OK
533533
if ((self.inputs != other.inputs) or
@@ -577,7 +577,7 @@ def __mul__(self, other):
577577
D = self.D * other
578578
dt = self.dt
579579
else:
580-
other = _convertToStateSpace(other)
580+
other = _convert_to_statespace(other)
581581

582582
# Check to make sure the dimensions are OK
583583
if self.inputs != other.outputs:
@@ -614,7 +614,7 @@ def __rmul__(self, other):
614614

615615
# is lti, and convertible?
616616
if isinstance(other, LTI):
617-
return _convertToStateSpace(other) * self
617+
return _convert_to_statespace(other) * self
618618

619619
# try to treat this as a matrix
620620
try:
@@ -839,7 +839,7 @@ def zero(self):
839839
def feedback(self, other=1, sign=-1):
840840
"""Feedback interconnection between two LTI systems."""
841841

842-
other = _convertToStateSpace(other)
842+
other = _convert_to_statespace(other)
843843

844844
# Check to make sure the dimensions are OK
845845
if (self.inputs != other.outputs) or (self.outputs != other.inputs):
@@ -907,7 +907,7 @@ def lft(self, other, nu=-1, ny=-1):
907907
Dimension of (plant) control input.
908908
909909
"""
910-
other = _convertToStateSpace(other)
910+
other = _convert_to_statespace(other)
911911
# maximal values for nu, ny
912912
if ny == -1:
913913
ny = min(other.inputs, self.outputs)
@@ -1061,7 +1061,7 @@ def append(self, other):
10611061
The second model is converted to state-space if necessary, inputs and
10621062
outputs are appended and their order is preserved"""
10631063
if not isinstance(other, StateSpace):
1064-
other = _convertToStateSpace(other)
1064+
other = _convert_to_statespace(other)
10651065

10661066
self.dt = common_timebase(self.dt, other.dt)
10671067

@@ -1186,16 +1186,16 @@ def is_static_gain(self):
11861186

11871187

11881188
# TODO: add discrete time check
1189-
def _convertToStateSpace(sys, **kw):
1189+
def _convert_to_statespace(sys, **kw):
11901190
"""Convert a system to state space form (if needed).
11911191
11921192
If sys is already a state space, then it is returned. If sys is a
11931193
transfer function object, then it is converted to a state space and
11941194
returned. If sys is a scalar, then the number of inputs and outputs can
11951195
be specified manually, as in:
11961196
1197-
>>> sys = _convertToStateSpace(3.) # Assumes inputs = outputs = 1
1198-
>>> sys = _convertToStateSpace(1., inputs=3, outputs=2)
1197+
>>> sys = _convert_to_statespace(3.) # Assumes inputs = outputs = 1
1198+
>>> sys = _convert_to_statespace(1., inputs=3, outputs=2)
11991199
12001200
In the latter example, A = B = C = 0 and D = [[1., 1., 1.]
12011201
[1., 1., 1.]].
@@ -1205,7 +1205,7 @@ def _convertToStateSpace(sys, **kw):
12051205

12061206
if isinstance(sys, StateSpace):
12071207
if len(kw):
1208-
raise TypeError("If sys is a StateSpace, _convertToStateSpace "
1208+
raise TypeError("If sys is a StateSpace, _convert_to_statespace "
12091209
"cannot take keywords.")
12101210

12111211
# Already a state space system; just return it
@@ -1221,7 +1221,7 @@ def _convertToStateSpace(sys, **kw):
12211221
from slycot import td04ad
12221222
if len(kw):
12231223
raise TypeError("If sys is a TransferFunction, "
1224-
"_convertToStateSpace cannot take keywords.")
1224+
"_convert_to_statespace cannot take keywords.")
12251225

12261226
# Change the numerator and denominator arrays so that the transfer
12271227
# function matrix has a common denominator.
@@ -1283,7 +1283,7 @@ def _convertToStateSpace(sys, **kw):
12831283
return StateSpace([], [], [], D)
12841284
except Exception as e:
12851285
print("Failure to assume argument is matrix-like in"
1286-
" _convertToStateSpace, result %s" % e)
1286+
" _convert_to_statespace, result %s" % e)
12871287

12881288
raise TypeError("Can't convert given type to StateSpace system.")
12891289

@@ -1662,14 +1662,14 @@ def tf2ss(*args):
16621662
from .xferfcn import TransferFunction
16631663
if len(args) == 2 or len(args) == 3:
16641664
# Assume we were given the num, den
1665-
return _convertToStateSpace(TransferFunction(*args))
1665+
return _convert_to_statespace(TransferFunction(*args))
16661666

16671667
elif len(args) == 1:
16681668
sys = args[0]
16691669
if not isinstance(sys, TransferFunction):
16701670
raise TypeError("tf2ss(sys): sys must be a TransferFunction "
16711671
"object.")
1672-
return _convertToStateSpace(sys)
1672+
return _convert_to_statespace(sys)
16731673
else:
16741674
raise ValueError("Needs 1 or 2 arguments; received %i." % len(args))
16751675

@@ -1769,5 +1769,5 @@ def ssdata(sys):
17691769
(A, B, C, D): list of matrices
17701770
State space data for the system
17711771
"""
1772-
ss = _convertToStateSpace(sys)
1772+
ss = _convert_to_statespace(sys)
17731773
return ss.A, ss.B, ss.C, ss.D

control/tests/frd_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import control as ct
1313
from control.statesp import StateSpace
1414
from control.xferfcn import TransferFunction
15-
from control.frdata import FRD, _convertToFRD, FrequencyResponseData
15+
from control.frdata import FRD, _convert_to_FRD, FrequencyResponseData
1616
from control import bdalg, evalfr, freqplot
1717
from control.tests.conftest import slycotonly
1818

@@ -174,9 +174,9 @@ def testFeedback2(self):
174174

175175
def testAuto(self):
176176
omega = np.logspace(-1, 2, 10)
177-
f1 = _convertToFRD(1, omega)
178-
f2 = _convertToFRD(np.array([[1, 0], [0.1, -1]]), omega)
179-
f2 = _convertToFRD([[1, 0], [0.1, -1]], omega)
177+
f1 = _convert_to_FRD(1, omega)
178+
f2 = _convert_to_FRD(np.array([[1, 0], [0.1, -1]]), omega)
179+
f2 = _convert_to_FRD([[1, 0], [0.1, -1]], omega)
180180
f1, f2 # reference to avoid pyflakes error
181181

182182
def testNyquist(self):

control/tests/statesp_test.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@
99

1010
import numpy as np
1111
import pytest
12+
import operator
1213
from numpy.linalg import solve
1314
from scipy.linalg import block_diag, eigvals
1415

16+
import control as ct
1517
from control.config import defaults
1618
from control.dtime import sample_system
1719
from control.lti import evalfr
18-
from control.statesp import (StateSpace, _convertToStateSpace, drss, rss, ss,
19-
tf2ss, _statesp_defaults)
20+
from control.statesp import (StateSpace, _convert_to_statespace, drss,
21+
rss, ss, tf2ss, _statesp_defaults)
2022
from control.tests.conftest import ismatarrayout, slycotonly
2123
from control.xferfcn import TransferFunction, ss2tf
2224

@@ -224,7 +226,7 @@ def test_pole(self, sys322):
224226

225227
def test_zero_empty(self):
226228
"""Test to make sure zero() works with no zeros in system."""
227-
sys = _convertToStateSpace(TransferFunction([1], [1, 2, 1]))
229+
sys = _convert_to_statespace(TransferFunction([1], [1, 2, 1]))
228230
np.testing.assert_array_equal(sys.zero(), np.array([]))
229231

230232
@slycotonly
@@ -456,7 +458,7 @@ def test_append_tf(self):
456458
s = TransferFunction([1, 0], [1])
457459
h = 1 / (s + 1) / (s + 2)
458460
sys1 = StateSpace(A1, B1, C1, D1)
459-
sys2 = _convertToStateSpace(h)
461+
sys2 = _convert_to_statespace(h)
460462
sys3c = sys1.append(sys2)
461463
np.testing.assert_array_almost_equal(sys1.A, sys3c.A[:3, :3])
462464
np.testing.assert_array_almost_equal(sys1.B, sys3c.B[:3, :2])
@@ -625,10 +627,10 @@ def test_empty(self):
625627
assert 0 == g1.outputs
626628

627629
def test_matrix_to_state_space(self):
628-
"""_convertToStateSpace(matrix) gives ss([],[],[],D)"""
630+
"""_convert_to_statespace(matrix) gives ss([],[],[],D)"""
629631
with pytest.deprecated_call():
630632
D = np.matrix([[1, 2, 3], [4, 5, 6]])
631-
g = _convertToStateSpace(D)
633+
g = _convert_to_statespace(D)
632634

633635
np.testing.assert_array_equal(np.empty((0, 0)), g.A)
634636
np.testing.assert_array_equal(np.empty((0, D.shape[1])), g.B)
@@ -927,3 +929,24 @@ def test_latex_repr(gmats, ref, repr_type, num_format, editsdefaults):
927929
g = StateSpace(*gmats)
928930
refkey = "{}_{}".format(refkey_n[num_format], refkey_r[repr_type])
929931
assert g._repr_latex_() == ref[refkey]
932+
933+
934+
@pytest.mark.parametrize(
935+
"op",
936+
[pytest.param(getattr(operator, s), id=s) for s in ('add', 'sub', 'mul')])
937+
@pytest.mark.parametrize(
938+
"tf, arr",
939+
[pytest.param(ct.tf([1], [0.5, 1]), np.array(2.), id="0D scalar"),
940+
pytest.param(ct.tf([1], [0.5, 1]), np.array([2.]), id="1D scalar"),
941+
pytest.param(ct.tf([1], [0.5, 1]), np.array([[2.]]), id="2D scalar")])
942+
def test_xferfcn_ndarray_precedence(op, tf, arr):
943+
# Apply the operator to the transfer function and array
944+
ss = ct.tf2ss(tf)
945+
result = op(ss, arr)
946+
assert isinstance(result, ct.StateSpace)
947+
948+
# Apply the operator to the array and transfer function
949+
ss = ct.tf2ss(tf)
950+
result = op(arr, ss)
951+
assert isinstance(result, ct.StateSpace)
952+

control/tests/xferfcn_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import operator
99

1010
import control as ct
11-
from control.statesp import StateSpace, _convertToStateSpace, rss
11+
from control.statesp import StateSpace, _convert_to_statespace, rss
1212
from control.xferfcn import TransferFunction, _convert_to_transfer_function, \
1313
ss2tf
1414
from control.lti import evalfr
@@ -711,7 +711,7 @@ def test_state_space_conversion_mimo(self):
711711
h = (b0 + b1*s + b2*s**2)/(a0 + a1*s + a2*s**2 + a3*s**3)
712712
H = TransferFunction([[h.num[0][0]], [(h*s).num[0][0]]],
713713
[[h.den[0][0]], [h.den[0][0]]])
714-
sys = _convertToStateSpace(H)
714+
sys = _convert_to_statespace(H)
715715
H2 = _convert_to_transfer_function(sys)
716716
np.testing.assert_array_almost_equal(H.num[0][0], H2.num[0][0])
717717
np.testing.assert_array_almost_equal(H.den[0][0], H2.den[0][0])

control/timeresp.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
atleast_1d)
8080
import warnings
8181
from .lti import LTI # base class of StateSpace, TransferFunction
82-
from .statesp import _convertToStateSpace, _mimo2simo, _mimo2siso, ssdata
82+
from .statesp import _convert_to_statespace, _mimo2simo, _mimo2siso, ssdata
8383
from .lti import isdtime, isctime
8484

8585
__all__ = ['forced_response', 'step_response', 'step_info', 'initial_response',
@@ -271,7 +271,7 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
271271
if not isinstance(sys, LTI):
272272
raise TypeError('Parameter ``sys``: must be a ``LTI`` object. '
273273
'(For example ``StateSpace`` or ``TransferFunction``)')
274-
sys = _convertToStateSpace(sys)
274+
sys = _convert_to_statespace(sys)
275275
A, B, C, D = np.asarray(sys.A), np.asarray(sys.B), np.asarray(sys.C), \
276276
np.asarray(sys.D)
277277
# d_type = A.dtype
@@ -436,7 +436,7 @@ def _get_ss_simo(sys, input=None, output=None):
436436
437437
If input is not specified, select first input and issue warning
438438
"""
439-
sys_ss = _convertToStateSpace(sys)
439+
sys_ss = _convert_to_statespace(sys)
440440
if sys_ss.issiso():
441441
return sys_ss
442442
warn = False
@@ -891,7 +891,7 @@ def _ideal_tfinal_and_dt(sys, is_step=True):
891891
dt = sys.dt if isdtime(sys, strict=True) else default_dt
892892
elif isdtime(sys, strict=True):
893893
dt = sys.dt
894-
A = _convertToStateSpace(sys).A
894+
A = _convert_to_statespace(sys).A
895895
tfinal = default_tfinal
896896
p = eigvals(A)
897897
# Array Masks
@@ -931,7 +931,7 @@ def _ideal_tfinal_and_dt(sys, is_step=True):
931931
if p_int.size > 0:
932932
tfinal = tfinal * 5
933933
else: # cont time
934-
sys_ss = _convertToStateSpace(sys)
934+
sys_ss = _convert_to_statespace(sys)
935935
# Improve conditioning via balancing and zeroing tiny entries
936936
# See <w,v> for [[1,2,0], [9,1,0.01], [1,2,10*np.pi]] before/after balance
937937
b, (sca, perm) = matrix_balance(sys_ss.A, separate=True)

0 commit comments

Comments
 (0)