GSoC end: Vector Module

Phew. Sorry about the late blogpost (and a missed one last week). Google Summer of Code is now officially over, and I am happy to report that I was successful in building a basic vector-manipulation/vector-calculus module for SymPy. The code is now in SymPy’s master, which means it will be released with SymPy 0.7.6. Its been a great 3 months, with intensive software designing, coding and bug-fixing going hand-in-hand to being out ‘sympy.vector’.

I would like to thank Jason Moore, my mentor during this year’s GSoC. Initially, I had begun on my usual path of the ‘lets start coding immediately’ philosophy, but he made me wait it out, figure out extensive use cases, and give stress on the software designing process. This was the first software written by me, with the test-driven development approach. And must say, it does benefit a lot. There were quite a few tricky places, but I am glad I got through it all :-). I couldn’t implement all I wanted to, but atleast I am happy that all I wrote is stable, and works perfectly :-D.

The docs are expected to go in soon, after which you (if interested) may read through them and understand how to use the new module. All in all, its been a great summer!

 

Cheers!

Advertisement

GSoC Week 11: A major bug fix, and printing

Jim brought my attention to a very crucial bug in my work this week. Well, SymPy now automatically detects folders to test by looking at the __init__.py files. That is, a given folder in the SymPy code directory would _only_ be tested if it has __init__.py. Since I hadn’t put any such file in _sympy/vector/tests_, they were being skipped till now! Thank God this got fixed.

I started out this week with the seemingly ‘easy’ task of implementing different kinds of printing functionalities for sympy.vector. Well, the basic methodology of doing things is pretty simple, if you just follow the documentation in the _sympy.printing.printer_ file. It will tell you all you need to know about – either implementing a new printer, or adding custom code for printing of your class (to an existing printer).

Some things I had to improve/word around-

1. BaseScalars had to be handled differently from BaseVectors, since BaseScalars are a part of other Exprs (that may be measure numbers in vectorial expressions), and they have their own dedicated printing methods. Hence, I had to implement the _latex and _pretty methods in BaseScalar itself.

2. The pretty _as well as_ latex printing for _both_ Vectors and Dyadics with a single _print_BasisDependent method in the respective printers.

3. I used the printing code in _sympy.physics.vector_ as reference, though quite a few things had to be changed keeping in mind the inheritance from Expr, the structure and nature of the args being different, etc.
I did improve on a few things. _physics.vector_’s pretty printing messes up when dealing with vectors whose measure numbers have varying ‘heights’.

Overall, it was quite a learning experience and tricky coding – to implement printing, compared to my initial impression of it being a boring and tedious job.

Well, I have implemented all the requried methods and tests (all of which pass). I have pushed them to my third GSoC PR, so thats in line. Hopefully, the dyadics PR will soon show all tests passing, after which Jason or I will get it merged. It will add the OOP structure, and the dyadic code, as well as fix some crucial bugs.

A demo of the new printing implementations for a tedious vector expression-

Assume N is a CoordSysCartesian instance. Then,
(a**2 + b)*N.i + (Integral(f(b)))*N.k pretty-prints as


u'\u239b 2 \u239e N_i + \u239b\u2320 \u239e N_k\n\u239da + b\u23a0 \u239c\u23ae f(b) db\u239f \n \u239d\u2321 \u23a0 '

and LaTeX-prints as-


(a^{2} + b)\mathbf{\hat{i}_{N}} + (\int f{\left (b \right )}\, db)\mathbf{\hat{k}_{N}}

GSoC Week 10: Polishing off the main vector framework

This was a tiring week, with me being sick with a bad case of sinus for 3 days. Phew. Even then, I did manage to get quite a bit of work done in the time I could manage to sit in front of the computer without getting a headache.
Some main points of progress –

1. I finished off the Orienter classes, with a nice OO-structure, along with docs and tests. I basically changed the API of the orient_new

GSoC Week 9: Dyadics done

Not much to report this week, except that the code for dyadics is now done, with a all-tests-passing PR being pushed. A happy moment was the basic vector framework code finally getting pushed. Phew :-). Now the next PR in line is the dyadics one itself.
I also spent time mapping out the API for the Rotator classes, which I will proceed to discuss with Jason during this week’s meeting. I am still a little doubtful about how useful these classes may be, API wise. Lets see about this one.
A problem that I am facing currently is the confusion about the Del operator. I started out trying to write it as a SymPy function, but then I realised that the _outputs_ from the methods of Del should be the ones being defined as unevaluated functions- like Gradient, Divergence, etc. Will have to take this up with Jason too.

Anyways, I hope the dyadics code goes in soon, and I plan to send one or two PRs with more functionality soon. Till then, have a great week!

GSoC Weeks 7,8: Beginning with Dyadics

The last two weeks have been slow, hence a common blog post for both of them. Last week was spent in improving the current PR even more, especially with dedicated rotator methods for each type of rotation (Body/Space/Axis/Quaternion) of Coordinate Systems. Its not much, just methods like ‘orient_new_axis’, ‘orient_new_body’, etc. as add-ons on top of the all-powerful ‘orient_new’ method. The coding involved wasn’t much, since the new methods essentially call the ‘orient_new’ method with the relevant parameters. However, the rotation API is now much simpler than using the ‘orient_new’ method for all kinds of orientations – mainly because the extra flexibility provided by the ‘orient_new’ method implies a more awkward API for the same.
Jason, Mathew and Aaron were together at SciPy, during our last week’s GSoC meeting. There, the common consensus was to try and have Rotator classes to make the orientation framework even more user-friendly. Discussing the interface for the same is on this week’s meeting agenda.
A big change that we thought of doing in the timeline was to let go of spherical/cylindrical systems for a while, and instead focus on dyadic tensors – since the code is mostly done (my work during last year’s GSoC), they will be a useful and powerful addition to the vector module.
So my next few (much shorter than the current one) PRs would be-
1) The code for dyadic tensors
2) Documentation for all the basic, non-time-dependent framework
3) Rotator classes(?)
4) Implementation of the Del operator as an SymPy Function
5) Just some basic helper methods to convert vectors from one form (rect/spherical/cylindrical) to another
The code for Dyadics is mostly done, the docs are on-going, and I am thinking of having a common super-class for Vector and Dyadic- called Tensor(inheriting from Expr) – since many of the SymPy manipulation procedures work in the exact same manner for Vectors as well as Dyadics. Will discuss this with Jason soon.

Anyways, thats all for now, have a great week!

GSoC Week 6: Completing coordinate systems

Phew. This was a busy week. Initially, the plan was to push a WIP PR (without tests maybe) with the code for coordinate systems and point classes. Midway through the week, Jason and I decided to push this new code to the first PR itself, and merge the entire fundamental framework together – in a single PR. Initially I did get a little worked up looking at the amount of work that needed to be done.

However, things moved much faster than expected – though with a lot of issues along the way. There were problems with the args for CoordSysRect, then some issues with the Tree-algorithm for inter-point distance calculation, and then some more with the code that implements orientation of systems wrt each other…you get the drift. But the code is finally done and polished, along with the unit tests and doctests. Thats why the late post this week – I ‘bravely’ decided to get the code fully working, without glitches, and then only do the blogpost for the week. Thankfully, the plan was a success :-D.

Some minor things still remain, like renaming of some attributes to follow conventions  – mostly cosmetic changes, nothing that will affect how the code works.

The next immediate steps now would be –

1. Finish off the PR and get it merged.

2. Study caching mechanisms and implement them in a new ‘patch’ PR.

The first PR is here.

See you later then, next week :-).

GSoC Week 5: PR reviews and starting CoordSysRect

This week had the dual focus of –

1. Polishing off the Vector framework based on PR reviews

2. Starting the implementation of CoordSysRect+Point

I had thought last week, that the vector classes I implemented in the first PR were the polished version. However, with the reviews given, I have come to realise that a lot of improvements had/have to be made. Francesco Bonazzi, one of the SymPy contributors, was a huge help in improving the code and making it more efficient than what it initially was.

The biggest suggestion for improvement that was provided was to not implement custom hashing and equality checking methods for the Vector classes. Initially, I had overridden the inherited versions of these methods in the new classes, based on tuples generated with respect to the vectorial components of any Vector instance. However, SymPy already has a strong framework for these functionalities, based on the args of a Basic object. Moreover, the SymPy core is apparently being re-written in C++. This would make the SymPy-core versions of the aforementioned methods much, much more efficient than my Python versions.

Luckily, I had implemented the ‘__new__’ methods of the Vector classes in such a way that ‘equivalent’ Vector instances had exactly the same args. This made the usage of the inherited methods much, much easier – the only thing that remained to do was to pass the appropriate args to the superclass __new__ methods. Hence, all Vector classes rely on the SymPy core now, for as much as they can. Phew. Still a problem is the BaseScalar class, whose superclass is Dummy. The __new__ method for Dummy makes it not-possible to pass coordinate-system and index-related information to it – making the appropriate hashing impossible. If I instead inherit from AtomicExpr, I will have to rewrite many methods – not sure if its a good idea. Lets see what the community has to say about this.

About the implementation of the new stuff, I have already finished implementing the Point class. Now I am currently working on implementing CoordSysRect – I am still writing the HUGE __new__ method for this class. For now, I am referring to the tests of sympy.physics.vector while doing the coding. Hope I am successful in writing the classes soon, and integrating it with a polishing and ‘perfected’ version of the vector core.

Thats all for this week. Have a great week!

GSoC Week 4: Vector framework done

This has been a tricky week. Not hectic, but rather tricky. Most of it was spent fixing the innumerable bugs that I encountered while polishing and ‘packaging’ the basic version of the new vector module – it’s in a PR here.

I cannot stress how helpful the pre-written unit and example tests were, in making things clearer and pointing out the many bugs in the first version of my code. In some cases, I spent quite some (read: a lot) of time fixing the issues, while in some, I just redid the code/API to work around the intricacies of the SymPy core. Its quite easy to get lost in there.

