10000 add unit tests for checking type converstions · python-control/python-control@5356388 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5356388

Browse files
committed
add unit tests for checking type converstions
1 parent 766943b commit 5356388

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# type_conversion_test.py - test type conversions
2+
# RMM, 3 Jan 2021
3+
#
4+
# This set of tests looks at how various classes are converted when using
5+
# algebraic operations. See GitHub issue #459 for some discussion on what the
6+
# desired combinations should be.
7+
8+
import control as ct
9+
import numpy as np
10+
import operator
11+
import pytest
12+
13+
@pytest.fixture()
14+
def sys_dict():
15+
sdict = {}
16+
sdict['ss'] = ct.ss([[-1]], [[1]], [[1]], [[0]])
17+
sdict['tf'] = ct.tf([1],[0.5, 1])
18+
sdict['frd'] = ct.frd([10+0j, 9 + 1j, 8 + 2j], [1,2,3])
19+
sdict['lio'] = ct.LinearIOSystem(ct.ss([[-1]], [[5]], [[5]], [[0]]))
20+
sdict['ios'] = ct.NonlinearIOSystem(
21+
sdict['lio']._rhs, sdict['lio']._out, 1, 1, 1)
22+
sdict['arr'] = np.array([[2.0]])
23+
sdict['flt'] = 3.
24+
return sdict
25+
26+
type_dict = {
27+
'ss': ct.StateSpace, 'tf': ct.TransferFunction,
28+
'frd': ct.FrequencyResponseData, 'lio': ct.LinearICSystem,
29+
'ios': ct.InterconnectedSystem, 'arr': np.ndarray, 'flt': float}
30+
31+
#
32+
# Table of expected conversions
33+
#
34+
# This table describes all of the conversions that are supposed to
35+
# happen for various system combinations. This is written out this way
36+
# to make it easy to read, but this is converted below into a list of
37+
# specific tests that can be iterated over.
38+
#
39+
# Items marked as 'E' should generate an exception.
40+
#
41+
# Items starting with 'x' currently generate an expected exception but
42+
# should eventually generate a useful result (when everything is
43+
# implemented properly).
44+
#
45+
# Note 1: some of the entries below are currently converted to to lower level
46+
# types than needed. In particular, LinearIOSystems should combine with
47+
# StateSpace and TransferFunctions in a way that preserves I/O system
48+
# structure when possible.
49+
#
50+
# Note 2: eventually the operator entry for this table can be pulled out and
51+
# tested as a separate parameterized variable (since all operators should
52+
# return consistent values).
53+
54+
rtype_list = ['ss', 'tf', 'frd', 'lio', 'ios', 'arr', 'flt']
55+
conversion_table = [
56+
# op left ss tf frd lio ios arr flt
57+
('add', 'ss', ['ss', 'ss', 'xrd', 'ss', 'xos', 'ss', 'ss' ]),
58+
('add', 'tf', ['tf', 'tf', 'xrd', 'tf', 'xos', 'tf', 'tf' ]),
59+
('add', 'frd', ['xrd', 'xrd', 'frd', 'xrd', 'E', 'xrd', 'xrd']),
60+
('add', 'lio', ['xio', 'xio', 'xrd', 'lio', 'ios', 'xio', 'xio']),
61+
('add', 'ios', ['xos', 'xos', 'E', 'ios', 'ios', 'xos', 'xos']),
62+
('add', 'arr', ['ss', 'tf', 'xrd', 'xio', 'xos', 'arr', 'arr']),
63+
('add', 'flt', ['ss', 'tf', 'xrd', 'xio', 'xos', 'arr', 'flt']),
64+
65+
# op left ss tf frd lio ios arr flt
66+
('sub', 'ss', ['ss', 'ss', 'xrd', 'ss', 'xos', 'ss', 'ss' ]),
67+
('sub', 'tf', ['tf', 'tf', 'xrd', 'tf', 'xos', 'tf', 'tf' ]),
68+
('sub', 'frd', ['xrd', 'xrd', 'frd', 'xrd', 'E', 'xrd', 'xrd']),
69+
('sub', 'lio', ['xio', 'xio', 'xrd', 'lio', 'ios', 'xio', 'xio']),
70+
('sub', 'ios', ['xos', 'xio', 'E', 'ios', 'xos' 'xos', 'xos']),
71+
('sub', 'arr', ['ss', 'tf', 'xrd', 'xio', 'xos', 'arr', 'arr']),
72+
('sub', 'flt', ['ss', 'tf', 'xrd', 'xio', 'xos', 'arr', 'flt']),
73+
74+
# op left ss tf frd lio ios arr flt
75+
('mul', 'ss', ['ss', 'ss', 'xrd', 'xio', 'xos', 'ss', 'ss' ]),
76+
('mul', 'tf', ['tf', 'tf', 'xrd', 'tf', 'xos', 'tf', 'tf' ]),
77+
('mul', 'frd', ['xrd', 'xrd', 'frd', 'xrd', 'E', 'xrd', 'frd']),
78+
('mul', 'lio', ['xio', 'xio', 'xrd', 'lio', 'ios', 'xio', 'xio']),
79+
('mul', 'ios', ['xos', 'xos', 'E', 'ios', 'ios', 'xos', 'xos']),
80+
('mul', 'arr', ['ss', 'tf', 'xrd', 'xio', 'xos', 'arr', 'arr']),
81+
('mul', 'flt', ['ss', 'tf', 'frd', 'xio', 'xos', 'arr', 'flt']),
82+
83+
# op left ss tf frd lio ios arr flt
84+
('truediv', 'ss', ['xs', 'tf', 'xrd', 'xio', 'xos', 'xs', 'xs' ]),
85+
('truediv', 'tf', ['tf', 'tf', 'xrd', 'tf', 'xos', 'tf', 'tf' ]),
86+
('truediv', 'frd', ['xrd', 'xrd', 'frd', 'xrd', 'E', 'xrd', 'frd']),
87+
('truediv', 'lio', ['xio', 'tf', 'xrd', 'xio', 'xio', 'xio', 'xio']),
88+
('truediv', 'ios', ['xos', 'xos', 'E', 'xos', 'xos' 'xos', 'xos']),
89+
('truediv', 'arr', ['xs', 'tf', 'xrd', 'xio', 'xos', 'arr', 'arr']),
90+
('truediv', 'flt', ['xs', 'tf', 'frd', 'xio', 'xos', 'arr', 'flt'])]
91+
92+
# Now create list of the tests we actually want to run
93+
test_matrix = []
94+
for i, (opname, ltype, expected_list) in enumerate(conversion_table):
95+
for rtype, expected in zip(rtype_list, expected_list):
96+
# Add this to the list of tests to run
97+
test_matrix.append([opname, ltype, rtype, expected])
98+
99+
@pytest.mark.parametrize("opname, ltype, rtype, expected", test_matrix)
100+
def test_xferfcn_ndarray_precedence(opname, ltype, rtype, expected, sys_dict):
101+
op = getattr(operator, opname)
102+
leftsys = sys_dict[ltype]
103+
rightsys = sys_dict[rtype]
104+
105+
# Get rid of warnings for InputOutputSystem objects by making a copy
106+
if isinstance(leftsys, ct.InputOutputSystem) and leftsys == rightsys:
107+
rightsys = leftsys.copy()
108+
109+
# Make sure we get the right result
110+
if expected == 'E' or expected[0] == 'x':
111+
# Exception expected
112+
with pytest.raises(TypeError):
113+
op(leftsys, rightsys)
114+
else:
115+
# Operation should work and return the given type
116+
result = op(leftsys, rightsys)
117+
118+
# Print out what we are testing in case something goes wrong
119+
assert isinstance(result, type_dict[expected])

0 commit comments

Comments
 (0)
0