Skip to content

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

Merged
merged 12 commits into from
Dec 7, 2024

Conversation

sdahdah
Copy link
Contributor

@sdahdah sdahdah commented Dec 3, 2024

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 in dkpy.

I saw there was a related issue (#325 ) and people seemed open to it. Specifically, I've added

  • control.combine() that takes an ArrayLike of TransferFunction objects, scalars, and NumPy arrays, and creates a MIMO transfer matrix, and
  • control.split() that takes a MIMO TransferFunction and returns a NumPy array with SISO TransferFunction 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.

@coveralls
Copy link

coveralls commented Dec 3, 2024

Coverage Status

coverage: 94.723% (+0.03%) from 94.689%
when pulling 1cc84a7 on sdahdah:main
into 69efbbe on python-control:main.

Copy link
Member

@murrayrm murrayrm left a 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))
Copy link
Member

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.

Copy link
Contributor Author

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.

@sdahdah
Copy link
Contributor Author

sdahdah commented Dec 4, 2024

Thanks for the feedback. Adding _tf to the function names makes sense to me.

I've also fixed the dimension checking and added a couple unit tests for that case I missed.

@sdahdah sdahdah requested a review from murrayrm December 6, 2024 21:03
@murrayrm murrayrm merged commit da55654 into python-control:main Dec 7, 2024
23 checks passed
@murrayrm murrayrm added this to the 0.10.2 milestone Feb 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants