-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
ENH: Split signal.lti into subclasses, part of #2912 #4576
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
Link to issue: gh-2912 Related issues: gh-2973, gh-3259 Mailing list discussion: http://thread.gmane.org/gmane.comp.python.scientific.devel/19427 |
@befelix this PR now has a merge conflict, can you rebase it? |
Seems mostly backwards compatible. I found one issue so far, related to the setters and the removal of
|
Is the added
as far as I can tell. |
I've rebased the code, should make it easier to review. The regression with l.C seems very weird, especially since that's something I've definitely tested before making the PR. I'll have a look! Just for completeness here are your comments from the mailing list:
""" I agree about the pythonic names, would make code using these classes super readable. Sos wasn't around when I wrote the PR, I'll check it out. |
Hmm, SOS was merged in January so was in the code already, but I guess it hadn't made its way into http://docs.scipy.org/doc/scipy-dev/reference/signal.html by then. Double checked that it's included now. |
Not sure what the best names would be by the way. |
Or |
The copy method is mostly there to support the setters for objects from different lti subclasses in a central location (i.e. the lti master class), rather than cluttering the subclasses with all the unrelated getters and setters (the code gets a bit ugly otherwise).
What happens in the code is that the setter for poles in the lti class converts our object to the tf class This is the best solution I came up with, though on second thought copy() should probably a private method. Any ideas how to make this prettier are appreciated. If you would prefer to have all the setters/getters in the subclasses then it's possible to remove the copy function. |
@@ -500,6 +476,399 @@ def freqresp(self, w=None, n=10000): | |||
return freqresp(self, w=w, n=n) | |||
|
|||
|
|||
class tf(lti): | |||
"""Linear Time Invariant system class in state-space form. |
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.
this one is transfer function form
Regression with Regarding the names: I can't think of a very pretty solution either. Maybe ss/tf/zpk is not that bad after all :/. |
I prefer capital letters for class names, whether it's |
Sorry I haven't been following this. So overall, this will still behave like an LTI class that stores whatever coefficients you initialized it with, and can output every other form when asked? |
@Eric89GXL Yeah I'm confused about the standard as well. Officially it's capital letters for classes I think, but then that doesn't really seem to be followed. The original lti class was already lower case, so at least in the short term there's probably nothing we can do about that. @endolith The original LTI class had attributes for all systems (ss,zpk,tf). Changing one of the elements caused an |
The standard is simply PEP8, however in the past it hasn't always been followed (Scipy itself is as old as the first draft of PEP8). That's especially true for So proposal: let's follow PEP8 here, no matter whether we choose |
+1 for following PEP8 from me, might as well start moving in that direction |
I agree that PEP8 would be great. My question would be how far we can go with that given backwards compatibility and wether it makes sense to fix only parts of those.:
If we can't change those maybe it's better to use the wrong style, but consistently? |
@rgommers Regarding the SOS class. There is some initial code in https://github.com/befelix/scipy/tree/sos_class to add them to to the lti class. However, this causes a bunch of problems, since there is no conversion function sos<-->ss (for example |
So as far as I can tell the PR should be okay now code-wise, leaving only the questions of the SOS system and the API (i.e. naming and what should the inputs to ss/tf/zpk be: Currently it's just *args. Maybe it should be more like proposed in #3259, where they take one input, which can be a touple of parameters or an lti system? Regarding the naming of variables I'm not sure and some input would be very welcome. Options seem to be
I'm not very keen on the last one; mostly since SsSystem looks weird to me. I think the first one is probably the best balance of readability and length. Given that these functions are in Regarding the StateSpace system matrices, we could maybe have both capital- (for backwards compatiblity) and lower case letters (for consistency)? One last thought: I think in the long-run it would make sense to depreciate the cross-subclasses setters (e.g. setting the poles on a StateSpace system). They encourage extremely bad behaviour, require code that is not nice, and are, imho, not very useful. |
Shouldn't that be StateSpace? |
Yes, yes it should be :) |
+1 for I think it should be okay to have +1 for a single input argument instead of *args. It seems to lend itself to easier interpretation and implementation in my head, but I haven't thought about it extensively. |
For the names, how are these intended to be used? If you're only ever going to create objects using a generic What I'm imagining for "easy filtering" is like this:
where
I'm not sure, I was reading about this but don't fully understand it: http://www.bisonacademy.com/ECE461/Lectures/06%20State%20Space.pdf Controller and observer canonical forms are made from the tf coefficients, Jordan form is made from the partial fraction expansion coefficients (like Also remember that SS supports MIMO systems and the others don't, etc. |
Alright, that should wrap up all the of @Eric89GXL's comments. Is there anything else that needs to change? |
@befelix rebasing is our preferred way of fixing merge conflict, so this looks good. |
This reverts commit fdd29d0.
I just quickly browsed over the code again, and quite like the look of this API now. |
|
||
|
||
class TestStateSpace(object): | ||
"""Test StateSpace class""" |
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.
This docstring is a bit superfluous. For all the docstrings for test_
methods, can you please change those to comments? That keeps the output of signal.test(verbose=2)
sane (with docstrings, those get displayed instead of the test class/method names).
Is there any hope of getting this merged before the 0.16 branching? |
@befelix I think it's possible, but I'm kind of running out of time. @Eric89GXL can you verify that all your comments are addressed and this is okay to merge for you? Then I'm happy to merge this after a quick last sanity check. |
freqresp -- frequency response of a continuous-time LTI system. | ||
lti -- Linear time invariant system base class. | ||
StateSpace -- Linear time invariant system in state space form. | ||
TransferFunction -- Linear time invariant system in tranfer function form. |
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.
"tranfer" typo
Other than my minor complains, LGTM. |
Alright, thanks for the last comments, they're all implemented. |
ENH: Split signal.lti into subclasses, part of #2912
Okay, in it goes. Thanks @befelix! |
And thanks @Eric89GXL and @endolith for reviewing. |
Thanks again everyone. In case you feel like looking through even more subclasses, there is a follow-up PR at #4881, which extends this framework to discrete-time systems. It would be great if you could give comments on that as well! |
new classes: ss, tf, zpk