July 05, 2020

This blog describes the 6th week of the official program and the 2nd week of Phase 2. By the end of this week, Compound Distributions framework is ready as targeted and I would now focus on the Joint Distributions in the upcoming weeks of this Phase.

June 30, 2020

This blog post describes my progress in Week 5 of Google Summer of Code 2020!

I ended up Week 4 by adding unit tests and a rough draft for Series and Parallel classes. Now in this week, to complete the implementation, we decided to add another...

June 28, 2020

Key highlights of this week’s work are:

  • Fixed RecursionError and Timeout in limit evaluations

    • The Recursion Errors in limit evaluations were mainly due to the fact that the indeterminant form of 1**oo was not handled accurately in the mrv() function of the Gruntz algorithm. So, some minor changes were required to fix those.

      The major issue was to handle those cases which were timing out. On deep digging, we identified that the cancel() function of polytools.py was the reason. Thus, we decided to completely transform the cancel() function to speed up its algorithm. Now after this major modification, many testcases were failing as the cancel() function plays an important role in simplifying evaluations and is thus used at many places across the codebase. Therefore, a lot of time was spent in debugging and rectifying these testcases.

      Finally we were able to merge this, enhancing the limit evaluation capabilities of SymPy.

This blogs describes the week 5, the beginning week of the Phase 2. Phase 2 will be mostly focused on Compound Distributions which were stalled from 2018, and additions to Joint Distributions.

June 23, 2020

With this, the fourth week and phase 1 of GSoC 2020 is over. Here I will give you a brief summary of my progress this week.

The initial days were spent mostly on modifying unit tests for Series and Parallel classes which I added in the...

June 21, 2020

I spent this week working on the implementation of the ParametricIntegral class.

Modifying API of ParametricRegion

When I was writing the test cases, I realized that the API of the ParametricRegion could be improved. Instead of passing limits as a dictionary, tuples can be used. So I modified the API of the ParametricRegion class. The new API is closer to the API of the integral class and more intuitive. I made a separate PR for this change to make it easy for reviewers.

Example of the new API:

ParametricRegion( ( x+y, x*y ), (x, 0, 2), (y, 0, 2))

Handling scalar fields with no base scalars

As discussed in previous posts, we decided to not associate a coordinate system with the parametric region. Instead, we assume that the parametricregion is defined in the coordinate system of the field of which the integral is being calculated. We calculate the position vector and normal vector of the parametric region using the base scalars and vectors of the fields. This works fine for most cases. But when the field does not contain any base scalar or vector in its expression, we cannot extract the coordinate system from the field.

ParametricIntegral(150, circle)
# We cannot determine the coordinate system from the field. 
# To calculate the line integral, we need to find the derivative of the position vector.
# This is not possible until we know the base vector of the field

To handle this situation, I assign a coordinate system C to the region. This does not affect the result in any way as the result is independent of it. It just allows the existing algorithm to work in this case.

Separate class for vector and scalar fields

Francesco suggested making separate classes based on the nature of the field: vector and scalar. I am open to this idea. But I think it will be more easy and intuitive for the users if they can use the same class to calculate the integral. I do not think they are different enough from a user’s perspective to have a separate interface.

Maybe we can have a function vectorintegrate which returns the object of ParametricVectorIntegral or ParametricScalarIntegral depending on the nature of the field. This can work for other types of integrals too. Suppose we implement a class ImplicitIntegral to calculate the integral over an implicit region. The vectorintegrate function can then return an object of ImplicitIntegral object by identifying the region is defined implicitly. I think this will be great. I will have more discussion with Francesco on this aspect.

Topological sort of parameters

When evaluating double integral, the result some times depend upon the order in which the integral is evaluated. If the bounds of one parameter u depend on another parameter v, we should integrate first with respect to u and then v.

For example, consider the problem of evaluating the area of the triangle.

T = ParametricRegion((x, y), (x, 0, 2), (y, 10 - 5*x))

The area of the triangle is 10 units and should be independent of the order parameters are specified at the time of object initialization. But the double integral depends on the order of integration.

