StateSpace.zero() now supports MIMO systems by calcmogul · Pull Request #205 · python-control/python-control

@calcmogul

scipy.linalg.eigvals() is used to solve the generalized eigenvalue
problem. The zero locations used in the unit test were obtained via the
zero() function in MATLAB R2017b with two more digits of precision added
based on the results of StateSpace.zero().

@coveralls

Coverage Status

Coverage decreased (-0.2%) to 77.707% when pulling 8607fb0 on calcmogul:mimo-zeros into 601b581 on python-control:master.

3 similar comments

@coveralls

Coverage Status

Coverage decreased (-0.2%) to 77.707% when pulling 8607fb0 on calcmogul:mimo-zeros into 601b581 on python-control:master.

@coveralls

Coverage Status

Coverage decreased (-0.2%) to 77.707% when pulling 8607fb0 on calcmogul:mimo-zeros into 601b581 on python-control:master.

@coveralls

Coverage Status

Coverage decreased (-0.2%) to 77.707% when pulling 8607fb0 on calcmogul:mimo-zeros into 601b581 on python-control:master.

@coveralls

Coverage Status

Coverage decreased (-13.1%) to 64.747% when pulling f66315d on calcmogul:mimo-zeros into 601b581 on python-control:master.

@rabraker

Calculating the zeros directly as a generalized eigenvalue problem only works if the system is square. The paper you linked talks about the non-square case on page 9.

Since square systems are common, I think this is a worthwhile pull request, but I do think the limitation should be noted in the doc string. I suppose a non-square system will cause scipy.linalg.eigvals() to throw its own error, but I think it would be better to catch it here, since we can provide a more enlightening error message.

@calcmogul

control.StateSpace.__init__() already requires that A is a square matrix and throws otherwise. However, documenting that zero()'s implementation details assume a square matrix seems reasonable. scipy.linalg.eigvals() throws ValueError('expected square matrix') if either argument is non-square, but the message is opaque.

@ilayn

Alternatively (if available) ab08nd from slycot can be used to get the transmission zeros directly.

@calcmogul The squareness is about the system shape, 3 inputs and 2 outputs system cannot be used with the generalized eigenvalue method.

@calcmogul

scipy.linalg.eigvals() is used to solve the generalized eigenvalue
problem. The zero locations used in the unit test were obtained via the
zero() function in MATLAB R2017b with two more digits of precision added
based on the results of StateSpace.zero().

@calcmogul

Oh, that makes a lot more sense. The latest patch uses AB08ND if available to produce square matrices scipy.linalg.eigvals() can use. I'd like the non-Slycot version to have feature parity though, so I'm going to keep working on that. The paper's suggestion of augmenting the non-square matrices with pseudo-random numbers isn't returning sensible eigenvalues for the test case (it always returns all 1's), but the input matrices to eigvals() look like what the paper specifies. I didn't like the idea of random numbers anyway.

I'm going to look into translating AB08ND's algorithm into Python instead. The logic and Fortran syntax hasn't been hard to follow so far.

This was referenced

Jul 2, 2018