

Today’s day started with receiving an email from Google. Here is a snapshot:
This left a big smile on my face 😄
The past 34 months have been amazing and I have learnt a lot during the course of time. I would like to thank Aaron, Ondrej and the SymPy team for providing me with this opportunity, my mentor Amit Kumar for guiding me all through the phases and a special thanks to Chris who was not officially my mentor but was present all the time for reviweing my work and helping me complete the project successfully.
Here is what Amit has to say:
Though GSoC is completed I will be continuing my contribution in the developement of the software.


This post summarizes the work done on the Group Theory part of the combinatorics module during 2018 summers as a part of the GSoC programme


This post summarises the work that I have done during GSoC for SymPy. The links to the Pull Requests are in chronological order under each header. For following the progress made during GSoC, see my weekly posts.
This summer has been a great learning experience and has helped me get a good exposure of testdriven development. I plan to actively review the work that has went into this project and continue contributing to SymPy. I am grateful to my mentors, Kalevi and Aaron for reviewing my work, giving me valuable suggestions, and being readily available for discussions.
This is the list of merged Pull Requests.
convolution_fft
, convolution_ntt
and a general method convolution
for identifying the type of convolution and handling the cyclic convolution case, and include docstring, doctests, unittests.convolution_fwht
and add support for keyword dyadic
in the general convolution
method, and include docstring, doctests, unittests.linrec
which allows evaluation of linear recurrences without obtaining closed form expressions, and include tests for the same.subset
keyword for flexibility of the implementation, and include docstring, doctests, unittests.convolutions
and recurrences
, refine the documentation for discrete
module.discrete
module for inclusion in Sphinx docs, which can be referred here.discrete
module to fix tests using floats instead of Rationals, adding warning about sequence size for fft
and other improvements..rewrite(exp)
capability for instances of Pow
and fix bugs in solvers
module.convolution
method.discrete.recurrences.linrec
and possibly extending it for different types of recurrences as well.fft
and convolution_fft
efficient for both symbolic and numeric variants, as some discussion and benchmarking has been done for it and there is some work done by Colin for implementing a ComplexFloat
class in sympy/sympy#12192 which would be very helpful for the same.


I am Nikhil Pappu, an undergraduate Computer Science student at the International Institute of Information Technology, Bangalore.
Autolev (now superseded by MotionGenesis) is a domain specific language used for symbolic multibody dynamics. The SymPy mechanics module now has enough power and functionality to be a fully featured symbolic dynamics module. The parser parses Autolev (version 4.1) code to SymPy code by making use of SymPy’s math libraries and the mechanics module.
The parser has been built using the ANTLR framework and its main purpose is to help former users of Autolev to get familiarized with multibody dynamics in SymPy.
The plan was to build a parser using ANTLR that could parse Autolev code to SymPy code. Overall, I think I was able to achieve most of what I had hoped for. I had faced some difficulties in some areas of the parser due to the very different nature of Autolev and Python. The parser has some issues as a result. I have specified all the details in the documentation I have written.
I made a parser for the Autolev language which is now a part of SymPy in the parsing module. I have written the code for the parser using the ANTLR framework. I have also included a bunch of tests for testing the rules of the parser code.
The majority of the work was a part of PR #14758. I made a second PR #15006 for the changes I had made after the main PR.
I have written documentation for the parser which is a part of these PRs: #15046, #15066 and #15067.
I have also written a PyDy for Autolev Users guide which is a part of PR #15077. This guide is meant to be a quick reference for looking up AutolevPyDy equivalents.
As of now, a large number of codes of Dynamics Online have been parsed. Completing all the remaining codes of the book would make the parser more complete.
I would like to keep contributing to SymPy. I would be doing a lot of math in college especially related to data science so I would love to contribute in areas like Probability and Algebra among others. I would also like to help newcomers feel comfortable with the environment.
I would like to thank my mentors Ondřej Čertík and Jason Moore for believing in me and taking time out from their busy schedules to guide me throughout the project. I would also like to thank Aaron Meurer for looking over GSoC as the org admin and making sure that we all had a great experience working with SymPy.
Main PR: #14758
Updated parser code PR: #15006 and #15013
Documentation PRs: #15046, #15066 and #15067
PyDy for Autolev Users guide PR: #15077
Weekly Blog link: https://nkhlpappu.wordpress.com/