Currently, the following functionalities are supported stably by my code(with appropriate error handling wherever required)-

1. All basic vector operations-

a) Addition/Subtraction

b) Multiplication/Division by scalars

c) Dot/Cross product

2. Including coordinate variables (spatial variables) in vectorial expressions.

3. All basic use cases of the Del operator in vector/scalar expressions, including-

a) Gradient

b) Divergence

c) Curl

d) Directional derivative

I know it seems a little low for something that’s based on code which is already a part of SymPy, but the whole point was to base it directly upon the SymPy core – for users not acquainted with the physics module. Moreover, with some rudimentary timing techniques, I found that on an average, the new module was able to do a set of most-basic vector operations (add, sub, dot, cross) approximately 3-4 times faster than sympy.physics.vector. But I guess it’s too early to judge now, since the new module has no overhead of coordinate systems.

I can say I am successful (hopefully all the tests on the PR should pass soon) in supporting all the functionality mentioned above, in a stable implementation – though I am still waiting for Jason and the SymPy people to review the PR. I hope it gets in soon.

The next step would be to start working on a new branch that would include the classes for coordinate systems and stationary points in 3D space (cartesian system). This is going to be tricky – the code for these classes in sympy.physics.vector is enough to prove that. As usual, the first step would be to write out the ‘expected-to-succeed’ unit and example tests. Hopefully, by that time, I would get sufficient feedback on the current PR too. But since the underlying vector framework is working well, I wouldn’t have to worry about bugs in that area – I can focus purely on the one-level-up code for multiple coordinate systems.

Cheers to a fun week! Hopefully I will be reporting just as much of progress next week too. Have a great week ahead :-).

 

GSoC Week 3: Formalizing design, polishing code

This week was mostly spent in polishing the design, writing mock sessions and adding tests to the code I wrote last week. Thanks to Jason’s constant encouragement towards objective- and test- driven code development, I now have a good idea of what I need to do in the coming week. If the meeting with Jason goes well and we are on the same page, I will soon complete the current WIP PR that is at this link, and then move on to implementing CoordSysRect class (just written the API for now).

What I learnt this week-

Before coding,

1. First write out as many example use cases of the software, as possible. In this case, the quality is more important than the quantity. The use cases should sufficiently touch upon all aspects of working required from the software that you are about to code. The interactions, on a conceptual and UI-level, should be as crytal-clear as needed.

2. Draw out the high-level API -> user-visible attributes(or better, ‘property’s in Python) and methods/functions. These will help you in defining all the ‘internal’ matter and algorithms succinctly.

3. While you are finalizing the API design, start drawing up a set of incremental objectives you would need to complete for building the overall software. Make sure that the objectives make sense chronologically, and reflect the priority and complexity level of the objectives correctly. This is basically to acknowledge that it is not possible to build and entire software together, but rather its better to code it module-by-module – with sufficuent testing at regular intervals, ofcourse.

The follow the timeline you have decided, and start coding.

Respecting this, I will start working on the code full-time next week onwards, so hope to give more detailed reports then. Have a great week :-).

GSoC 2014 Second Week: Basics of Vector, and Del operator

In my previous blog post, I had mentioned that I had begun working somewhat on a new branch for the vector module. This week was spent in polishing that work. But more importantly, I spent time confirming that my last week’s idea – of implementing the Vector framework, BaseScalar class, and the Del operator before implementing coordinate systems – does make sense. What this essentially means is that all the operations will occur in one frame only (for now).

I have implemented the Vector framework to a great extent by now, the BaseScalar class is done, and so is the Del operator. I have tried keeping the API of the Del class as ‘easy’ as possible, mainly so that the expressions typed out in code, would be very simple to read even for a non-fluent programmer.

To confirm that the one-system-framework does work, I tried proving all of the product rules of vector differential calculus (using the constructed API).

Here  is a snippet of (actual) Python-Shell session proving the last product rule-

Rule says :

\nabla \times (\vec u \times \vec v) = \vec u \, (\nabla \cdot \vec v) - \vec v \, (\nabla \cdot \vec u) + (\vec v \cdot \nabla) \, \vec u - (\vec u \cdot \nabla) \, \vec v

Shell session (i, j and k denote base vectors, while x, y and z denote base scalars)-


>>> u = x**2 * i + 4 * j - y**2*z * k
>>> v = 4 * i + x*y*z * k
>>> lhs = delop ^ (u ^ v)
>> rhs = u * (delop & v) - v * (delop & u) + (v & delop) * u - (u & delop) * v
>>> simplify(lhs) == simplify(rhs)
True

I guess intensive coding will begin this week onwards. The first priority would be to ensure that the Vector framework is foolproof, by writing unit tests and some long ones. I would also like SymPy functions like the solve one, to work with vector too (To solve problems like – given 3 vectors, prove that they can be used as a valid basis for 3D space). Then, I will most likely send a PR  with the work done till now. On a different branch, I’ll start working on the CoordSys class. Thats all for now! Have a great wek!