You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I notice that the simulation functions: step_response, impulse_response, for discrete time systems is not very intuitive, and is also inconsistent with matlab's behavior (I sort of have the habit of checking matlab documentation for a python-control function if there are suprises).
we would expect T to be the time instances that correspond to values in y (matlab behavior), but it turns out not the case. I got T.shape = (25,) while y.shape=(1, 10). The same behavior can be observed for other time-domain functions for discrete-time systems (continuous-time systems are alright).
However, this behavior is not intuitive to users. I would prefer it to be the actual time-array that is used to compute the impulse response. This information can be used, say, for plotting. Also, with the current behavior, the returned time-array T does not convey any information.
I did a bit of looking into this. Some observations and issues:
The 'bug' in this code is something that is apparently inherited from the scipy.signal.dlsim(), which is what step_response() eventually calls (through a call to forced_response()). In particular, it appears that if you pass dlsim() a time vector that doesn't match the sampling time, it doesn't generate an error and, furthermore, it returns whatever you passed it (same behavior as what was noticed here).
There is a further inconsistency in the way that T=None is handled in the control simulation functions for discrete time systems: the time vector that is generated will have dt=1 independent of what the actually sampling time for the system is.
There may also be some issues with the way that the default response time is determined when you pass T=None for discrete time systems. For step_response() and initial_response() this is supposed to be based on the dynamics matrix A. This uses the _default_response_times() function from scipy.signal.ltisys, but I believe that function assumes continuous time (need to check).
I think that the correct behavior for discrete time systems is the following (which would match MATLAB):
The values of the output argument T should always match the times at which the corresponding outputs Y are obtained. This is consistent with the idea that you plot the outputs of a simulation function by using commands of the form
t, y = step_response(sys)
plot(t, y)
If you pass an explicit set of sampling times for a discrete time system, the time increment should match the sampling time (with dt=True being interpreted as a sampling time of 1). In this case, the output argument T will match the input argument T.
If you omit the sampling time, the value of T will be determined based on either the input signal (for forced_response() or the time constants coming from the system dynamics. In either case, the difference between time points should be equal to the sampling time of the system (or 1 if dt=True).
For forced_response(), the length of the input vector U should match the length of the time vector T.
The good news is that a relatively modest set of changes are required to fix all of these things up. Comments welcome on whether I am missing anything, but I'll start putting together test cases for the properties above and then updating the code.
Activity
ilayn commentedon Oct 25, 2018
It is just giving you back the time array but since the sampling time of the system doesn't match the time increment it is resampling the bounds.
hungpham2511 commentedon Nov 22, 2018
That's right.
However, this behavior is not intuitive to users. I would prefer it to be the actual time-array that is used to compute the impulse response. This information can be used, say, for plotting. Also, with the current behavior, the returned time-array T does not convey any information.
murrayrm commentedon Dec 28, 2018
I agree that this behavior is non-intuitive and probably incorrect. Marking as a bug to be fixed in the next release.
murrayrm commentedon Jan 5, 2019
I did a bit of looking into this. Some observations and issues:
The 'bug' in this code is something that is apparently inherited from the
scipy.signal.dlsim(), which is whatstep_response()eventually calls (through a call toforced_response()). In particular, it appears that if you passdlsim()a time vector that doesn't match the sampling time, it doesn't generate an error and, furthermore, it returns whatever you passed it (same behavior as what was noticed here).There is a further inconsistency in the way that
T=Noneis handled in thecontrolsimulation functions for discrete time systems: the time vector that is generated will havedt=1independent of what the actually sampling time for the system is.There may also be some issues with the way that the default response time is determined when you pass
T=Nonefor discrete time systems. Forstep_response()andinitial_response()this is supposed to be based on the dynamics matrixA. This uses the_default_response_times()function fromscipy.signal.ltisys, but I believe that function assumes continuous time (need to check).I think that the correct behavior for discrete time systems is the following (which would match MATLAB):
Tshould always match the times at which the corresponding outputsYare obtained. This is consistent with the idea that you plot the outputs of a simulation function by using commands of the formIf you pass an explicit set of sampling times for a discrete time system, the time increment should match the sampling time (with
dt=Truebeing interpreted as a sampling time of 1). In this case, the output argumentTwill match the input argumentT.If you omit the sampling time, the value of
Twill be determined based on either the input signal (forforced_response()or the time constants coming from the system dynamics. In either case, the difference between time points should be equal to the sampling time of the system (or 1 ifdt=True).For
forced_response(), the length of the input vectorUshould match the length of the time vectorT.The good news is that a relatively modest set of changes are required to fix all of these things up. Comments welcome on whether I am missing anything, but I'll start putting together test cases for the properties above and then updating the code.
murrayrm commentedon Apr 11, 2019
Fixed in PR #286
tomaszG247 commentedon Apr 17, 2019
Hello,
@murrayrm :After stumbling upon this issue in 0.8.1, I installed 0.8.2, which I believe only partly solves the issue:
When running
I am still having the problem that youtd is 2D while T is 1D. The error reads
x and y must have same first dimension, but have shapes (9,) and (1, 9)murrayrm commentedon Apr 20, 2019
Will look into this and see if I can generate a unit test that exhibits the error, so that we can nail this one down.
murrayrm commentedon Apr 21, 2019
This behavior has been fixed in PR #295. Can close as soon as that PR is merged.
murrayrm commentedon May 2, 2019
PR #295 is merged. Closing this (again).