This week I continued the work with log solver and lambert solver. The log solver implementation is almost done with just few check for assumptions. Symbolic logarithmic equations should be dealt with proper assumptions. Such equations would give unsolved instance of ConditionSet
otherwise.
>>> a, b, x = symbols('a, b, x')
>>> solveset(a**x  b**(x + 1), x, S.Reals)
ConditionSet(x, Eq(a**x  b**(x + 1), 0), S.Reals)
# because the bases (here, `a and b`) should have a positive value > 0)
>>> a, b = symbols('a b', positive=True)
>>> solveset(a**x  b**(x + 1), x, S.Reals)
{log(b)/(log(a)  log(b))}
Discussions with Amit and Chris suggested that there should be some other way to handle vanilla symbols. There should be atleast a ValueError
or something else that would tell the user why this cannot be solved. Chris suggested of returning a Piecewise
as object for this scenario. Something like:
cond = True if fuzzy_and([a > 0, b > 0, Eq(im(f), 0), Eq(im(g), 0)]) else False
Piecewise((solutions, cond), ConditionSet(........), True))
Using Piecewise was not the greatest of the option as:
Though the assumptions were checked but it didn’t provided information to the user that why did it not solved.
Also using Piecewise
had some problem causing recursion error, though it could be solved but it would make things unncessarily complicated.
Also solveset
is not made to return objects other than Sets
.
So we switched to a completely different approach. We tried using a different type of ConditionSet
: providing the information within it that is necessary for the equation to be solved. The approach was: Force the equation to get solved but return a ConditionSet (a different than ususal) with the required assumptions, like:
ConditionSet(x, And(a_base>0, b_base>0, Eq(im(a_exp), 0), Eq((im(b_exp), 0))), {solutions})
. So now the above equation would return solutions something like:
ConditionSet(x, (a > 0) & (b > 0), Intersection(Reals, {log(b)/(log(a)  log(b))}))
So this approach has been applied in the PR as of now, only a few minor changes needs to be done. I will try to finish this by the end of the week.
Apart from this some work has been done in lambert solver
:
_is_lambert
to identify lambert type equations.solve
’s tests, to get an idea of the extent to which solveset
would handle such equations.What’s next:
I will try to wrap up the work of both the PR’s. Lambert solver PR would need a bit more time for reviewing but nevertheless I will be continuing its work post GSoC. Implementing these two solvers will make solveset
fully functional to handle transcendental equations which is a major part of my GSoC propsal. There will be a few minor things left that I will try to finish post GSoC. Also since this is the last week for the coding period, I will be needing to submit a final report of my work, I will complete and submit it before the deadline.


The final week of Coding Period has completed.
This week, the work was mainly concerned with the documentation and refinements in the discrete
module.
I started by opening PR #14994 to update Sphinx docs for SymPy.
Kalevi and Aaron were kind enough to review the PR and help refine it for the final merge. The documentation for discrete
module is now part of the SymPy docs and can be referred here.
Late this week, I opened PR #15025 for improvements in the discrete
module.
Colin helped fix accidental floats in unit tests (which should have been Rationals). After the review, the PR was merged successfully.
Future work would include  addition of a userfacing public method for linrec
and making methods fft
and convolution_fft
efficient for both symbolic and numeric variants, as some discussion and benchmarking has been done for it and there is some work done by Colin for ComplexFloat
class in PR #12192 which would be helpful for the same.
Looking forward to the concluding phase, where I will be wrapping up GSoC and preparing the report for the final evaluation.


