All Projects → namannimmo10 → Google-Summer-of-Code-with-SymPy

namannimmo10 / Google-Summer-of-Code-with-SymPy

Licence: other
This repository showcases my proposal, final report, and the work done during Google Summer of Code 2020 with the SymPy project.

Projects that are alternatives of or similar to Google-Summer-of-Code-with-SymPy

srijan-gsoc-2020
Healthcare-Researcher-Connector Package: Federated Learning tool for bridging the gap between Healthcare providers and researchers
Stars: ✭ 17 (+41.67%)
Mutual labels:  gsoc, gsoc-2020
RobustAndOptimalControl.jl
Robust and optimal design and analysis of linear control systems
Stars: ✭ 25 (+108.33%)
Mutual labels:  control-systems, control-theory
gsoc
Project Tracker for GSoC 2020: Creating Quality models using @grimoirelab and @chaoss metrics
Stars: ✭ 21 (+75%)
Mutual labels:  gsoc, gsoc-2020
GSoC-Proposal
Google Summer of Code 2019, 2020 proposal for GNU Radio
Stars: ✭ 18 (+50%)
Mutual labels:  gsoc-2020
GSoC-Proposals-Archive
This repository contains Accepted and Rejected proposals for various Google Summer of Code organizations.
Stars: ✭ 47 (+291.67%)
Mutual labels:  gsoc
PyConSys
Python Control System : Create control loops and let the AI set the PID parameters
Stars: ✭ 21 (+75%)
Mutual labels:  control-systems
community
Keptn community content: governance, community management, project infrastructure etc.
Stars: ✭ 42 (+250%)
Mutual labels:  gsoc
gsoc-2022
List of project ideas for contributors applying to the Google Summer of Code program in 2022 (GSoC 2022).
Stars: ✭ 44 (+266.67%)
Mutual labels:  gsoc
GSoC-Ideas
CloudCV GSoC 2021 Ideas
Stars: ✭ 95 (+691.67%)
Mutual labels:  gsoc
The-Beginners-Guide-to-Google-Summer-of-Code-GSoC
The Beginners Guide to Google Summer of Code (GSoC)
Stars: ✭ 33 (+175%)
Mutual labels:  gsoc
accepted-gsoc-proposals
A repository containing links to accepted proposals for GSoC, Hopefully this helps someone write a better proposal and get accepted into the program
Stars: ✭ 115 (+858.33%)
Mutual labels:  gsoc
pytheory
Music Theory for Humans.
Stars: ✭ 1,358 (+11216.67%)
Mutual labels:  sympy
SLICOT-Reference
SLICOT - A Fortran subroutines library for systems and control
Stars: ✭ 19 (+58.33%)
Mutual labels:  control-systems
FARNN
Code that trains cancer soft-robot networks
Stars: ✭ 15 (+25%)
Mutual labels:  control-systems
Soccer
Tired of searching the melange website for GSoC projects? Here's something that's visually pleasing and fast.
Stars: ✭ 15 (+25%)
Mutual labels:  gsoc
gsoc-meta-k8s
Project tracker for my GSoC project - Improve TPRs - for the Kubernetes organization (CNCF).
Stars: ✭ 23 (+91.67%)
Mutual labels:  gsoc
CC33Z
Curso de Ciência da Computação
Stars: ✭ 50 (+316.67%)
Mutual labels:  sympy
CRAWLAB-Code-Snippets
Small pieces of code for use in CRAWLAB research
Stars: ✭ 12 (+0%)
Mutual labels:  control-systems
PyLMI-SDP
[UNMAINTAINED] Symbolic linear matrix inequalities (LMI) and semi-definite programming (SDP) tools for Python
Stars: ✭ 20 (+66.67%)
Mutual labels:  sympy
control
Control in C++
Stars: ✭ 17 (+41.67%)
Mutual labels:  control-systems

img img2

GSoC 2020 @SymPy

This repository showcases my proposal, and the work done (final report) during Google Summer of Code 2020 with the SymPy project. SymPy is a computer algebra system written in pure python.

It all started here:

img3

The SymPy community is very welcoming and supportive. I sent an email to the SymPy mailing list around Feb 3rd, 2020, asking the community about the scope of adding a new Control Systems engineering package. Initially, their opinions were against this, and students were advised to focus on improving existing SymPy packages, instead of adding new packages (core or not).

I continued to show my interest in this project and guess what?? Here is the response I got finally (Thanks, Jason):

img4

Project: Control Theory - Implement a control systems package

Student: Naman Gera (namannimmo10)

Official Mentors:

Since this was a big project and I had to develop a package from scratch, I got a lot of help from other members of the SymPy development team and even Control theory experts. I would also really like to thank S.Y. Lee, Oscar Benjamin, Eric Wieser, Ilhan Polat, and Richard Murray for constantly reviewing my PRs and discussing the API designs with me.

Work done:

My main focus was to implement in SymPy, a basic Control Systems functionality from scratch. This can be used by Control engineers or professors/students to solve various control theory related problems. Being a part of SymPy, this is purely symbolic in nature. The advantage of this package over other packages/libraries (which are great, btw!) like harold and python-control is that the solutions obtained from it are highly accurate and do not rely on numerical methods to approximate the solutions. The solutions obtained are in a compact form that can be used for further analysis. Documentation is available at Control API and Control Intro.

PULL REQUESTS -

Major additions:

  • (Merged) sympy/sympy#19390 - Adds TransferFunction, Series, Parallel, and Feedback classes for control package.
  • (Merged) sympy/sympy#19896 - Adds other useful methods in TransferFunction class.
  • (Merged) sympy/sympy#19761 - Adds TransferFunctionMatrix class in physics.control.

Miscellaneous PRs opened in the summer:

Future Work:

  • Add StateSpace class for creating State space models
  • Further improve the documentation of control package. Add a couple more examples to show us the users how to use the implemented functionality as they tend to use any software more if the docs are top-notch.
  • Graphical analyses: root_locus, pole_zero, bode, and nyquist plots

Examples:

This section consists of the main features that were added under sympy.physics.control.

A transfer function is used for representing linear, time-invariant (LTI) systems that can be strictly described by a ratio of polynomials. Here's how we can construct a transfer function:

>>> from sympy.abc import s, a
>>> from sympy.physics.control import TransferFunction
>>> numerator = 2*s + a
>>> denominator = s**2 + s + 1
>>> G = TransferFunction(numerator, denominator, s) # third arg is a complex variable of the Laplace transform
>>> G
TransferFunction(a + 2*s, s**2 + s + 1, s)
>>> G.num
a + 2*s
>>> G.den
s**2 + s + 1
>>> G.var
s

Now using pretty-printing (which is pretty dope ;) to make it actually look like a ratio of polynomials:

>>> from sympy import pprint
>>> pprint(G)
 a + 2s  
──────────
 2        
s  + s + 1

>>> from sympy import init_printing
>>> init_printing(use_unicode=True)
>>> G2 = TransferFunction(s**4 - 2*s**3 + 5*s + 4, s + 4, s)
>>> -G2 # negate a transfer function
   4      3          
- s  + 2s  - 5s - 4
─────────────────────
        s + 4        
>>> G2**3 # take the integer power
                     34      3          ⎞ 
⎝s  - 2s  + 5s + 4⎠ 
──────────────────────
              3       
       (s + 4)        
>>> _.expand() # now expand the num and den after taking the power
 12      11       10      9       8       7        6       5        4       3        2             
s   - 6s   + 12s   + 7s  - 48s  + 12s  + 123s  - 30s  - 192s  + 29s  + 300s  + 240s + 64
───────────────────────────────────────────────────────────────────────────────────────────────────
                                        3       2                                                  
                                       s  + 12s  + 48s + 64

You can use a Float or an Integer (or other constants) as num and den:

>>> G3 = TransferFunction(1/2, 3, a)
>>> G3.num
0.500000000000000
>>> G3.den
3
>>> G3.var
a

Other features used in computations:

>>> TransferFunction(s + 2, s**2 - 9, s).dc_gain() # compute the gain of the response as the freq approaches 0.
-2/9
>>> TransferFunction(a, s, s).dc_gain()
∞⋅sign(a)
>>> G4 = TransferFunction((1 - s)**2, (s + 1)**2, s)
>>> G4.is_stable() # checks for the asymptotic stability
True
>>> G4.poles()
[-1, -1]
>>> G4.zeros()
[1, 1]
>>> G4.is_proper
True
>>> G4.is_biproper
True
>>> G4.is_strictly_proper
False

>>> from sympy import symbols
>>> c, p, d0, d1, d2 = symbols('c, p, d0:3')
>>> num, den = c*p, d2*p**3 + d1*p**2 - d0
>>> G5 = TransferFunction(num, den, p)
>>> G5.subs({c: 2, d0: 3, d1: 2, d2: 5})
      2p      
───────────────
   3      2    
5p  + 2p  - 3
>>> G5.subs({c: 2, d0: 3, d1: 2, d2: 5}).evalf()
        2.0p        
─────────────────────
     3        2      
5.0p  + 2.0p  - 3.0
>>> G5.xreplace({c: 3.0})
       3.0p       
───────────────────
          2       3
-d+ d₁⋅p  + d₂⋅p 

>>> from sympy import factor
>>> factor(TransferFunction(s - 1, s**2 - 2*s + 1, s))
 s - 1  
────────
       2
(s - 1) 
>>> TransferFunction((p + 3)*(p - 1), (p - 1)*(p + 5), p).simplify()
p + 3
─────
p + 5

Now, let's do some SISO transfer function algebra:

>>> init_printing(use_unicode=False)
>>> G6 = TransferFunction(s + 1, s**2 + s + 1, s)
>>> G6
  s + 1   
----------
 2        
s  + s + 1
>>> G7 = TransferFunction(s - p, s + 3, s)
>>> G7
-p + s
------
s + 3 
>>> G8 = TransferFunction(4*s**2 + 2*s - 4, s - 1, s)
>>> G8
   2          
4*s  + 2*s - 4
--------------
    s - 1     