>>> integrate(1, (x, 0, 2), (y, 10 - 5*x))
20 - 10*x
>>> integrate(1, (y, 0, 10 - 5*x), (x, 0, 2))
10

So parameters must be passed to integrate in the correct order. To overcome this issue, we topologically sort the parameters. SymPy already had a function to perform topologically sort in its utilities module. I implemented a function that generates the graph and passes it to the topological_sort function. This made my work easy.

Long computation time of Integrals

Some integrals are taking too long to compute. When base scalars in the field are replaced by their parametric equivalents, the expression of the field becomes large. Further, the integrand is the dot product of the field with a vector or product of the field and the magnitude of the vector. The integrate function takes about 20-30 seconds to calculate the integral. I think this behavior is due to the expression of integrand growing structurally despite it being simple.

For example,

>>>solidsphere = ParametricRegion((r*sin(phi)*cos(theta), r*sin(phi)*sin(theta), r*cos(phi)),\
                                (r, 0, 2), (theta, 0, 2*pi), (phi, 0, pi))
>>> ParametricIntegral(C.x**2 + C.y**2, solidsphere)

In this case, the parametric field when replaced with parametersr become r**2*sin(phi)**2*sin(theta)**2 + r**2*sin(phi)**2*cos(theta)**2 although it can be easily simplified to r**2*sin(phi).

SymPy has a function called simplify. simplify attempts to apply various methods to simplify an expression. When the integrand is simplified using it before passing to integrate, the result is returned almost immediately. Francesco rightly pointed out that simplify is computationally expensive and we can try to some specific simplification. I will look into it.

Failing test cases

Some test cases are failing because of integrate function returning results in different forms. The results are mathematically equivalent but different in terms of structure. I found this strange. I do not think this has to do with hashing. I still have not figured out this problem.

Next week’s goal

Hopefully, I will complete the work on the ParamatricIntegral and get it merged. We can then start discussing about representing implicit regions.

Leave a comment

Your email address is used to display your Gravatar, if applicable. Your email address will not be displayed publicly or shared with anyone else.

Part of this week was spent in getting the PR for ParametricRegion merged. I made some fixes to get the failing tests to pass. I also added the docstring.

ParametricIntegral

I started working on the ParametricIntegral class. ParametricIntegral class returns the integral of a scalar or vector field over a region defined parametrically. It should be able to calculate line, surface, or volume integral depending on the nature of the parametric region. To identify the nature of the region, the dimensions property needs to be added in the ParametricRegion class.

I started with writing the test cases to avoid my previous mistake of working on the implementation before deciding the API. The API of the ParametricIntegral class:

ParametricIntegral(field, parametricregion)

Some examples:

>>> curve = ParametricRegion((3*t - 2, t + 1), {t: (1, 2)})
>>> ParametricIntegral(C.x, curve)
5*sqrt(10)/2
>>> semisphere = ParametricRegion((theta, pi), (2*sin(phi)*cos(theta), 2*sin(phi)*sin(theta), 2*cos(phi)),\
                            {theta: (0, 2*pi), phi: (0, pi/2)})
>>> ParametricIntegral(C.z, semisphere)
8*pi

I initially thought to make it a subclass of Integral as the ParametricIntegral is a kind of integral. But there was no reuse of any code from Integral in the ParametricIntegral so decided against it.
A rough sketch of the algorithm to calculate integral is described below:

  1. Replace the base scalars in the field with their definition in terms of parameters and obtain the parametric representation of the field.
  2. Form the position vector of the region using definition tuple and base vectors determined from the field.
  3. Depending on the type of region, calculate the derivative of the position vector, or find the normal vector or calculate dV using Jacobian.
  4. Calculate the integrand using dot product or multiplication with the parametric field.
  5. Use the integrate function to calculate the integral.
  6. If the integrate function can evaluate the integral, return it otherwise return an object of the ParametricRegion class.

We also had discussion on whether swapping the upper and lower limit has any affect on the result of a vector integral. For multiple integrals, the sign of the result changes when the upper and lower bound of a parameter are interchanged. I do not think we came to any conclusion. But this won’t matter for integrals over parametric regions as the bounds are directly defined by the user.

Next week’s goal

