Skip to content

Improved default time vector and handling for time response functions step, impulse, and initial #420

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 11 commits into from
Jul 11, 2020
Merged

Improved default time vector and handling for time response functions step, impulse, and initial #420

merged 11 commits into from
Jul 11, 2020

Conversation

sawyerbfuller
Copy link
Contributor

@sawyerbfuller sawyerbfuller commented Jun 18, 2020

step, impulse, and initial, and step_info, as well as their matlab equivalents

  • before, it always returned a time vector with unit time intervals, rather than sys.dt time intervals.
  • introduced a new utility function _get_default_tfinal(sys) _get_ideal_tfinal_and_dt(sys) that computes a time window equal to seven times the slowest time constant of sys, inspired by scipy.signal.ltisys._default_response_times(A, n), that can also accommodate discrete-time systems

@murrayrm
Copy link
Member

Looks like this broke some unit tests?

…d number of steps rather than complete time vector in timeresponse functions
@sawyerbfuller sawyerbfuller changed the title fixed default response time for time response of discrete-time functi… fix default response time for discrete-time systems Jun 19, 2020
@coveralls
Copy link

coveralls commented Jun 19, 2020

Coverage Status

Coverage increased (+0.07%) to 84.34% when pulling e155a15 on sawyerbfuller:fix-discrete-step-response into ce3a231 on python-control:master.

@sawyerbfuller
Copy link
Contributor Author

Ok take a look, fixed the tests. Also implemented a convenience that you can now specify T as a scalar in step, impulse, and initial to quickly change the length of the simulation. Easier than specifying the whole T vector every time (which you can still do). This is similar to how you can do it in bode, and how Matlab does it. I think these conveniences will not break compatibility with extant code.

@sawyerbfuller
Copy link
Contributor Author

I’m not sure how solidified things are considered to be in the package, so I’m making guesses, trying balance adding functionality I would like to have, and avoiding breaking backwards compatibility. Please let me know if I am going too far in one direction or the other!

If these changes seem ok, I can add a couple more unit tests.

@sawyerbfuller
Copy link
Contributor Author

Looks like this PR addresses half of the issue of issue #287 , but I essentially just used the same coarse algorithm to estimate a reasonable time horizon that scipy uses. And expanded it to work with Discrete-time systems.

@murrayrm
Copy link
Member

This looks good to me. I need to check it a bit more carefully, but nice to have a proper method for computing response times and some enhancements on how to specify the final time.

@sawyerbfuller
Copy link
Contributor Author

sawyerbfuller commented Jun 21, 2020

Great. I took a stab at solving the other half of #287, automatically generating a default dt from the fastest system eigenvalues as well, if the time vector is not specified.

  • And added unit tests.

@sawyerbfuller sawyerbfuller changed the title fix default response time for discrete-time systems Improved default time vector and handling for time response functions step, impulse, and initial Jun 25, 2020
@sawyerbfuller
Copy link
Contributor Author

I hope that for now this is maybe a “good enough” version of the more comprehensive solution that ilayn was working on in #287 – that also adds discrete-time support.

Copy link
Member

@murrayrm murrayrm left a comment

Choose a reason for hiding this comment

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

Changes look fine in general. A couple of questions regarding updates to unit tests (to make sure I understand) and some questions about documentation. No changes required for approval unless you feel they are justified.

@@ -27,7 +27,7 @@ def test_sisotool(self):
assert_array_almost_equal(ax_rlocus.lines[2].get_data(),initial_point_2)

# Check the step response before moving the point
step_response_original = np.array([ 0., 0.02233651, 0.13118374, 0.33078542, 0.5907113, 0.87041549, 1.13038536, 1.33851053, 1.47374666, 1.52757114])
step_response_original = np.array([0. , 0.0217, 0.1281, 0.3237, 0.5797, 0.8566, 1.116 , 1.3261, 1.4659, 1.526 ])
Copy link
Member

Choose a reason for hiding this comment

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

Why do these values need to be changed? The system is the same and so shouldn't the step response be the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The function in scipy that used to be used to generate the time vector, scipy.signal.ltisys._default_response_times(A, n) uses numpy.linspace without the keyword arg endpoint=False so it returns n+1 data points instead of n. The new function does, so it generates only n data points, which is consistent with how other functions in python-control seem to do it. (thus the slightly changed values). Let me know if you have a preference to go back to n+1 datapoints. My thinking is, if you ask for n datapoints, that ought to be how many you get.

@@ -59,7 +59,7 @@ def test_sisotool(self):
assert_array_almost_equal(ax_mag.lines[0].get_data()[1][10:20],bode_mag_moved)

# Check if the step response has changed
step_response_moved = np.array([[ 0., 0.02458187, 0.16529784 , 0.46602716 , 0.91012035 , 1.43364313, 1.93996334 , 2.3190105 , 2.47041552 , 2.32724853] ])
step_response_moved = np.array([0. , 0.0239, 0.161 , 0.4547, 0.8903, 1.407 , 1.9121, 2.2989, 2.4686, 2.353 ])
Copy link
Member

Choose a reason for hiding this comment

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

Same question as above. Just want to make sure I understand the need for the change.

Time vector (argument is autocomputed if not given)
T: array-like or number, optional
Time vector, or simulation time duration if a number (time vector is
autocomputed if not given)
Copy link
Member

Choose a reason for hiding this comment

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

Should we document someplace (perhaps in doc/) how this is autocomputed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't find an obvious place in doc about where to put it so I put in the docstring of step_response and referred back to that docstring in impuse, initial, and step_info.


T_num: number, optional
Number of time steps to use in simulation if T is not provided as an
array (autocomputed if not given); ignored if sys is discrete-time.
Copy link
Member

Choose a reason for hiding this comment

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

Document someplace how these are autocomputed?

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