>>> G9 = TransferFunction(a - s, s**2 + 4, s)
>>> G9
a - s 
------
 2    
s  + 4

>>> G6 + G7 # just adding two TFs will leave them unevaluated
  s + 1      -p + s
---------- + ------
 2           s + 3 
s  + s + 1         
>>> # `.doit()` will evaluate the result above
>>> # `.rewrite(TransferFunction)` does the same.
>>> _.doit()
         ⎛ 2        ⎞                  
(-p + s)⋅⎝s  + s + 1+ (s + 1)⋅(s + 3)
───────────────────────────────────────
                  ⎛ 2        ⎞         
          (s + 3)⋅⎝s  + s + 1>>> G8 - G9
   2                   
4s  + 2s - 4   -a + s
────────────── + ──────
    s - 1         2    
                 s  + 4
>>> G6 * G9s + 1   ⎞ ⎛a - s ⎞
⎜──────────⎟⋅⎜──────⎟
⎜ 2        ⎟ ⎜ 2    ⎟
⎝s  + s + 1⎠ ⎝s  + 4>>> G8 * G9 + G6 - G7 # do all at the same time2          ⎞                              
⎜4s  + 2s - 4⎟ ⎛a - ss + 1      p - s
⎜──────────────⎟⋅⎜──────⎟ + ────────── + ─────
⎝    s - 1     ⎠ ⎜ 22           s + 3s  + 4s  + s + 1
>>> (G8 * G9 + G6).rewrite(TransferFunction)
        ⎛ 2        ⎞ ⎛   2          ⎞                   ⎛ 2    ⎞
(a - s)⋅⎝s  + s + 1⎠⋅⎝4s  + 2s - 4+ (s - 1)⋅(s + 1)⋅⎝s  + 4⎠
────────────────────────────────────────────────────────────────
                         ⎛ 2    ⎞ ⎛ 2        ⎞                  
                 (s - 1)⋅⎝s  + 4⎠⋅⎝s  + s + 1

A class for representing negative feedback interconnection between input/output systems was also added - Feedback. Here's how solve a basic block diagram problem (having a negative feedback) with that class:

img6

>>> from sympy.physics.control import Feedback
>>> G = plant = TransferFunction(2*s**2 + 5*s + 1, s**2 + 2*s + 3, s)
>>> C = controller = TransferFunction(5*(s + 2), s + 10, s)
>>> velocity = Feedback(plant, controller)
>>> velocity2          ⎞       
        ⎜2s  + 5s + 1⎟       
        ⎜──────────────⎟       
        ⎜  2           ⎟       
        ⎝ s  + 2s + 3 ⎠       
───────────────────────────────
    ⎛   212s  + 5s + 1⎟ ⎛5s + 10⎞
─ + ⎜──────────────⎟⋅⎜────────⎟
12           ⎟ ⎝ s + 10 ⎠
    ⎝ s  + 2s + 3>>> velocity.doit() # this gives the resultant closed-loop transfer function2          ⎞ ⎛   2          ⎞               
               (s + 10)⋅⎝s  + 2s + 3⎠⋅⎝2s  + 5s + 1⎠               
──────────────────────────────────────────────────────────────────────
⎛         ⎛ 2          ⎞              ⎛   2          ⎞⎞ ⎛ 2          ⎞
⎝(s + 10)⋅⎝s  + 2s + 3+ (5s + 10)⋅⎝2s  + 5s + 1⎠⎠⋅⎝s  + 2s + 3>>> velocity.doit().simplify() # we can further cancel poles and zeros2          ⎞              
             (s + 10)⋅⎝2s  + 5s + 1⎠              
────────────────────────────────────────────────────
          ⎛   2          ⎞            ⎛ 25⋅(s + 2)⋅⎝2s  + 5s + 1+ (s + 10)⋅⎝s  + 2s + 3

My GSoC Experience and Learnings:

I've been writing weekly blog-posts documenting my journey during GSoC. The blog is hosted at namannimmo.me/emerald. This experience was so amazing and complete and I learned lots of different things; I can't write them all in here.

But, here are a few:

  1. Having to adjust to my team members' different timezones was definitely a challenge. I also loved the challenge of working with a remote team and leaving my comfort zone of talking in person to work on something
  2. I also learned written communication. Writing accurately is difficult, so I had to learn how to convey my thoughts well enough, because we were working remotely, right?
  3. I had not implemented any package from scratch before, so this was a challenge in itself. But the mentors were helpful enough and discussed everything with me - they were readily available for discussions
  4. If could repeat this again, I would do so. This community is so welcoming, even if you come up with a naïve approach of solving a particular problem, they will help you to improve the code even further because we had to adhere to the SymPy standards
  5. Since a lot of people get confused in the beginning, I've written a detailed answer on Quora for students preparing for GSoC. Here's my answer to "How can I apply and prepare for Google Summer of Code?" - hope this helps!

Edit: I'm mentoring for SymPy in GSoC 2021.

:wq for now.


Naman Gera (namannimmo)

Email | GSoC blog | StackOverflow | Quora

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].