I will start working on the implementation of the ParametricIntegral class. I am also trying to get more involved in SymPy outside of my GSoC project. I hope I can become a contributing member of the community.

Leave a comment

Your email address is used to display your Gravatar, if applicable. Your email address will not be displayed publicly or shared with anyone else.

Key highlights of this week’s work are:

  • Adds cdir parameter to handle series expansions on branch cuts

    • Finally, after spending almost 2 weeks on this, we were able to merge the PR, adding a very important functionality of series expansions on the branch cuts to the codebase. Previously, either SymPy raised some error or the series expansion was computed incorrectly, when the value in the input was on the branch cut. But now, for most of the functions, the expansion produced is correct.

      Not only this, we added the cdir parameter to leadterm and as_leading_term functions as well. We even extended the functionality a bit to the limits module, so now, limits of values lying on the branch cuts of a function are also computed correctly in most cases.

      We are planning to extend this functionality to all the remaining special functions and wherever else possible to make the codebase even more robust.

With this blog it completes the awesome month of statistical learning and coding, and the official Phase 1 of the Google Summer of Code-2020.

June 16, 2020

In the starting days of Week 3, I made further changes in the class level docstrings for TransferFunction after Jason and Nikhil reviewed the PR. Jason also mentioned that I had to add a new page in sympy docs which should include the purpose of adding a control...

June 14, 2020

Key highlights of this week’s work are:

  • Fixed incorrect evaluation caused due to subfactorial in limit_seq expression

    • This was a minor bug fix. The functionality of rewriting the subfactorial term present in an expression into an equivalent term expressed in the form of factorial or gamma was added which helped resolve the issue.

  • Adds cdir parameter to handle series expansions on branch cuts

    • Currently, many functions in the codebase are unable to produce correct series expansions on branch cuts. As a result, the limit evaluation takes place incorrectly for these functions when the limiting value lies on the branch cuts.

      Thus, we have decided to come up with a parameter named cdir which stands for complex direction and it indicates the direction from which the series expansion is required, thus helping us to produce the correct series expansion. Special care needs to be taken while handling series expansions on the branch points.

      Once we are finished with this work, it will be a major enhancement to the limit evaluation and series expansion capabilities of SymPy.

This marks the end of Phase-1 of the program. I learnt a lot during this one month and gained many important things from my mentors.

This blog provides the brief description of the last week i.e week 4 of the Phase 1. Some of the key highlights on the discussions and the implementation during this week are described below:

June 11, 2020

The first week of GSoC has been completed. My goal for this week was to add ParametricRegion class. Many common regions have well known parametric representation. Calculation of Integrals on parametric regions is a common problem of vector calculus.

The PR for adding the ParametricRegion class is #19472.

ParametricRegion

An object of ParametricRegion class represents a region in space defined in terms of parameters. If a user wants to perform integration on a region, they have to create a ParametricRegion object. This object can then be passed to other classes to perform integration.

The implementation part was easy. The difficulty was in deciding the API. I spent much of the week discussing the API, But it was worth it. The ParametricRegion class will most likely be used by many users so it is important for it to be simple and intuitive. I think I should have first completed writing test cases and examples.

The final API of ParametricRegion class:

ParametricRegion(parameters_or_coordsys, definition, limits=None)

Some Examples:

p = ParametricRegion(t, (t, t**3), limits={t: (1, 2)})
halfdisc = ParametricRegion((r, theta), (r*cos(theta), r* sin(theta)), {r: (-2, 2), theta: (0, pi)})
cylinder = ParametricRegion((r, theta, z), (cos(theta), r*sin(theta), C.z), {theta: (0, 2*pi), z: (0, 4)})

parameters_or_coordsys

This argument specifies the parameters of the parametric region. When there are more than one parameter, the user has to pass them as tuple. When a CoordSys3d object is passed, its base scalars are used as parameters.

definition

definiton tuple maps the base scalars to thier parametric representation. It is not necessary for evey base scalar to have a parametric definition.

CoordSys3D

A parametric representation is just defining base scalars in terms of some parameters. If the base scalars are not knowm, the region cannot be completely specified. My intial approach was to include an argument to specify the coordinate system.

