-
Notifications
You must be signed in to change notification settings - Fork 438
Use SLICOT's TB05AD in Statespace.freqresp #116
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
Comments
Hi all, I would like to work on this. I agree that evaluation of the frequency response by converting to a transfer function is problematic. I have in the last few days written a wrapper module that exposes two sets of functionality in slycots TB05AD. This needs to be tested further but the current version has been pushed to my github repo. It works for all the examples I've thrown at it though. I've also been working modyfing the statespace class so that sys.freqresp uses TB05AD. Because this is pretty basic functionality, I think getting the frequency response should still work if somebody doesn't have slycot installed. Thus, I wrote a fallback method that emulates the functionality TB05AD in python. It works pretty much the same way using scipy.linalg.hessenberg(). Since both TB05AD and linalg.hessengberg() and linalg.solv() will all need to be called the same number of times, it's unclear to me if there is anything to be gained by using the slycot function... I've never contributed to an open source project before. Do I just make a pull request when I think it's ready? |
That would be great if you want to take a cut at addressing this. We definitely want to make sure that have a fallback solution that doesn't require slycot, which will make the functionality much more accessible. When you are ready, you can just issue a pull request and someone will take a look at the code and make sure it fits the programming style of the project, has appropriate unit tests, etc. We haven't put together a style guide for the project yet, but you can get a sense of common problems by looking at some of the recently merged pull requests. |
I think the most convenient solution for this is given by Misra, Patel SIMAX 1988 Algo. 3.1 via staircase forms. If I'm not mistaken SLICOT is using a similar approach but Misra et al's solution is faster. I've tested the algorithm and it indeed provides a fast enough and accurate response. |
I'm not sure that numpy or scipy offer solvers that take advantage of the Hessenberg form (see, e.g. numpy.linalg and scipy.linalg). LAPACK itself apparently doesn't offer a Hessenberg-specific solver either, see e.g. this stackoverflow answer. So, the non-Slycot fallback could be a straight solution of C*(sI-A)\B + D; anyone who cares enough about having it run faster can install Slycot. |
The article I've linked to offers a solution precisely to that restriction, namely, you avoid solving a hessenberg form but instead, using the structure, only use LU decomposition updates which are fast to compute in any domain. |
Roryyorke, thanks for pointing out that there isn't a Hessenberg specific solver in LAPACK or scipy. That hadn't actually occurred to me yet. I've been working on this a bit this evening. For a random state space system with 50 states, 10 inputs and 5 outputs evaluated at 1000 frequency points, the slycot implementation takes about 0.1 seconds, while directly solving C(sI-A)\B takes about 0.6 seconds. Errors between the two are on the order 10^-11 for magnitude and 10^-14 for phases. In the same scenario but with 500 states, slycot finishes in about 3 seconds while direct evaluation takes about 35 seconds. Errors between the two are on the order of 10^-9 for magnitude and 10^-12 for phase. My plan is to finish writing unit tests for my current implementation. My personal feeling is that the method in the article linked by Ilayn is a good idea but it will take some time to understand and implement. I think that what I currently have will be acceptable to many users and it would be good to fix the robustness issue associated with the current implementation before optimizing for speed. |
@rabraker Are you still working on this? |
Thanks for the reminder, I had essentially forgotten about this. I think I have the function written.
Should be able to submit a PR before winter break is over.
…On 12/30/17, Richard Murray wrote:
@rabraker Are you still working on this?
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#116 (comment)
|
Fixed in PR #173. |
StateSpace.freqresp current converts to a transfer-function matrix (TFM) to evaluate the frequency response (see [1]) .
Polynomials can give numerical problems (see below), so this method should probably use
[2]
(unfortunately not currently exposed in Slycot). This technique uses an orthogonal similarity transform to make the system quicker to evaluate.One possible problem is that if one evaluates a decoupled (diagonal TFM) system in which one system has poles on the imaginary axis, I imagine the whole frequency response will be infinite. I'm not sure if this is really important.
[1]
python-control/control/statesp.py
Line 398 in cdd3e73
[2] http://slicot.org/objects/software/shared/doc/TB05AD.html
A script to demonstrate the problem:
result is
The text was updated successfully, but these errors were encountered: