Skip to content

Commit

Permalink
make iosys_test.py compatible with current source code state
Browse files Browse the repository at this point in the history
revert this commit when merging into or with python-control#400 and python-control#431
  • Loading branch information
bnavigator committed Aug 20, 2020
1 parent 411467e commit f0fcc08
Showing 1 changed file with 18 additions and 135 deletions.
153 changes: 18 additions & 135 deletions control/tests/iosys_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ class TSys:
"""Return some test systems"""
# Create a single input/single output linear system
T.siso_linsys = ct.StateSpace(
[[-1, 1], [0, -2]], [[0], [1]], [[1, 0]], [[0]])
[[-1, 1], [0, -2]], [[0], [1]], [[1, 0]], [[0]], 0)

# Create a multi input/multi output linear system
T.mimo_linsys1 = ct.StateSpace(
[[-1, 1], [0, -2]], [[1, 0], [0, 1]],
[[1, 0], [0, 1]], np.zeros((2, 2)))
[[1, 0], [0, 1]], np.zeros((2, 2)), 0)

# Create a multi input/multi output linear system
T.mimo_linsys2 = ct.StateSpace(
[[-1, 1], [0, -2]], [[0, 1], [1, 0]],
[[1, 0], [0, 1]], np.zeros((2, 2)))
[[1, 0], [0, 1]], np.zeros((2, 2)), 0)

# Create simulation parameters
T.T = np.linspace(0, 10, 100)
Expand Down Expand Up @@ -281,7 +281,7 @@ def test_algebraic_loop(self, tsys):
linsys = tsys.siso_linsys
lnios = ios.LinearIOSystem(linsys)
nlios = ios.NonlinearIOSystem(None, \
lambda t, x, u, params: u*u, inputs=1, outputs=1)
lambda t, x, u, params: u*u, inputs=1, outputs=1, dt=0)
nlios1 = nlios.copy()
nlios2 = nlios.copy()

Expand Down Expand Up @@ -310,7 +310,7 @@ def test_algebraic_loop(self, tsys):
iosys = ios.InterconnectedSystem(
(lnios, nlios), # linear system w/ nonlinear feedback
((1,), # feedback interconnection (sig to 0)
(0, (1, 0, -1))),
(0, (1, 0, -1))),
0, # input to linear system
0 # output from linear system
)
Expand All @@ -331,7 +331,7 @@ def test_algebraic_loop(self, tsys):

# Algebraic loop due to feedthrough term
linsys = ct.StateSpace(
[[-1, 1], [0, -2]], [[0], [1]], [[1, 0]], [[1]])
[[-1, 1], [0, -2]], [[0], [1]], [[1, 0]], [[1]], 0)
lnios = ios.LinearIOSystem(linsys)
iosys = ios.InterconnectedSystem(
(nlios, lnios), # linear system w/ nonlinear feedback
Expand Down Expand Up @@ -374,7 +374,7 @@ def test_rmul(self, tsys):
# Also creates a nested interconnected system
ioslin = ios.LinearIOSystem(tsys.siso_linsys)
nlios = ios.NonlinearIOSystem(None, \
lambda t, x, u, params: u*u, inputs=1, outputs=1)
lambda t, x, u, params: u*u, inputs=1, outputs=1, dt=0)
sys1 = nlios * ioslin
sys2 = ios.InputOutputSystem.__rmul__(nlios, sys1)

Expand Down Expand Up @@ -414,7 +414,7 @@ def test_feedback(self, tsys):
# Linear system with constant feedback (via "nonlinear" mapping)
ioslin = ios.LinearIOSystem(tsys.siso_linsys)
nlios = ios.NonlinearIOSystem(None, \
lambda t, x, u, params: u, inputs=1, outputs=1)
lambda t, x, u, params: u, inputs=1, outputs=1, dt=0)
iosys = ct.feedback(ioslin, nlios)
linsys = ct.feedback(tsys.siso_linsys, 1)