Passing a CoordSys3D object can be non intuitive for users. In most cases, the base scalars of the parametric region are the same as that of vector/scalar field. We can avoid passing the CoordSys3D object if we assume that the base scalars of parametric region field are same.

p = ParametricRegion((r, theta), (r*cos(theta), r*sin(theta)), limits={r: (0,1), theta: (0, pi)})
Integral(C.x**2*C.y, p)
# C.x = r*cos(theta),  C.y = r*sin(theta), C.z = C.z
Integral(R.x*R.y*R.z, p)
# R.x = r*cos(theta),  R.y = r*sin(theta), R.z = R.z

There can be a situation where SymPy cannot determine the coordinate system of the field. In such situations, we can raise a ValueError. For example:

Integral(R.x*C.z, p)

limits

Most parametric region have bounds on the parameters. Note that it is not necessary for every parameter to have an upper and lower bound.

There can be many methods for a user to define bounds of parametric region. We decied to use a dictionary which we named limits. The keys of the dictionary are parameters and the values are tuples (lower bound, upper bound). Another approach is to use a nested bound tuple. Every subtuple will represent the bounds of a parameter.

Next week’s goal

My next week’s task is to get started with ParametricIntegral class. This class will represent integral of a scalar/vector field on a parametric surface. I will first write the unit tests and examples.

Leave a comment

Your email address is used to display your Gravatar, if applicable. Your email address will not be displayed publicly or shared with anyone else.

June 09, 2020

Week 2 of the coding period is now over. It was a week full of learning and a lot of challenges. I had my first meeting with Nikhil and Ishan on June 4, between 5:00 - 6:00 p.m. where we discussed a few things regarding the implementation part for this...

June 08, 2020

June 07, 2020

Key highlights of this week’s work are:

  • Fixed _eval_nseries() of Power

    • This was a long pending issue. Previously, in the codebase the series expansion of b**e was computed by breaking the code into different cases, depending on the values of the exponent or if the exponent has a symbol etc. Moreover, there was code to handle specific cases, and it was not written in a general way. As a result, the code was very long and it was difficult to debug it when some issue popped up.

      Hence, it was very important to completely rewrite and clean-up Pow._eval_nseries(), so that many issues get resolved and it becomes easy to debug any further issues related to series expansions or limit evaluations.

      Thus, we came up with a general algorithm covering all the cases.

      The series expansion of b**e is computed as follows:

      • We express b as f*(1 + g) where f is the leading term of b. g has order O(x**d) where d is strictly positive.
      • Then b**e = (f**e)*((1 + g)**e)where, (1 + g)**e is computed using the concept of binomial series.

      The major challenge which we had to face was the fragile nature of the existing code of Pow._eval_nseries(). Changing the code even a bit resulted in many test failures, as this function plays an important role in both series expansions and limit evaluations.

      At times, it became extremely difficult to debug the cause of failures because there were several other functions as well on which the code of this function depended. Not only this, fixing one failure caused several others to pop-up.

      Ultimately, after a week of hard-work, we got everything working. After which, we further optimised the code ensuring that we are not compromising with efficiency. At last, this issue was resolved and we ended up adding an extremely optimised implementation of the function to the codebase.

This blog provides the brief overview of the week 3 of the Phase 1. Some of the key highlights on the discussions and the implementation during this week are described below:

June 02, 2020

This specific blog describes the first official week of the coding period. I actually started coding from May 21 by opening #19390. I decided to start off the coding period by adding TransferFunction class… which was basically a class for representing the LTI (Linear, time-invariant) systems in...

May 31, 2020

On May 4, I got an email from Google that my proposal with SymPy has been accepted! Seriously, that was the best day of my life. I have learned a lot from this open source community from the past 6 months, and I hope to continue that.

The community...

