-
Notifications
You must be signed in to change notification settings - Fork 438
Implement ERA, change api to TimeResponseData #1024
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
55ac0ed
to
614a080
Compare
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.
Overall this looks good. I found a few small things that you might want to update.
control/modelsimp.py
Outdated
impulse-response data from which the StateSpace model is estimated, | ||
1D or 3D array. |
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.
impulse → Impulse (start sentence with a capital letter) and try to fit on one line (if less than 75 characters).
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.
Done.
control/modelsimp.py
Outdated
impulse-response data from which the StateSpace model is estimated, | ||
1D or 3D array. | ||
data : TimeResponseData | ||
impulse-response data from which the StateSpace model is estimated. |
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.
impose → Impulse
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.
Done.
control/modelsimp.py
Outdated
Number of rows in Hankel matrix. | ||
Default is 2*r. |
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.
Put on a single line (here and below).
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.
Done!
control/modelsimp.py
Outdated
True indicates discrete time with unspecified sampling time, | ||
positive number is discrete time with specified sampling time. | ||
It can be used to scale the StateSpace model in order to match | ||
the impulse response of this library. | ||
Default values is True. |
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.
Can probably have fewer lines by going out to column 75 before wrapping. Default value sentence doesn't need to start on a new line.
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.
Tried and Done!
control/modelsimp.py
Outdated
def era(arg, r, m=None, n=None, dt=True, transpose=False): | ||
r"""era(YY, r) |
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.
Optional: to be consistent with the longer naming style we are using in python-control, I suggest we call the function eigensys_realization
and then define era = eigensys_realization
at the bottom of the file (see freqplot.py
for some example). We should also (but not here) redefine the other functions in this file (minimal_realization
, balanced_realization
, etc).
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.
Done! See #1028
I get a warning ../python-control/doc/generated/control.era.rst: WARNING: document isn't included in any toctree I could not exclude the alias name era from autosummary. __all__=[eigensys_realization, era] How to exclude era from autosummary? SOLUTION: The Solution is, to delete the generated folder in doc. Then the sphinx/autosummary does not use old files. |
c5f0cbe
to
4ea1d82
Compare
4ea1d82
to
250c448
Compare
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.
some minor suggestions, and a question.
control/modelsimp.py
Outdated
where `response` is an `TimeResponseData` object, and `YY` is 1D or 3D | ||
array and r is an integer. |
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.
where `response` is an `TimeResponseData` object, and `YY` is 1D or 3D | |
array and r is an integer. | |
where `data` is a `TimeResponseData` object, `YY` is a 1D or 3D | |
array, and r is an integer. |
response is more specific than data, perhaps better?
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.
response
or data
? Not sure.
For me, the function time_response_plot which uses data
for time_response, is the blueprint.
The plotting functions use data
for input.
bode_plot
The response data types use response
for input.
NyquistResponseData
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.
Done.
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.
OK, in my PR #1022 I initially used response
instead of data
. I will go with data
for now.
@roryyorke @murrayrm what should we use?
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.
I prefer response
as it's more specific, but the main thing is to be consistent within the ERA docstring(s).
control/modelsimp.py
Outdated
Number of columns in Hankel matrix. Default is 2*r. | ||
dt : True or float, optional | ||
True indicates discrete time with unspecified sampling time, | ||
positive number is discrete time with specified sampling time. It |
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.
positive number is discrete time with specified sampling time. It | |
and a positive float means discrete time with the specified sampling time. It |
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.
Done.
control/modelsimp.py
Outdated
True indicates discrete time with unspecified sampling time, | ||
positive number is discrete time with specified sampling time. It | ||
can be used to scale the StateSpace model in order to match the | ||
impulse response of this library. Default is True. |
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.
I don't understand the idea of "impulse response of this library" - what does library mean here?
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 library "python-control" uses a unit area impulse "delta = 1/dt" for dt > 0 and a unit impulse "delta = 1" for dt = True.
The dt
parameter is used to create a discrete time state space system (A,B,C,D,dt) to match an impulse response generated by control.impulse_response.
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.
Done!
I change the text to " It can be used to scale the StateSpace model in order to match the unit-area impulse response of python-control. "
Is there a better way to explain that behavior. Should we add something to Library conventions in order to explain the unit-area impulse response of python-control?
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.
Ah, thanks, now I understand.
One possibly-not-obvious side-effect of using True
is that it has a value of 1, so one gets debatably natural discrete-time behaviour in that case.
The unit-area convention is documented in timeresp.impulse_resp
under Notes
, I suggest a reference to that.
control/modelsimp.py
Outdated
""" | ||
raise NotImplementedError('This function is not implemented yet.') | ||
def block_hankel_matrix(Y, m, n): |
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.
suggest making this top-level _block_hankel
.
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.
Done!
A reduced order model sys=StateSpace(Ar,Br,Cr,Dr,dt). | ||
S : array | ||
Singular values of Hankel matrix. Can be used to choose a good r | ||
value. |
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.
given this, is there an alternative interface with a minsigma
argument which could be used to choose r based on the singular values instead? (or maybe tol, with minsigma = tol * maxsigma ?)
This probably a bit out-of-scope, and if the user needs this capability it is simple enough to implement in their own code.
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.
I have thought about it, but I will not be adding this feature at this time.
I don't know the literature on this topic well enough, but I know that there are papers that study the choice of r.
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.
Postponed. Possible improvement in the future.
control/modelsimp.py
Outdated
# balanced realizations | ||
Sigma_inv = np.diag(1./np.sqrt(S[0:r])) | ||
Ar = Sigma_inv @ Ur.T @ Hl @ Vhr.T @ Sigma_inv | ||
Br = Sigma_inv @ Ur.T @ Hf[:,0:p]*dt |
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.
It looks like the reference here is "Algorithm 1" of the arxiv paper.
Why does dt
makes an appearance here? I don't see any mention of sample rate or sample period in the referenced paper. It must be needed since you have dt=0.1 in the spring-damper model unit test -- I guess I'm missing something obvious?
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.
ERA in the paper assumes a unit impulse response "delta = 1". There is no dt in the paper.
However, python control generates a unit-area impulse response "delta = 1/dt". See also: #812, #977.
In other words, the impulse responses of StateSpace(A,B,C,D,dt=True) and StateSpace(A,B,C,D,dt=0.1) differ by a scaling.
The dt parameter in era can be used to create the right StateSpace model.
Alternative:
We could also rescale the output data by Y=Y*dt in order to get the unit impulse response instead of the unit-area impulse response.
Overall, my goal is that impulse_response, era, markov and StateSpace should work well together.
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.
Done. I added a little comment to indicate the intentional use of Br*dt.
Is there a more elegant way to achieve this?
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.
LGTM. If you think it's useful, add a reference to timeresp.impulse_response
.
This PR implements the ERA method. Related to #1002 and #847