Expand Down Expand Up @@ -740,7 +740,7 @@ def test_named_signals(self, tsys):
inputs = ('u[0]', 'u[1]'),
outputs = ('y[0]', 'y[1]'),
states = tsys.mimo_linsys1.states,
name = 'sys1')
name = 'sys1', dt=0)
sys2 = ios.LinearIOSystem(tsys.mimo_linsys2,
inputs = ('u[0]', 'u[1]'),
outputs = ('y[0]', 'y[1]'),
Expand Down Expand Up @@ -797,121 +797,6 @@ def test_named_signals(self, tsys):
np.testing.assert_array_almost_equal(ss_feedback.C, lin_feedback.C)
np.testing.assert_array_almost_equal(ss_feedback.D, lin_feedback.D)

def test_sys_naming_convention(self, tsys):
"""Enforce generic system names 'sys[i]' to be present when systems are created
without explicit names."""

ct.InputOutputSystem.idCounter = 0
sys = ct.LinearIOSystem(tsys.mimo_linsys1)
assert sys.name == "sys[0]"
assert sys.copy().name == "copy of sys[0]"

namedsys = ios.NonlinearIOSystem(
updfcn = lambda t, x, u, params: x,
outfcn = lambda t, x, u, params: u,
inputs = ('u[0]', 'u[1]'),
outputs = ('y[0]', 'y[1]'),
states = tsys.mimo_linsys1.states,
name = 'namedsys')
unnamedsys1 = ct.NonlinearIOSystem(
lambda t,x,u,params: x, inputs=2, outputs=2, states=2
)
unnamedsys2 = ct.NonlinearIOSystem(
None, lambda t,x,u,params: u, inputs=2, outputs=2
)
assert unnamedsys2.name == "sys[2]"

# Unnamed/unnamed connections
uu_series = unnamedsys1 * unnamedsys2
uu_parallel = unnamedsys1 + unnamedsys2
u_neg = - unnamedsys1
uu_feedback = unnamedsys2.feedback(unnamedsys1)
uu_dup = unnamedsys1 * unnamedsys1.copy()
uu_hierarchical = uu_series*unnamedsys1

assert uu_series.name == "sys[3]"
assert uu_parallel.name == "sys[4]"
assert u_neg.name == "sys[5]"
assert uu_feedback.name == "sys[6]"
assert uu_dup.name == "sys[7]"
assert uu_hierarchical.name == "sys[8]"

# Unnamed/named connections
un_series = unnamedsys1 * namedsys
un_parallel = unnamedsys1 + namedsys
un_feedback = unnamedsys2.feedback(namedsys)
un_dup = unnamedsys1 * namedsys.copy()
un_hierarchical = uu_series*unnamedsys1

assert un_series.name == "sys[9]"
assert un_parallel.name == "sys[10]"
assert un_feedback.name == "sys[11]"
assert un_dup.name == "sys[12]"
assert un_hierarchical.name == "sys[13]"

# Same system conflict
with pytest.warns(UserWarning):
unnamedsys1 * unnamedsys1

def test_signals_naming_convention(self, tsys):
"""Enforce generic names to be present when systems are created
without explicit signal names:
input: 'u[i]'
state: 'x[i]'
output: 'y[i]'
"""
ct.InputOutputSystem.idCounter = 0
sys = ct.LinearIOSystem(tsys.mimo_linsys1)
for statename in ["x[0]", "x[1]"]:
assert statename in sys.state_index
for inputname in ["u[0]", "u[1]"]:
assert inputname in sys.input_index
for outputname in ["y[0]", "y[1]"]:
assert outputname in sys.output_index
assert len(sys.state_index) == sys.nstates
assert len(sys.input_index) == sys.ninputs
assert len(sys.output_index) == sys.noutputs

namedsys = ios.NonlinearIOSystem(
updfcn = lambda t, x, u, params: x,
outfcn = lambda t, x, u, params: u,
inputs = ('u0'),
outputs = ('y0'),
states = ('x0'),
name = 'namedsys')
unnamedsys = ct.NonlinearIOSystem(
lambda t,x,u,params: x, inputs=1, outputs=1, states=1
)
assert 'u0' in namedsys.input_index
assert 'y0' in namedsys.output_index
assert 'x0' in namedsys.state_index

# Unnamed/named connections
un_series = unnamedsys * namedsys
un_parallel = unnamedsys + namedsys
un_feedback = unnamedsys.feedback(namedsys)
un_dup = unnamedsys * namedsys.copy()
un_hierarchical = un_series*unnamedsys
u_neg = - unnamedsys

assert "sys[1].x[0]" in un_series.state_index
assert "namedsys.x0" in un_series.state_index
assert "sys[1].x[0]" in un_parallel.state_index
assert "namedsys.x0" in un_series.state_index
assert "sys[1].x[0]" in un_feedback.state_index
assert "namedsys.x0" in un_feedback.state_index
assert "sys[1].x[0]" in un_dup.state_index
assert "copy of namedsys.x0" in un_dup.state_index
assert "sys[1].x[0]" in un_hierarchical.state_index
assert "sys[2].sys[1].x[0]" in un_hierarchical.state_index
assert "sys[1].x[0]" in u_neg.state_index

# Same system conflict
with pytest.warns(UserWarning):
same_name_series = unnamedsys * unnamedsys
assert "sys[1].x[0]" in same_name_series.state_index
assert "copy of sys[1].x[0]" in same_name_series.state_index

def test_named_signals_linearize_inconsistent(self, tsys):
"""Mare sure that providing inputs or outputs not consistent with
updfcn or outfcn fail
Expand Down Expand Up @@ -1012,9 +897,10 @@ def test_lineariosys_statespace(self, tsys):


def test_duplicates(self, tsys):
nlios = ios.NonlinearIOSystem(lambda t,x,u,params: x, \
lambda t, x, u, params: u*u, \
inputs=1, outputs=1, states=1, name="sys")
nlios = ios.NonlinearIOSystem(lambda t, x, u, params: x,
lambda t, x, u, params: u * u,
inputs=1, outputs=1, states=1,
name="sys", dt=0)

# Duplicate objects
with pytest.warns(UserWarning, match="Duplicate object"):
Expand All @@ -1023,20 +909,17 @@ def test_duplicates(self, tsys):
# Nonduplicate objects
nlios1 = nlios.copy()
nlios2 = nlios.copy()
with pytest.warns(UserWarning, match="copy of sys") as record:
with pytest.warns(UserWarning, match="Duplicate name"):
ios_series = nlios1 * nlios2

assert "copy of sys_1.x[0]" in ios_series.state_index.keys()
assert "copy of sys.x[0]" in ios_series.state_index.keys()

# Duplicate names
iosys_siso = ct.LinearIOSystem(tsys.siso_linsys)
nlios1 = ios.NonlinearIOSystem(None,
lambda t, x, u, params: u * u,
inputs=1, outputs=1, name="sys")
inputs=1, outputs=1, name="sys", dt=0)
nlios2 = ios.NonlinearIOSystem(None,
lambda t, x, u, params: u * u,
inputs=1, outputs=1, name="sys")
inputs=1, outputs=1, name="sys", dt=0)

with pytest.warns(UserWarning, match="Duplicate name"):
ct.InterconnectedSystem((nlios1, iosys_siso, nlios2),
Expand All @@ -1045,10 +928,10 @@ def test_duplicates(self, tsys):
# Same system, different names => everything should be OK
nlios1 = ios.NonlinearIOSystem(None,
lambda t, x, u, params: u * u,
inputs=1, outputs=1, name="nlios1")
inputs=1, outputs=1, name="nlios1", dt=0)
nlios2 = ios.NonlinearIOSystem(None,
lambda t, x, u, params: u * u,
inputs=1, outputs=1, name="nlios2")
inputs=1, outputs=1, name="nlios2", dt=0)
with pytest.warns(None) as record:
ct.InterconnectedSystem((nlios1, iosys_siso, nlios2),
inputs=0, outputs=0, states=0)
Expand Down

0 comments on commit f0fcc08

Please sign in to comment.