8000 bdalg.connect: added and fixed index checks to fix #421; docstring up… · python-control/python-control@85cc6ca · GitHub
[go: up one dir, main page]

Skip to content

Commit 85cc6ca

Browse files
committed
bdalg.connect: added and fixed index checks to fix #421; docstring updated to indicate that Q matrix can be >2 columns
1 parent 1fc4cc1 commit 85cc6ca

File tree

2 files changed

+67
-13
lines changed

2 files changed

+67
-13
lines changed

control/bdalg.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,16 @@ def connect(sys, Q, inputv, outputv):
302302
sys : StateSpace Transferfunction
303303
System to be connected
304304
Q : 2D array
305-
Interconnection matrix. First column gives the input to be connected
306-
second column gives the output to be fed into this input. Negative
307-
values for the second column mean the feedback is negative, 0 means
308-
no connection is made. Inputs and outputs are indexed starting at 1.
305+
Interconnection matrix. First column gives the input to be connected.
306+
The second column gives the index of an output that is to be fed into
307+
that input. Each additional column gives the index of an additional
308+
input that may be optionally added to that input. Negative
309+
values mean the feedback is negative. A zero value is ignored. Inputs
310+
and outputs are indexed starting at 1 to communicate sign information.
309311
inputv : 1D array
310-
list of final external inputs
312+
list of final external inputs, indexed starting at 1
311313
outputv : 1D array
312-
list of final external outputs
314+
list of final external outputs, indexed starting at 1
313315
314316
Returns
315317
-------
@@ -325,15 +327,34 @@ def connect(sys, Q, inputv, outputv):
325327
>>> sysc = connect(sys, Q, [2], [1, 2])
326328
327329
"""
330+
inputv, outputv, Q = np.asarray(inputv), np.asarray(outputv), np.asarray(Q)
331+
# check indices
332+
index_errors = (inputv - 1 > sys.inputs) | (inputv < 1)
333+
if np.any(index_errors):
334+
raise IndexError(
335+
"inputv index %s out of bounds"%inputv[np.where(index_errors)])
336+
index_errors = (outputv - 1 > sys.outputs) | (outputv < 1)
337+
if np.any(index_errors):
338+
raise IndexError(
339+
"outputv index %s out of bounds"%outputv[np.where(index_errors)])
340+
index_errors = (Q[:,0:1] - 1 > sys.inputs) | (Q[:,0:1] < 1)
341+
if np.any(index_errors):
342+
raise IndexError(
343+
"Q input index %s out of bounds"%Q[np.where(index_errors)])
344+
index_errors = (np.abs(Q[:,1:]) - 1 > sys.outputs)
345+
if np.any(index_errors):
346+
raise IndexError(
347+
"Q output index %s out of bounds"%Q[np.where(index_errors)])
348+
328349
# first connect
329350
K = np.zeros((sys.inputs, sys.outputs))
330351
for r in np.array(Q).astype(int):
331352
inp = r[0]-1
332353
for outp in r[1:]:
333-
if outp > 0 and outp <= sys.outputs:
334-
K[inp,outp-1] = 1.
335-
elif outp < 0 and -outp >= -sys.outputs:
354+
if outp < 0:
336355
K[inp,-outp-1] = -1.
356+
elif outp > 0:
357+
K[inp,outp-1] = 1.
337358
sys = sys.feedback(np.array(K), sign=1)
338359

339360
# now trim

control/tests/bdalg_test.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,43 @@ def test_feedback_args(self):
275275
def testConnect(self):
276276
sys = append(self.sys2, self.sys3) # two siso systems
277277

278-
# feedback interconnection -3 is out of bounds
279-
Q1 = [[1, 2], [2, -3]]
280-
self.assertRaises(IndexError, connect(sys, Q1, [2], [1, 2]))
281-
278+
# feedback interconnection out of bounds: input too high
279+
Q = [[1, 3], [2, -2]]
280+
with self.assertRaises(IndexError) as context:
281+
connect(sys, Q, [2], [1, 2])
282+
# feedback interconnection out of bounds: input too low
283+
Q = [[0, 2], [2, -2]]
284+
with self.assertRaises(IndexError) as context:
285+
connect(sys, Q, [2], [1, 2])
286+
287+
# feedback interconnection out of bounds: output too high
288+
Q = [[1, 2], [2, -3]]
289+
with self.assertRaises(IndexError) as context:
290+
connect(sys, Q, [2], [1, 2])
291+
Q = [[1, 2], [2, 4]]
292+
with self.assertRaises(IndexError) as context:
293+
connect(sys, Q, [2], [1, 2])
294+
295+
# input/output index testing
296+
Q = [[1, 2], [2, -2]] # OK interconnection
297+
298+
# input index is out of bounds: too high
299+
with self.assertRaises(IndexError) as context:
300+
connect(sys, Q, [3], [1, 2])
301+
# input index is out of bounds: too low
302+
with self.assertRaises(IndexError) as context:
303+
connect(sys, Q, [0], [1, 2])
304+
with self.assertRaises(IndexError) as context:
305+
connect(sys, Q, [-2], [1, 2])
30 57AE 6+
# output index is out of bounds: too high
307+
with self.assertRaises(IndexError) as context:
308+
connect(sys, Q, [2], [1, 3])
309+
# output index is out of bounds: too low
310+
with self.assertRaises(IndexError) as context:
311+
connect(sys, Q, [2], [1, 0])
312+
with self.assertRaises(IndexError) as context:
313+
connect(sys, Q, [2], [1, -1])
314+
282315

283316
if __name__ == "__main__":
284317
unittest.main()

0 commit comments

Comments
 (0)
0