GSoC 2023 : Improving and Expanding the Functionalities of SymPy's Control Module by Anurag Bhat
This report summarizes my work during GSoC 2023, on the project Improving and Expanding the Functionalities of SymPy's Control Module. A step by step, weekly development of the project can be found at https://faze-geek.github.io
I am Anurag Bhat, a fourth-year undergraduate student pursuing a major in Computer Science from the Indian Institute of Technology (IIT) Jodhpur. I'm particularly interested in the fields of mathematics, algorithms and fast computations. I usually work on open source PyData repositories and would love to contribute and collaborate on more interesting projects.
The project plan was focused on multiple areas of control theory that were required to be added to sympy.control
.
For an in depth understanding of the proposed plan, you can go through my submitted proposal.
- Community Bonding
- Go through the codebase and understand files relevant to my project.
- Set up documentation pages which were not required during the contributing phase.
- Investigate the code for small scale optimisations, mistakes and redundant code.
- Phase 1
- Addition of online illustrations and textbook examples solved using SymPy's control package.
- Addition of plots - Root Locus plot, Nichols plot and Nyquist plot.
- Phase 2
- Burn down bugs identified and mentioned in the proposal.
- Compare functions with other Control System Toolkits like
MATLAB
andpython-control
and implement them after discussions.
- Phase 3
- Add a symbolic State Space model.
- Attempt to add online illustrations and textbook examples.
-
#25147 : Minor Change in Control Plots Documentation. This PR corrects the
See Also
docstring of theramp_response_plot
. -
#25161 : Remove unused test variable from
test_control_plots
.
-
#25227 : Add Examples in the Control System Package. This PR adds 5 textbook examples to
doc/src/guides/physics/control_problems.rst
on topics of Transfer Function, Transfer Function Matrix, Laplace Transform, Configurations and Plots. -
#25251 : Add Root Locus and Nichols plot in control plots. This PR added the above mentioned plots. The results were pretty consistent with
MATLAB
, but it had dependencies on numpy and matplotlib. I learned how to make sampling of points efficient and accurate. -
#25287 : Add Instantiation methods for Transfer Functions. This PR adds methods
from_coeff_lists
andfrom_zpk
to instantiate Transfer Functions. -
#25305 : Refactor Pole Zero Plot to use Algebraic methods. This PR replaces the numerical methods from numpy with algebraic methods from sympy.
-
#25575 : Implementation of the Nyquist Plot. This PR adds the above mentioned plot, which is still a work in progress as it has a dependency on matplotlib.
-
#25234 : Adjust Scale of Pole Zero Plot for better understanding of poles and zeros. This issue points out how the current plot is misleading due to the
1e-5
range of the imaginary axis. -
#25235 : Shift physics example files to
guides\physics\
. This issue suggests that the example.rst
files of all physics modules must be shifted toguides\physics-guides\
for better categorization and access by users. -
#25236 : Better representation of Transfer Function expressions. This issue asks for suggestions from the community, about visual improvements in complex Series, Parallel or Feedback systems.
-
#25304 : Refactoring Control Plots: Replace Numerical methods with Algebraic methods as much as possible. This issue is a check for all 7 plots currently present in
physics/control/control_plots.py
, which are implemented using numpy. To complete this issue, sympy would need to support thescatter
plot from matplotlib. -
#25471 : Status of the Nyquist Frequency Plot. This issue mentions the blockers stalling the Nyquist plot.
-
#25576 : Feature Request : Support for Arrows in Sympy's plotting module. This issue is a request for arrows so that the trajectory of the frequency plot can be drawn.
-
#25239 : Handle the division of Transfer Function instances. This PR implements division
/
similar to multiplication and returns a Series object. -
#25335 : Add method to evaluate system response of Transfer Functions. This PR adds
evalfr
, which returns the system response at any point on the real or complex plane. -
#25418 : Add System Margins for Transfer Functions. This PR adds
phase_margin
andgain_margin
and supports tests fromMATLAB
. -
#25463 : Support phase unwrapping in frequency response. This PR adds the
phase_unwrap
argument in thebode_plot
to correct the discontinuities caused when phase angle reached -180 or +180. -
#25555 : Update implementation to evaluate system response at given frequency. This PR rectified certain mistakes like naming and return format, in the previous implementation of
eval_frequency
.
-
#25308 : How should division of Transfer Functions be handled? This issue discusses if the ValueError should be replaced by a Series object.
-
#25315 : How should
subs()
be handled for Transfer Functions? This issue discusses if it should be supported as it is common to evaluate an input transfer function at a particular frequencyjw
. -
#25326 : Restrict Inputs to only valid Transfer Functions. This issue suggests that any symbolic input should not be allowed as a transfer function. If sympy wants to allow time delay terms, there could be some kind of heuristics to check if that input could possibly be a valid output from a Laplace transform.
-
#25340 : Use of Minimal Realization. This issue proves that some functions should output the object in a minimal format, to avoid inaccurate results as the order of the input increases.
-
#25347 : Printing Improvement: Is it possible to print an expression in specific order of a variable. This issue discusses various methods, so that the Transfer Function can be expressed in descending orders of powers of s (the complex variable of the system).
-
#25473 : Add StateSpace class for control package. This PR adds the State Space model to
lti.py
.
-
#25502 : Solved Problems to tackle using State Space class. This issue has documented the examples with should be added to
doc/src/guides/physics/control_problems.rst
. -
#25635 : Planner on future implementations in the State Space Class. This issue documents all the implementations that were planned but could not be completed due to lack of time.
-
Refactor the old plots - All the plots that were implemented previously namely - Pole Zero, Step Response, Impulse Response, Ramp Response, Bode Magnitude and Bode Phase plot use
numpy
andmatplotlib
. The numerical methods were used for speed but they sacrifice on precision. Sympy's symbolic methods are used in the first place to the precision they provide, hence these numerical methods should be replaced by algebraic methods.
Davide, a fellow contributor has been revamping the plotting module. I would like to point out this roadmap, according to whichSymPy
will soon have it's ownplot_list
function after which this refactoring could be done with ease. -
Complete newly implemented plots - The plots added in this GSoC project namely - Root Locus, Nichols and Nyquist plot are draft pull requests. The have clear ideas to follow and some comments which can be addressed once
SymPy
no longer depends uponmatplotlib
andnumpy
. -
Implementations for the
StateSpace
class -- Solve examples mentioned in #25502 and add them to the
control_problems
file . The required functionality is already supported in the pull request. - Add a symbolic solver (and a numeric solver if required) with the help of the ODE module to solve
x' = Ax + Bu
form.
Make the class more feature rich:
- Read about Laub's or Horner's method to evaluate system transfer function at complex frequency. This will be the equivalent of
eval_frequency
for Transfer Functions. - Add Feedback interconnection between 2 state space LTI systems.
- Other features can be picked up on comparison with
MATLAB
andpython-control
.
- Solve examples mentioned in #25502 and add them to the
-
Adding a Discrete time model - A Discrete-time
TransferFunction
and Discrete-timeStateSpace
model. Discussing the API and making things compatible with the current implementation is a challenging task. It has already been a component of theMATLAB
CST package from the beginning. As a control module, we have to realize that all signals in practical real life use are always discrete in nature. This is my motivation for wanting this model, so that users can have extensive use ofSymPy’s
CST package in their projects.
I am quite satisfied with the current state of the control module right now. A good number of issues which were looming since previous GSoC's have now been resolved. My overall target of developing a robust control module by the end of this summer seems closer than ever. The next phase of development should target heavy testing of added implementations and discussions towards the unresolved issues.
I had been hearing amazing things about GSoC since the past 2 years and my tenure lived upto its expectation. I had an amazing experience past summer working for SymPy. Apart from improving my coding skills, I got a feel of how documentation and testing driven software development works. I am thankful to SymPy for this experience.
I am highly grateful to my mentors, Nikhil Maan and Smit Lunagariya for always being there whenever I was stuck and have guided me in every possible way. I would also like to thank the org admins like Oscar Benjamin for being readily available throughout the summer and pitching in for code reviews whenever they had time.
I plan to keep contributing to SymPy, trying to finish the work proposed in the Future Work. I would also like to pitch in as a co-mentor for modules such as the control, series and calculus module for GSoC 2024 if required.