Key highlights of this week’s work are:

  • Fixed _eval_nseries() of Mul

    • This was a long pending issue. Previously, in the codebase the series expansion of a product was computed as the product of expansions of the factors. This approach was correct only when the leading term of each series is a constant but not in general.

      For example, to compute the expansion of f(x)/x**10 at x = 0 to order O(x**10) it is necessary to compute the series expansion of the function f(x) to order O(x**20) and thus, computing till order O(x**10) would not suffice.

      The strategy we implemented to resolve this issue was:

      • Compute the order n0 of the leading term of the product as the sum of the orders of the leading terms of the factors.
      • For each factor, compute n - n0 terms of its series expansion (starting from its leading term of order n1 and ending at order n - n0 + n1).
      • Multiply the expansions (truncating at terms of order n).

      I enjoyed implementing all this because at every step we had to ensure that we are not compromising with the efficiency of the code. Finally, this issue was resolved and we ended up adding an extremely optimised implementation of the function to the codebase.

  • Used is_meromorphic() function to speed up limit evaluations

    • In this PR, we made use of the is_meromorphic() function of SymPy to speed up limit evaluations for certain type of cases.

      A function is said to be meromorphic at a point, if at that point the limit of the function exists but is infinite. In these cases, the value of the limit can usually be determined with the help of the series expansion of that function and thus, there is no need to invoke the Gruntz algorithm.

      While working on the implementation of this functionality, we required the leading term of the series expansion of the function in the limit expression at the point at which the limit needs to be evaluated.

      But we came across a weird situation, where for some functions, we got Complex Infinity as the leading term. Thus, we had to rectify the _eval_as_leading_term() methods of these functions (done in a separate PR).

      After resolving this issue, we succeeded in adding the required functionality and hence, increased the efficiency of the limit evaluation algorithm of SymPy.

I will be describing the second week of the project in this blog. This week can be considered as one the most important week as it consists of completing one of the important aim of the project. I will highlight some of the main discussions and the completed work during this week.

May 27, 2020

My proposal to SymPy has been selected for GSoC. My project is to add the support of vector integration over Curves, Lines, and Surfaces to SymPy. My mentors are Francesco Bonazzi and DivyanshuThakur. I am very excited to learn from them and contribute to SymPy.

Google Summer of Code or GSoC is a three-month program to bring student developers into open source development. Students contribute to an open project for three months. Students apply by submitting proposals to organizations. Students can submit up to 3 proposals. I only submitted one as most students do.

When I started contributing to SymPy, I was new to Open-source. I looked through many projects. SymPy was a great fit for my skills and interests. The Introduction to contributing and development workflow pages are great and helpful. SymPy has nice documentation and the codebase is well maintained. I received continuous feedback from the community on my Pull Requests. SymPy is a great project to get started with the open-source if you are familiar with Python and comfortable with mathematics.

SymPy

SymPy is a python library for symbolic mathematics. Symbolic computations are useful when we want to represent any mathematical quantity exactly.

SymPy is free software and is licensed under New BSD license.

Perhaps, the best way to get started with SymPy is to go through the SymPy tutorial. We can compute complicated math expressions, solve equations, perform integration, and do many more things.

>>> from sympy import *
>>>
>>> eq = 9*x - 2*x*y + y**2
>>> eq = eq - x
>>> eq
-2*x*y + 8*x + y**2
>>>
>>> eqdash = eq/x
>>> eqdash.expand()
-2*y + 8 + y**2/x
>>> factor(eqdash)
-(2*x*y - 8*x - y**2)/x
>>>
>>> diff(eq,x)
-2*y + 8
>>> Integral(eq,y)
Integral(-2*x*y + 8*x + y**2, y)
>>> Integral(eq,y).doit()
-x*y**2 + 8*x*y + y**3/3
>>>
>>> solve(sin(x)*x, x)
[0, pi]

My project

SymPy has a vector module. It provides tools for basic vector maths.

To get started with vectors, we first have to define a coordinate system. The module supports Cartesian, spherical, and curvilinear coordinate systems.

>>> from sympy.vector import CoordSys3D, divergence, gradient
>>> C = CoordSys3D('C')

We can access the unit vectors of the Coordinate System using C.i, C.j an C.k. C.x, C.y and C.z represent . Any vector expression can be created by performing basic mathematical operations like *,-,+ or / on base scalars and base vectors. We can also calculate gradient, curl and divergence.

