Skip to content

bandwidth feature #889

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 14 commits into from
May 15, 2023
Merged

bandwidth feature #889

merged 14 commits into from
May 15, 2023

Conversation

SCLiao47
Copy link
Contributor

@SCLiao47 SCLiao47 commented May 1, 2023

As discussed in #690, the bandwidth feature is added to the LTI class.

Implementation:

  1. The range of possible frequency is extracted from freqplot._default_frequency_range.
  2. The index, $idx$, is identified, which corresponds to the first frequency dropped by a desired amount relative to the DC gain.
  3. Bisection search (scipy.optimize.root_scalar) is used to solve for the bandwidth in the frequency bracket $[\omega[idx-1], \omega[idx]]$.

Notes:

  1. The bandwidth of a system with infinite DC gain is set to be np.nan, which follows the convention of Matlab.
  2. The above approach is chosen to solve the bandwidth instead of the scipy.optimize.root suggested in issue Create matlab's equivalent to bandwidth. #690. The suggested approach requires an initial guess and might fail, e.g., a system with a resonant peak at a frequency higher than the bandwidth.

Notes on git commits:
git commits are duplicated as I was having some issues to push. I pulled (suggested by git error hint), and it prompts "merge made by the 'recursive' strategy. Not sure whether this is a problem.

@murrayrm
Copy link
Member

murrayrm commented May 2, 2023

Thanks for this contribution, @SCLiao47.

I think the _bandwidth method should be renamed to bandwidth and put in the LTI class in lti.py. With that change, you should be able to get rid of the bandwidth methods in TransferFunction and StateSpace, since they will get the method from their parent class. You will probably have to override bandwidth in FrequencyResponseData since the dcgain method is not implemented there.

I have some other suggestions, but if you agree with the change above then I would start there, since it will move things around.

@coveralls
Copy link

coveralls commented May 2, 2023

Coverage Status

Coverage: 94.652% (+0.003%) from 94.649% when pulling ab68562 on SCLiao47:feature_bandwidth into c06a205 on python-control:main.

@SCLiao47
Copy link
Contributor Author

SCLiao47 commented May 3, 2023

@murrayrm thank you for the comments and suggestions.

The _bandwidth method was implemented as I was following the _dcgain method in the LTI class in lti.py. But as you suggested renaming it to bandwidth can simplify the code structure. One other thing I wasn't so sure about is "what other classes should have the bandwidth method." The FrequencyResponseData class is one of them as you mentioned, and I wonder if there are others as well?

[Regarding development flow]

  • I'm still learning the development flow on GitHub. The contribute wiki page (step 11) mentioned that I could keep working on the branch under my own fork. However, does the new commit directly sync to this pull request?
  • One other thing I notice while following the contribute wiki page. It seems like GitHub has renamed the master branch to main. Maybe there needs some edition to the wiki page but I'm not so sure.

@sawyerbfuller
Copy link
Contributor

Hi @SCLiao47

i think only the classes that derive from LTI should get a bandwidth method: tf, ss, and frd.

As for your question about development: adding new commits to your branch is very seamless. Add them to your own branch (on your own computer) and then, when you do git push origin, they will appear right here on your pull request.

Our main branch name is grandfathered in as master.

@murrayrm
Copy link
Member

murrayrm commented May 3, 2023

I've updated the documentation to refer to the main branch (master is deprecated).

@SCLiao47
Copy link
Contributor Author

SCLiao47 commented May 4, 2023

@sawyerbfuller @murrayrm thank you for the suggestions and comments. I've restructured the bandwidth method in the LTI class in lti.py.

FRD

As for the FrequencyResponseData class, I wonder how you would suggest implementing the bandwidth method for it? At the moment, the class seems to not support interpolating, which is needed to infer DC gain and compute the bandwidth. However, this will probably fall outside of the scope of this feature. Is there a way to get around this?

Development flow

I think I need to make sure I understand the flow and might need some clarification. In step 8 of the contribute wiki page, the intention is to update and sync the local code (on my machine) to the upstream version (python-control/python-control).

What happened in the instructions:

  1. After clicking sync fork and Update branch on github.com, my forked repo (SCLiao47/python-control) will be sync to the upstream version. Both repos are remote on github.
  2. The first chunk of command lines (on my machine) is to sync my local main branch to the main of the forked repo on GitHub.
  3. The second chunk of command lines is to bring the commits in the local feature branch to the local main. The git rebase allows resolving conflict before merging local feature into upstream main and maintaining a cleaner git graph.

If the above understanding is correct, I wonder about the following:

  1. The local main is not intended to be developed and made changed from my understanding. Why do we need to git push after merge origin/main?
  2. Can we skip sync fork on github.com and replace git merge origin/main with git merge upstream/main? This will have the same result that the local main will be synced to upstream main, right?

@murrayrm murrayrm merged commit 15ed92c into python-control:main May 15, 2023
@bnavigator
Copy link
Contributor

What happened in the instructions:

  1. After clicking sync fork and Update branch on github.com, my forked repo (SCLiao47/python-control) will be sync to the upstream version. Both repos are remote on github.

Correct.

  1. The first chunk of command lines (on my machine) is to sync my local main branch to the main of the forked repo on GitHub.

Correct.

  1. The second chunk of command lines is to bring the commits in the local feature branch to the local main. The git rebase allows resolving conflict before merging local feature into upstream main and maintaining a cleaner git graph.

Yes, the commands make sure that your local feature branch also has all the recent changes of your recently updated local main which should now be at the same commit as upstream/main

If the above understanding is correct, I wonder about the following:

  1. The local main is not intended to be developed and made changed from my understanding. Why do we need to git push after merge origin/main?

If you didn't change anything in your local main before the merge, you don't need to push. The push is a noop then. In that case the merge will be a fast-forward and it is sufficient to alternatively just.

git switch main; git pull

But if you have changes in local main (which you should not), you will notice here.

  1. Can we skip sync fork on github.com and replace git merge origin/main with git merge upstream/main? This will have the same result that the local main will be synced to upstream main, right?

Yes, but then you need the push so that your origin/main does not stay behind. These sequences are equivalent, assuming origin/main is already the tracked remote branch of your local clone.

  1. git switch main; git fetch --all; git merge upstream/main; git push
    
  2. on main press "sync fork", then:
    git switch main; git pull
    

@murrayrm murrayrm added this to the 0.9.4 milestone Jun 7, 2023
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.

5 participants