Skip to content

LQR using SciPy #683

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 7 commits into from
Dec 26, 2021
Merged

LQR using SciPy #683

merged 7 commits into from
Dec 26, 2021

Conversation

murrayrm
Copy link
Member

This PR updates the mateqn module to allow the use of SciPy linear algebra functions as a replacement for Slycot functions. Among other things, this allows the use of the lqr command without having to install Slycot.

I implemented this by changing all of the mateqn functions (lyap, care, dare, etc) to accept at method keyword that can either be scipy or slycot. The default value for method is slycot if it is installed, otherwise scipy, so there is no change in behavior if you have Slycot.

Other changes:

  • Updated lqr to call care rather than replicating the code and cleaned up a lot of the code in mateqn to be more Pythonic.
  • Modified the slycot_check function so that it stores the result of checking whether slycot can be imported rather than trying to import every time the function is called.
  • Implemented a function for checking size and properties of matrices passed to mateqn functions (mateqn._check_shape) that provides more consistent errors (this also required updating some of the unit tests).
  • Modified dare to solve the generalized Sylvester equation using slycot.sg02ad rather than using slycot.sg02md to solve the simplified form of the discrete algebraic Riccati equation because there seems to be an error in the way that stabilizing is handled in sg02md (it returns the closed loop eigenvalues in the wrong order). (I'm working on generating a concrete counterexample for posting to Slycot.)

@murrayrm murrayrm mentioned this pull request Dec 24, 2021
@coveralls
Copy link

coveralls commented Dec 24, 2021

Coverage Status

Coverage increased (+0.7%) to 93.433% when pulling 801f282 on murrayrm:lqr_scipy into 4f681ab on python-control:master.

Copy link
Contributor

@bnavigator bnavigator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A few minor comments:

Comment on lines +585 to +590
elif method == 'slycot':
return _dare_slycot(A, B, Q, R, S, E, stabilizing)

else:
_check_shape("B", B, n, m)
_check_shape("Q", Q, n, n, square=True, symmetric=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe _dare_slycot() and _dare_scipy() should be on the same level?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the asymmetry is annoying. I left it this way to avoid changing code that was working. In care everything is in the main function, so at some point we should clean all of these up to be more uniform (either a single function or use _method uniformly).

@bnavigator bnavigator merged commit a05351b into python-control:master Dec 26, 2021
@murrayrm murrayrm added this to the 0.9.1 milestone Dec 30, 2021
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