>>> v = 3*C.i + 5*C.j - 2*C.k
>>> s = 3*C.x*C.y
>>> vdash = C.i - 8*C.j + 11*C.k 
>>> v + vdash
4*C.i + (-3)*C.j + 9*C.k
>>> v.cross(vdash)
39*C.i + (-35)*C.j + (-29)*C.k
>>> gradient(s)
3*C.y*C.i + 3*C.x*C.j

SymPy does not support integration of vector/scalar fields over curves, surfaces and volume elements. But Vector instances can be integrated with respect to a single variable using Integral class.

>>> from sympy import Integral
>>> Integral(v, C.x)
(Integral(3, C.x))*C.i + (Integral(5, C.x))*C.j + (Integral(-2, C.x))*C.k
>>> Integral(v, C.x).doit()
3*C.x*C.i + 5*C.x*C.j + (-2*C.x)*C.k

Vector calculus has many applications in the field of physics and mathematics, especially in the description of electromagnetic fields, gravitational fields, and fluid flow. The integrals of these fields represent important physical quantities. Vector Calculus plays a significant role in the study of partial differential equations.

Let’s look at some problems of such integrals.

  1. Integrate a scalar field f(x,y,z) = x2yz over the circle centered at x = 2 and radius r = 3.
  2. Calculate the flux of the vector field v across the surface x2 + y2 + z2 = 4 and z > 0.
  3. Calculate the mass of the body of Volume V bounded by x2 + y2 + z2 = 1 and z2 = (x2 + y2)/2. The desnity is given as rho = z.

To solve such integrals using Sympy, one first has to represent these integrals into multiple integrals and then use Integral class to get the result. Other Computer Algebra Systems like Mathematica and Maple already provides the functionality to perform such Integrals.

Community Bonding Period

Community Bonding Period is the first phase of the program. Students try to get familiar with the community and the codebase. I have contributed to SymPy in the past so I was comfortable with the development workflow.

I submitted my proposal just before the deadline. Therefore, I could not discuss the proposal with the community. I wanted to use this period to discuss the API with the community and find any possible problem which can arise. I also wanted to get familiar with the vector module. SymPy, require that all student-mentor interactions happen on a public channel like a mailing list or Gitter. The Gitter room for discussion related to vectors is sympy/vector. If you have any ideas or suggestions or just want to check out the progress, do lurk around there.

The API

In my proposal, I suggested a possible API. But there were some obvious problems with that API which Francesco highlighted. The API must be easy to use and intuitive for SymPy users. It has to be close to the mathematical representation in textbooks. This reduces the difficulty of learning a new API and allows the user to focus. I have started an issue for discussing the API with the rest of the community. I also looked at other CAS to get inspiration. Mathematica seems to do a good job of calculating vector integrals.

I proposed separate classes for different types of integrals(Line, Surface, Volume). Francesco suggested that the classes should represent the way an integral is displayed, not what kind of integral it is. SymPy should distinguish what these integrals are. Integral equations will be represented using subclasses of Integral. Then, we can write algorithms to perform computation.

We discussed about the separate classes to represent special surfaces. Many problems involve integrating over geometric objects like Circle, Sphere, Rectangle, Disk, etc. It can be helpful to the users if SymPy provides classes to represent such geometric entities. This saves the user from defining these objects using their parametric or implicit equation. We have decided to leave this part for later.

Another problem is determining the orientation of a surface. A surface can have two normals. The surface integral of scalar fields does not depend on the orientation. A surface integral of a vector field(flux) depends on the orientation. The result differs in sign. We decided that SymPy should always return the magnitude of the integral and it should be left to the user to decide the sign using the dot product.

Defining regions using implicit equations

Many curves and surfaces are easy to describe using their implicit equations. As an example, a problem involves calculating integral over S where S is the portion of y = 3sx2 + 3z2 that lies behind y=6. It will be tiresome for the user to first get the parametric representation of this surface and then use SymPy to solve the integral. I believe that a major part of the problem is finding the parametric representation. The rest of the calculation can be easily performed.

But handling such integrals is a difficult problem. To calculate the integral, we generally need the parametric representation of the curve/surface. We can then reduce the integral to multiple integrals and use SymPy integral class to get the result.

One approach to handle implicit equations is to write an algorithm to get the parametric representation from the implicit equation. This approach requires significant effort. We have decided to handle implicit integrals after we have completed the work on parametric integrals.

Conclusion

We have decided to first handle integrals over parametric regions. I will implement a class which will represent a parametric region in space. Another class will be implemented to represent an integral over a parametric region.

>>> circle = ParametricCurve(r*cos(theta), r*sin(theta), (theta, 0, 2*pi), (r, 0, 1))
>>> ParametricIntegral(f(x, y), (x, y), circle)

We will handle implicit regions later. I plan to complete this work in the first phase hopefully and get started with implicit integrals from the next phase.

I wanted to start coding early but due to midsemester exams, I could not. Most probably, the end-semester exams will not be conducted this summer. They will get conducted along with next semester’s exams. So, I do not have any other major commitments for the next 3 months.

Leave a comment

Your email address is used to display your Gravatar, if applicable. Your email address will not be displayed publicly or shared with anyone else.

May 24, 2020

Key highlights of this week’s work are:

  • Fixed incorrect limit evaluations caused due to different assumptions of the limit variable

    • In this issue, due to different assumptions of the limit variable, the output was coming out to be different and incorrect for the same limit expression. On digging deep into this issue, we observed that the assumption integer = True was common between all the incorrectly evaluated limit expressions. Thus, we concluded that the Gruntz algorithm is not able to correctly evaluate those expressions where the limit variable possesses integer = True property. So, in order to get all the correct mathematical behaviour from the expression, we decided to define a dummy variable lacking integer = True property. After which, we simply had to substitute the limit variable with this dummy variable for these type of limit expressions to resolve the issue.

  • Fixed incorrect limit evaluations caused due to bug in rewriting

    • At first, this issue seemed tough to resolve because we were unable to find the source of the error. But then, we decided to examine each expression which is generated during evaluation. This helped us to observe that rewriting of the expression was taking place incorrectly and we shifted our focus towards the rewrite() function. Afterwards, it was pretty evident that the xreplace() function utilised for rewriting is not sufficient, as it did not find everything that needs to replaced. Thus, replacing the xreplace() function with the subs() function helped us to resolve this issue.

This blog discribes the first official implementation week of the program. One of the advantage of Community Bonding period, I experienced during this week was that it saves a lot of time of designing new APIs. Since, it was all decided earlier on the APIs in the previous week, it made easy to maintain the timeline and add significant features.

May 20, 2020

I will be spending this summer with Sympy in Gsoc. In this post i want to share my journey over the past 4 months.

May 17, 2020

The first part of my GSoC journey was the Community Bonding Period.

In this period, I mainly focussed on the following things:

  • Setting up my blog, where I will provide weekly reports on the progress of my project, and synchronizing it with Planet SymPy.
  • Setting up a public gitter channel for discussions regarding the project.
  • Prioritising the issues to be solved.
  • Deciding the finer details of the workflow with my mentors and working out efficient ways to solve each particular issue.

Since I have been contributing to SymPy for the past 8-9 months, it was easier for me to blend into the community.

Now, as everything has gone as planned, I have decided to make a head start and begin with the implementation of my project.

This is the first official blog associated with GSoC 2020. I will be sharing the experience of the Community Bonding Period and work during this period after selection.

May 07, 2020









The results of Google Summer of Code were out on 04 May 2020 and I am pleased to share with you that my proposal with SymPy was accepted.

I would like to thank all the members of the organisation especially Kalevi Suominen for guiding me in my proposal and PR’s. I am really excited to work for such an amazing organization.

I will be working on my project, Amendments to Limit Evaluation and Series Expansion, during a period of 3 months spanning from June to August, under the mentorship of Kalevi Suominen and Sartaj Singh.

My primary focus will be to work on the series module and make it more robust as it is the backbone of all the limit evaluations performed by the library.

Looking forward for a really productive and wonderful summer ahead.

May 06, 2020


Older blog entries


Planet SymPy is made from the blogs of SymPy's contributors. The opinions it contains are those of the contributor. This site is powered by Rawdog and Rawdog RSS. Feed readers can read Planet SymPy with RSS, FOAF or OPML.