I have made some changes to the parser code to parse more files since #14758 has been merged. I have also made the changes suggested in that PR after it had been merged. I have opened a new PR #15006 for the updated parser code. I have also opened #15013 to include tests for physics functions which I didn’t do in the initial PR. The GitLab repo autolevtestexamples is in good shape now and is part of the sympy user.
I am currently writing the documentation in which I shall include how to use the parser, gotchas, limitations, issues and future improvements. I shall also include a rewritten version of the PyDy for Autolev Users guide in it.
I shall then write the output tests (Tests to compare the outputs of Autolev against those of SymPy) for most of the test examples in the GitLab repo (I shall include these in a directory called outputtests in the GitLab repo). I think its good to put them here as I don’t see the need to test these on Travis as changing the parser code won’t affect these. Plus, they will be in a place where the test examples are which are what they will be based on. We could still test these on Travis if required even from here I suppose.
Finally, I shall wrap things up with the Final Report and Submission.


Last week, I created #14967 for implementation of plotting methods. Soon after pushing my commits, many of the jobs failed on Travis. It was strange as I was not able to reciprocate the errors locally.
After discussing it on Gitter, I got to know that it was due to the printing of plots using TextBackend in the doctest in absence of matplotlib. As matplotlib was present in my system, doctest used matplotlib backend instead of TextBackend locally, hence passing all tests. Kalevi suggested using unset_show to stop the printing of plots during doctest but apparently, unset_show didn’t work for TextBackend. This was fixed by #14984 later that day and #14967 passed all the tests after former one was merged.
This week, I also started editing #14453 for documentation. It included a few beam problems along with their ascii diagrams.




So this week I started up with implementing and sending a PR for lambert solver #14972. Solving these equations can be achieved by _solve_lambert
routine of bivariate.py. It is really powerful and can solve a varied type of equations having a general form. Another routine comes into action, the bivariate_type
to solve majorly lambert type of equations when the former is unable to solve. These two routines can be handy for implementing such equations. As of now I have added _solve_lambert()
in the PR. I will add bivariate_type
once the log solver PR gets finalised. There are few equations that can be solved by posifying the variable that needs to be solved. A bit discussion is needed on this part.
Apart from this, a lot of work was done in the log solver
PR
_term_factors()
is used again.
Logic for exponential identifying is modified to not identify lambert type equations
Few mores tests were added.
Chris advised to make identification helpers such that they identify their class even if they won’t get solved by their respective solvers, the equation should not be passed to any of the other helpers for further solving. This wasn’t the case before, the identifying helpers were implemented only for equations that their helpers could solve. So now this idea is implemented for both the exponential and logarithmic solver. Equations that these identifiers can’t identify will be further solved as lambert type.
Almost all the work of the log solver PR is done. I will be finishing the work on lambert solver PR and complete in coming week. I hope both the PR’s gets merged before the GSoC period ends.


