-
Notifications
You must be signed in to change notification settings - Fork 439
Add combine()
and split()
functions for transfer matrices
#1073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution! This will make a nice addition.
Lots of little suggestions herein, mainly to keep things consistent with other code in the package.
One bigger picture question is on the function names: since these only work for transfer functions, I wonder if the function names shouldn't be combine_tf
and split_tf
(using 'tf' rather than transfer_function since the factor function is tf
).
Also, I think there needs to be some checking for size consistency. For example, consider the following code:
import control as ct
sys1 = ct.tf(ct.rss(2, 1, 2))
sys2 = ct.tf(ct.rss(2, 2, 1))
sys = ct.combine([[sys1, sys2]])
The first system has 1 output and the second system has two outputs, so I think this should generate an error. Instead, I get a 3 input (correct) by 1 output (incorrect) system. If instead I do
sys = ct.combine([[sys2, sys1]])
I get an error message:
587 for col in row:
588 for j_in in range(col.ninputs):
--> 589 num_row.append(col.num[j_out][j_in])
590 den_row.append(col.den[j_out][j_in])
591 num.append(num_row)
IndexError: list index out of range
Shouldn't both forms generate error messages (perhaps saying that there are an inconsistent number of outputs in row 1)?
try: | ||
for row in tf_array: | ||
for tfn in row: | ||
dt_list.append(getattr(tfn, "dt", None)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dt
will always exist for an InputOutputSystem
, so this can just be tfn.dt
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The combine_tf()
function allows NumPy arrays to be input as well, so you can do something like
control.combine_tf([
[np.eye(2), np.zeros((2, 1))],
[np.zeros((1, 2)), control.TransferFunction([1], [1, 0])],
])
So in that case, the NumPy arrays do not have a dt
attribute. The dt
will be taken from the TransferFunction
object in this case.
I've found this useful when creating weighting functions for optimal control problems.
Thanks for the feedback. Adding I've also fixed the dimension checking and added a couple unit tests for that case I missed. |
RE #325
I've run into a few times where it would be convenient to construct MIMO
TransferMatrix
objects from SISO ones, or the reverse. In particular, this came up as I've been working on a D-K iteration package,dkpy
. The specific implementation here is from utilities.py indkpy
.I saw there was a related issue (#325 ) and people seemed open to it. Specifically, I've added
control.combine()
that takes anArrayLike
ofTransferFunction
objects, scalars, and NumPy arrays, and creates a MIMO transfer matrix, andcontrol.split()
that takes a MIMOTransferFunction
and returns a NumPy array with SISOTransferFunction
objectss.I'm new to the
python-control
codebase, so I'm not 100% sure if I've placed things in the correct files, but I've added unit tests and would appreciate some feedback.