This week, I started working on adding the final method to convolution module for Intersecting Product. PR #14954 dealt with the addition of intersection_product
method. Intersecting Product was implemented using Möbius Transform with superset enumeration (mobius_transform(..., subset=False)
and inverse_mobius_transform(..., subset=False)
). After minor documentation improvements, the PR was merged successfully. The proposed transforms and convolutions are now part of sympy.discrete
. The basic usage for the method is:
>>> from sympy import symbols, S, I, intersecting_product
>>> u, v, x, y, z = symbols('u v x y z')
>>> intersecting_product([u, v], [x, y])
[u*x + u*y + v*x, v*y]
>>> intersecting_product([u, v, x], [y, z])
[u*y + u*z + v*y + x*y + x*z, v*z, 0, 0]
Late this week, I started working on improving the documentation for SymPy’s Sphinx docs (http://docs.sympy.org/dev/index.html) and other minor changes in the PR #14969. Also, issue #14964 was opened to discuss the possibility of using LaTeX in docstrings for SymPy documentation. The following changes were part of the PR:
Successive reviews and discussions were helpful in finalizing the Pull Requests.
Looking forward to the final week of Coding Period.


Hello Everyone. I have been working on getting the PR #14758 into shape and now it is finally merged. I have written my own tests for the PR so as to not include copyrighted files that belong to the creators of Autolev.
I am now working on a testexamples repo which serves as a showcase of the parser and also as a source of additional tests. The repo is private on GitLab as it contains copyrighted files. You can request access at the repo link above. Files from this repo can be copied over to the test_examples folder of parsing/autolev to use them as tests. From now, I will be working on adding more examples from the PyDy example repo, Autolev Tutorial, and Dynamics Online to this repo while improving the code of the parser to parse all these codes. I am also making note of things like errors, inaccuracies etc to include them in the Documentation.
I will open another PR once I have made enough number of changes to the parser code.
Here is my plan for the future of this project:
Till the end of GSoC:
Post GSoC:
Thanks,
Nikhil


This week I started working on implementing methods to plot Shear force, bending moment, slope and deflection diagrams. #14967 was created for it.
Mainly four methods were added to the Beam class:
Here is a sample notebook demonstrating how to use these plotting methods.




This week started with the merge of the PR #14736. Yehhhh!!!!!. So now solveset
will be able to solve a varied type of exponential equations. Next work is going on to build the logarithmic and lambert solver.
A lot of discussion has been taken place over the implementation of the logarithmic solver, there were mainly two points to consider:
Take for instance a logarithmic equation log(x  3) + log(x + 3) = 0
, when solved the solutions would be sqrt(10) and sqrt(10)
, but sqrt(10)
make the log term negative. So the question was what should we do for such a scenario? Should we add a check to remove these solution or just accept. it.
As of now as suggested by Kalevi and Aaron we should focus on the liberal interpratation for evaluating equations: if an expression can be written in its equivalent form and makes sense then we can consider solutions of this equivalent form. Therefore both the above solutions are acceptable.
The identification of logarithmic type is another question and is still yet to be agreed upon. At first the implementation was done by extracting each term of the expression and see if it has log
terms in it, this wasn’t the best of the method as we are trying to identify a large class of logarithmic equation while solving is done only for a subset of those equations (only those that can be reduced by logcombine
). So Amit and Chris stressed upon making the logarithmic identification for equations that its solver would solve. So as of now I have made changes accordingly.
Another problem that this PR is facing is of the infinite recursion. The equations that both exponential and logarithmic can’t solve but still their respective solver try to handle gets into infinite recursion. One way (though not appropriate) is to use flags
like in solve
, using this would remove the infinite recursion but is not the best way to handle, therefore I am looking into ways on how to get this fixed.
Apart from the work on log solver, I did some work on lambert solver how the implementation would go, ran all the tests of solve
, differentiated the tests that _solve_lambert
could solve and that bivariate_type
would. I will be adding a PR for this in a day or so.
Next week goals:
Finish things with logarithmic solver
Sending a PR for lambert solver and try to finish its work as quickly as possible.


This week SymPy 1.2 was released, which included the discrete
module. The complete changelog for the SymPy 1.2 is here. I started the week by cleaning up discrete
module, improving the API of public convolution
method by attending to reviews by Aaron and Kalevi and fixing issue #14901 reported by Aaron in PR #14907.
The PR #14907 has been merged successfully and will be part of SymPy 1.2.1.
Late this week, I started working on the convolution module for inclusion of covering_product
.
The PR #14298 included the same with documentation, doctests and unit tests.
The implementation of covering_product
uses Möbius Transform with subset enumeration (mobius_transform(..., subset=True)
and inverse_mobius_transform(..., subset=True)
). As included in the PR, the usage for the same is:
>>> from sympy import symbols, covering_product
>>> u, v, x, y, z = symbols('u v x y z')
>>> covering_product([u, v], [x, y])
[u*x, u*y + v*x + v*y]
>>> covering_product([u, v, x], [y, z])
[u*y, u*z + v*y + v*z, x*y, x*z]
Looking forward to the next week, where I will be implementing intersecting_product
as the final method for the convolution module.


I have been working on improving the parser by parsing Dynamics online codes, planning out how to go about writing tests and other aspects of the project and getting the PR into shape.
I am currently working on writing tests to cover all the rules of the parser. I should be done with this in 2 days.
This is the plan I have for the third phase:


I started implementing Beam_3d class which can be used to find Shear force, Bending moment, Slope, Deflection and other few things for the Beam object. PR #14883 was created for this.
I implemented Beam_3d class using this paper as a reference. Actually, like Beam class, it uses a few sets of equations to find certain quantities:
Example for the API:
There is a beam of l meters long. A constant distributed load of magnitude q
is applied along the yaxis from start till the end of the beam. A constant distributed
moment of magnitude m is also applied along the zaxis from start till the end of the beam. Beam is fixed at both of its end. So, deflection of the beam at the both ends
is restricted.
>>> from sympy.physics.continuum_mechanics.beam import Beam_3d
>>> from sympy import symbols
>>> l, E, G, I, A = symbols('l, E, G, I, A')
>>> b = Beam_3d(l, E, G, I, A)
>>> b.apply_support(0, "fixed")
>>> b.apply_support(l, "fixed")
>>> q, m = symbols('q, m')
>>> b.apply_load(q, dir="y")
>>> b.apply_moment_load(m, dir="z")
>>> b.shear_force()
[0, q*x, 0]
>>> b.bending_moment()
[0, 0, m*x + q*x**2/2]
>>> b.solve_slope_deflection()
>>> b.slope()
[0, 0, l*x*(l*q + 3*l*(A*G*l**2*q  2*A*G*l*m + 12*E*I*q)/(2*(A*G*l**2 + 12*E*I)) + 3*m)/(6*E*I)
+ q*x**3/(6*E*I) + x**2*(l*(A*G*l**2*q  2*A*G*l*m + 12*E*I*q)/(2*(A*G*l**2 + 12*E*I))
 m)/(2*E*I)]
>>> b.deflection()
[0, l**2*q*x**2/(12*E*I) + l**2*x**2*(A*G*l**2*q  2*A*G*l*m + 12*E*I*q)/(8*E*I*(A*G*l**2 + 12*E*I))
+ l*m*x**2/(4*E*I)  l*x**3*(A*G*l**2*q  2*A*G*l*m + 12*E*I*q)/(12*E*I*(A*G*l**2 + 12*E*I))  m*x**3/(6*E*I)
+ q*x**4/(24*E*I) + l*x*(A*G*l**2*q  2*A*G*l*m + 12*E*I*q)/(2*A*G*(A*G*l**2 + 12*E*I))  q*x**2/(2*A*G), 0]
As this class is relatively new, it would require a few improvements in the future:
Beam_3d
doesn’t use SingularityFunction
, I was unable to find a way to represent point load/moments. So for now Beam_3d
only supports continous load (applied over the whole span length of beam).For now, after discussing it with Arihant, we decided to raise NotImplementedError in such cases.


Having completed an applied Mathematics project last year, I wanted to explore a CS specific field. Hence I decided to apply for a parallelization project under CERNHSF.
On April 23 of this year, I was accepted into the project. However, I have failed the second evaluations due to my main PR#2236 not being able to get compiled till date. In retrospect, both me and my mentors were not able to resolve the compilation issue so far. Strangely enough, the Jenkins build is able to compile the code I wrote and report errors which are not even visible on my machine.
Anyway, I think and have also advised juniors in the past that contributing to Open Source libraries is largely beneficial and teaches one a lot(with or without the GSoC certificate).
Hence, have decided to keep on contributing and get my project finished unofficially. My main aim was more inclined towards getting involved with CERN and getting to contribute to one of the most amazing science experiments of our century.




The second phase of Coding Period has concluded.
This week I worked on implementing Subset Convolution for discrete
module.
PR #14878 was opened for the same. The PR included unit tests, documentation, and correspondingly subset
keyword was added for public convolution
method.
After discussing the implementation details and references with Kalevi, the approach was finalized. The PR has been merged successfully. The usage for the same is:
>>> from sympy.discrete.convolutions import (convolution, convolution_subset)
>>> u, v, x, y, z = symbols('u v x y z')
>>> convolution_subset([u, v], [x, y])
[u*x, u*y + v*x]
>>> convolution([u, v, x], [y, z], subset=True)
[u*y, u*z + v*y, x*y, x*z]
>>> convolution([u, v, x], [y, z], subset=True, cycle=3)
[u*y + x*z, u*z + v*y, x*y]
Plan for this phase has executed well, and the second evaluation has been successful.
Looking forward to the final phase of Coding Period.


At the start of the week I worked on the leftovers of week 8:
log_singularities()
that will help in determining logarithmic singularities,Status of the PR’s:
PR #14736 is ready to be merged.
PR #14792 is being worked on. Major tasks has been completed, just review and refining has to be done.
Apart from this I started working on the way Lambert type equations can be solved through _transolve()
. I looked into _tsolve's
way of handling such equations.
For solving Lambert type equations _tsolve()
largely depends on bivariate.py
. It takes help of the different utility functions implemented there.
Of them two important are _solve_lambert()
and bivariate_type()
. These two helpers help in getting the equations evaluated.
Equations that can be written in the standard form as: A + B*x + C*log(D + E*x) = 0
has the solutions in terms of Lambert
function as:
D/E + C*B*W(t) with (B/C*E)*exp((BD  AE)/CE)
This is what _solve_lambert()
determines and accordingly returns the solutions, otherwise returns a NotImplementedError
If _solve_lambert()
is unable to handle bivariate_type()
is tried. This function first tries to identify the type of composite bivariate and then substitutes Dummy
in place of them. For eq: (x + y)**2  3
would become _u**2  3
where _u
is the dummy variable. The idea is that solving the latter equation for u
and then equating the solutions to the former equation is equivalent for solving the original one.
While implementing in _transolve
this philosophy needs to be applied. As of now I have looked into different tests on how they behave. I will start implementing it next.
Next week’s plan:
Finishing with the logsolver
Implementing lambert solver.




Before the start of the week Amit and I discussed on a few points on:
Note: is_logarithmic()
is an identifier helper for _transolve
to determine whether the expression is logarithmic or not.
and _solve_log()
is a solving helper that returns the equation in a tractable form for solveset
to better handle.
is_logarithmic()
return?While designing the method at first it returned a logcombined
equation if found to be logarithmic, but we agreed upon having consistency among all the identifying helpers to return either True
or False
.
_is_logarithmic()
should work?Next question was how it should work. We can implement it in two ways either to make the logcombined
equation, if the expression reduces, it is obviously a logarithmic equation otherwise not. We also need to check whether the equation reduced has the variable to be solved in its free_symbols
But logcombine
possessed a problem that it unknowingly manipulates the equation, like log(x)  log(2*x)
would reduce to log(1/2)
for which the routine would return False
as there are no symbol involved. So a more better way needs to be implemented.
_solve_log()
will handle removing unwanted solutions?Simply reducing the logarithmic equation to a tractable form for solveset
to handle would cause spurious solutions in the result. Therefore it becomes necessary to remove them. Take for example: solveset
gives the result of log(x  3) + log(x + 3)
as {sqrt(10), sqrt(10)}
, but sqrt(10)
is not the solution in Real
domain. Therefore one way to remove it was using checksol
. Amit suggested on to have a look over the singularities and try incorporating the check in _solveset
.
Things that I did during the week:
is_logarithmic()
Removed the logcombine
way of checking the equation. As of now the _is_logarithm
checks for every term to be logarithmic in terms of the variable to be solved, if so it returns True
otherwise False
_solve_log()
As per the current documentation of _transolve
this routine is improved to return a modified form of the equation that solveset
could better handle. Checking of the spurious solutions will take place in solveset
itself.
To handle this scenario I have added a check in _solveset
specifically for logarithmic equations to remove spurious solutions.
The idea is based on the fact that natural log in undefined for negative and zero value, therefore this method gets each term of the expression, substitutes each solution to every term one by one and if for any term the value isn’t real that solution will not be included.
Why checksol()
is not the appropriate way?
At first I thought of using the checksol()
, but it possessed a problem. checksol
unintensionally allows wrong solution to creep in. Take for example log(3*x)  log(x + 1)  log(4*x + 1)
, solveset
would give 1/2 and 1/2
as the solutions but the former isn’t a solution in real domain. Using checksol
would not remove this as I*pi
gets cancelled out during evaluating the expression therefore it returns True
, which is not correct.
Apart from this few changes have been done in the _transolve
PR:
I have added a method that would return all the terms present in the expression: make_expr_args()
Made the expresssion remain unevaluated when doing lhs  rhs within _transolve
.
Read this blog for better understanding of logarithmic solving.


This week I mainly focused on finding and solving a bug due to which continuum_mechanics gave ValueError on using units with the quantities passed. Initially, I created #14856, which included a workaround in the Beam class itself to handle that error. But Arihant suggested opening a separate PR as the error was occurring due to a bug in the separate module.
So, #14865 was created. is_commutative attribute was added in the Prefix class (setting Prefix.is_commutative to True removed PolynomialError). While doing changes in the PR, another bug appeared:
>>> from sympy.physics.units import meter, newton, kilo >>> from sympy.physics.units.util import quantity_simplify
>>> quantity_simplify(x*(8*newton + y)) x*(8*newton + y, 1)
This bug was solved with few changes. After #14865 gets merged, continuum_mechanics should work with quantities involving units.


This week I started working on adding Möbius Transform to the discrete
module using Yate’s DP (Dynamic Programming) method for implementation as part of PR #14853. The proposed transforms are part of sympy.discrete.transforms
module.
After discussing with Kalevi, the methods implementing this transform were added with appropriate names. The keyword subset
is used as a boolean to choose whether enumeration is done over subsets or supersets. The usage for the transform is:
>>> from sympy import mobius_transform, inverse_mobius_transform
>>> seq = list(symbols('w x y z'))
>>> mobius_transform(seq)
[w, w + x, w + y, w + x + y + z]
>>> inverse_mobius_transform(_)
[w, x, y, z]
>>> inverse_mobius_transform(seq, subset=False)
[w  x  y + z, x  z, y  z, z]
>>> mobius_transform(_, subset=False)
[w, x, y, z]
The PR was merged successfully, after inclusion of docstring and unit tests for the transform.
Looking forward to another exciting week.


I have a PR for a working parser now with some test cases. The Travis errors I had previously have been fixed.
I am currently going through the chapters of the book Dynamics Online: Theory and Implementation with Autolev and parsing most of the Autolev codes I come across. I feel this would help to make the parser more complete. After getting the desired parsed code I am also running the code and checking that the results are same/similar to the Autolev responses in the .ALL files.
I have parsed the codes of Chapter 1 and 2 of the book and am currently working on Chapter 3. There are 6 Chapters overall and the bulk of the stuff is concentrated in Chapters 4 and 5.
After parsing the codes of this book, I shall update the parser code and the tests in the PR. I will add more test cases as well. I will also send in a file containing all the parsed codes of Dynamics Online.
A lot of the codes are parsing completely fine. A few I feel are quite difficult to parse to SymPy code using a parser and they wouldn’t even be in the spirit of SymPy/Python if parsed exactly. I have marked these for later. A few of them are producing slightly altered expressions or in some cases errors in SymPy. I am classifying all the codes appropriately based on criteria like this.
After parsing the book I plan on finishing up the leftover parts of the Autolev Tutorial examples and making sure the Bicycle Model Autolev code is parsed.
I will then go on to do a complete code cleanup (general cleanup, using standard conventions and better variable names, adding more comments etc).
Finally, I will wrap things up by writing the Documentation and a Final Report. In these I shall discuss: what the parser can do, how it should be used (there are some minor things in some cases that the user should note to get a proper SymPy parse), limitations and future improvements.


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.