July 16, 2018

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 CERN-HSF.

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.


July 15, 2018

Hello everyone. Here is the progress of rubi module in the 9th week of GSoC period.

In the very beginning of the week, the PR for appelf1 was merged. My aim for this week was to load all rules and test at least a small part for each type of rule. Due to the time factor, its not possible to test all. Moreover, rubi needs to be updated to the latest version, so the test suite too will be updated.  

I started with trigo rules. They are huge in number. They were never tested before, so some utility_functions like `TrigReduce`, `KnownTrigIntegrandQ`, `FunctionOfTrig` etc were wrong. They were corrected. Soon I realised a difference between sympy and Mathematica. In mathematica, `1/Cot[x]` is automatically transformed to `Tan[x]` and `1/Tan[x]` too was transformed to `Cot[x]`. But in sympy, these are different. So, `tan(x)` didn't match to `cot(x)` . Francesco suggested to replace all `cot` with `1/tan`  and similarly for `sec` and `csc` (in the code generator too). 

Next, I moved to `inverse_trigo`, `hyperbolic` and `inverse_hyperbolic`. I tested some test cases for all these rules. I also tested `error_functions` completely to make sure `special_functions` are working properly. 

After all this, I feel rubi is in a stable and working condition. The loading time is around `10 minutes`. Except for the loading time, the performance of rubi is good. 

I have left `DerivativeIntegration` and `Piecewise` rules. We will be discussing it. 

July 14, 2018

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.convolution 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.

July 13, 2018

At the start of the week I worked on the leftovers of week 8:

  • added log_singularities() that will help in determining logarithmic singularities,
  • improved documentation of all helpers as suggested by Amit to maintain consistency

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.

July 11, 2018

July 08, 2018

Hello everyone. Here is the brief summary of the progress of rubi integration module in the 8th week of GSoC period.

We completed the testing of logarithmic test cases. Some of the tests are failing as they depend on trigonometric rules. The rules and tests have been updated in this PR.

Next, I loaded all trigonometric rules. They are huge in number. So the loading time increased from 1 min 30 sec to around 6 min. For now, I have not loaded them. I also updated the test cases for parsetools and fixed code quality issues. Currently, the travis is failing due to a bug, which has been fixed in branch 1.2. In the upcoming week, 1.2 probably will get merged in master.

Then I moved on to implementing appellf1 in sympy. Progress can be seen in this PR.

We will be updating our utility_functions to the latest version of RUBI.

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.

  • What should 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.

  • How _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.

  • How _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:

  • improved 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

  • improved the _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.

  • Way to remove spurious solutions

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.

  • Addressing comments

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.

July 07, 2018

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 @parsoyaarihant 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.

Next Week

  • Make sure #14865 gets merged.
  • Open a Pull Request and start working on 3dbeam class.

July 06, 2018

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.

July 05, 2018

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.

July 01, 2018

Hello everyone. Here is the brief summary of my work in the seventh week of GSoC period.

Last week, we found a solution for matching `exp` as `Pow`. This week major part was spent in testing exponential rules. Here are some problem faced.

1. UnevaluatedExpr is quite untested and results in recursion errors in many places.
like `u = UnevaluatedExpr(E)` now when we want to find imaginary and real part of `u`, using `im(u)`. It causes recursion error. There were other instances too. So in those functions, I replaced them back to `exp`.

2. There was a lot of index error because length of args of a `Pow` object is 2. Whereas for `exp` it's 1. Utility functions used in lot of places `.args[1]`. I found all possible places where arguments of a `Pow` object was accessed using `.args[0] and .args[1]` . I replaced them with `.base` and `.exp`. This solved the problem

There were more minor changes in many utility functions. Currently, I have finished the exponential testing and almost all are passing. I have pushed all changes in this PR

I have tested a small part of logarithmic tests. I will try to finish them in 2 days and next move on to either special functions on trigonometric rules.

This week I continued to work on finalising the design of the _transolve. Following were the things discussed and implemented:

  • The loop over the rhs_s was removed because solveset already has a loop and since _transolve is called within the loop therefore there won’t be a case where there would be more than one argument in rhs_s inside _transolve.

  • pow_type() was created to handle power type equations in _transolve but it turns out that power type equations will be handled in the _invert() itself, so it was repetitive to add again.

  • The names of the solving helpers were improved to _solve_class from the previous _class_solver.

  • Discussions with Amit and Chris led to the conclusion that _transolve should be completely made an internal function of solveset, i.e. it should not be used as an independent function. At first the thought was that it can be used as an independent function, but this created a problem of the code being repeated as that of solveset, so Chris suggested that _transolve should raise an error for equations that solveset can handle, but again this created problem, it would make unnnecessary complications in the code as we need to be very specific as to when and where raise an error.

  • We decided to have same arguments for all the helpers. Be it identification or solving helper, both will take the equation and the variable as their arguments, with the choice that the helper can ignore to use any of the argument if not needed.

  • There were a lot of improvement in the documentation as the design changed.

Apart from these changes work in implementing log solver is going on in parallel.

June 29, 2018

Last week I created #14826 to solve statically indeterminate beam systems using boundary conditions (bc_slope and bc_deflection). This week I mainly focussed on implementing a logic to find the maximum bending moment and maximum shear force in a beam.

Initially, I thought it would be as simple as differentiating the bending_moment and shear force and then solving those using solve. But solve couldn’t represent Interval solutions and hence gave a NonImplemented error, as both of these quantities can occur in Intervals.

So instead of using solve over whole spam length, I found out points of discontinuity in the respective equations using

for term in terms:
    if isinstance(term, Mul):
         term = term.args[-1]

where terms are all the Muls extracted from Add. and term.args[-1] gives us the point of singularity.

Now between two singularity points, our function can be:

  1. A continuous and differentiable function (hence no Interval solution)
  2. or a constant value

for the first scenario, you just use solve over that interval and see values at the endpoint. The higher one of both gives you maxima in that interval. For the second, the constant value is indeed maximum by itself. Then compare maxims of all intervals and return location and its value.

>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E, I')
>>> l, P = symbols('l, P', positive=True)
>>> b = Beam(l, E, I)
>>> R1, R2 = symbols('R1, R2')
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(R2, l, -1)
>>> b.apply_load(P, 0, 0, end=l)
>>> b.solve_for_reaction_loads(R1, R2)
>>> b.max_bmoment()
(l/2, P*l**2/8)


Next Week

  • Beam class gives ValueError if passed value contains unit. So I would focus on fixing it.
  • Read relevant theory for implementation of 3dBeam class.

June 28, 2018

The second phase of Coding Period has started.

I started this phase working on sympy.discrete.recurrence module. After having an initial discussion with Kalevi regarding the functionality to be implemented, I did the proof-of-concept for the same on a remote branch.

After the approach was finalized, the implementation was polished before opening the PR. The PR #14816 also included documentation, doctests, and unit tests for the module.

The method linrec(coeffs, init, n) takes coefficients, initial values and point of evaluation for the linear recurrence. Usage for a recurrence like f(n) = f(n - 7) + f(n - 13) + f(n - 17) (having order 17) would be:

In []: coeffs, init = [0]*17, [1]*17
In []: coeffs[7 - 1] = coeffs[13 - 1] = coeffs[17 - 1] = 1
In []: [linrec(coeffs, init, n) for n in range(40, 50)]
Out[]: [17, 21, 21, 23, 29, 31, 31, 35, 41, 41]

In []: def f(n):
  ...:     if n < 17:
  ...:         return 1
  ...:     return f(n - 7) + f(n - 13) + f(n - 17)

In []: [f(n) for n in range(40, 50)]
Out[]: [17, 21, 21, 23, 29, 31, 31, 35, 41, 41]

As suggested by Aaron, it will be good to have a user-facing method that calls linrec internally for performing the computation.

Looking forward to another exciting week.

June 24, 2018

Here is the brief work done for rubi in the 6th week of GSoC period.

Last week almost 70 % of the miscellaneous algebra was tested. In the start of the week, the miscellaneous algebra testing was completed. The miscellaneous algebra test cases have been pushed in this PR.

After this, I moved on to load exponential rules and test them. While loading the exponential rules, there were some parsing issues. Those were fixed. On start of the testing, it was found that some integrals depend upon the logarithmic and special_function rules. Those too needed to be loaded. There were some undefined or wrongly defined utility_functions like `CancelCommonFactors`, `Gamma (gammainc)`, `PolyGamma`, `ProductLog` and few more small functions. These didn't take much time. I fixed all these.

Soon I realised a major issue of `exp` and `Pow`. Sympy doesn't identify exp as Pow. The rubi rules are defined in such a way that exp needs to be realised as Pow. I tried to process an expression to replace exp with Pow. These are the major methods I tried :
  • Pow(E, z, evaluate=False) . This does not work well, an expression containing Mul is evaluated to exp. I tried to fix it. I found that `flatten` of Mul causes the evaluation. I found the code messy. These can be solved but requires more time.
  • Pow(Dummy('E', z, evaluate=False) .This was suggested by Aaron. The matching part has no issues in this. But functions which use the property of `E` does not work properly. Like `Log(E)` should evaluate to 1.
  • Pow(UnevaluatedExpr(E), z) . In this the matching was as expected. I modified `Log` as `return log(z).doit()` . But then also there were some issues. I made a new subclass `rubi_unevaluated_expr`. To solve the commutative issue, I defined a property in this new subclass.
I think the last one is the best solution for now. Another issue was some rules which caused recursion errors like one in the image 

To solve it I checked that if last 5 rules applied are same then return a Function `Integrate` and replace it at last while returning. This works fine.

In this week, I was unable to do much testing. But I am sure the upcoming week will be better in this respect. I have tested a small part of exponential rules. In the upcoming week, I will try to finish exponential rules within 2-3 days and soon move to logarithmic rules. 

June 23, 2018

This week I worked on solving statically indeterminate beam systems and created #14826 for that. Some work was already done in #14681, which me and Jason reviewed during community bonding period.

Now Beam class uses boundary conditions (bc_deflection and bc_slope) to solve for unknown reactions, hence making statically indeterminate systems solvable.

>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E, I')
>>> F = Symbol('F')
>>> l = Symbol('l', positive=True)
>>> b5 = Beam(l, E, I)
>>> b5.bc_deflection = [(0, 0),(l, 0)]
>>> b5.bc_slope = [(0, 0),(l, 0)]
>>> R1, R2, M1, M2 = symbols('R1, R2, M1, M2')
>>> b5.apply_load(R1, 0, -1)
>>> b5.apply_load(M1, 0, -2)
>>> b5.apply_load(R2, l, -1)
>>> b5.apply_load(M2, l, -2)
>>> b5.apply_load(-F, l/2, -1)
>>> b5.solve_for_reaction_loads(R1, R2, M1, M2)
>>> b5.reaction_loads
{R1: F/2, R2: F/2, M1: -F*l/8, M2: F*l/8}

Next Week

  • Add max_bmoment and mx_shear_force methods to #14826.

For the sixth week, I started working on a few things as per the discussions with Amit:

  • Improving the API of transolve.

As transolve grew over the past few weeks the API became a bit messy, which was against the plan. So Amit suggested on to work on it to make it look clean. For this I added two internal functions add_type() and pow_type(), to handle expressions having add or power terms respectively. This could help us in achieving what we planned of: making the API extensible without it getting affected from the changes done in the function itself. If new solvers are to be added the modifcation has to be done in either of the internal functions.

  • Improved the working of _check_expo.

The implementation of the check_expo had a probelm, of not being generalised, only equations having two terms were checked. So the task was to make it generalised, so I implemented it using atoms, filtered the equations having Pow or exp with the help of .atoms() and then checked whether the variable that needs to be solved is present in the exponent or not but this too possesed a problem: asking for atoms was not a great choice as they can come from anywhere like cos(2**x).atoms(Pow, exp) would give 2**x and consequently the helper would return True, which is wrong. For this smichr suggested even better method of using .make_args(). We will seperate out all the Add arguments and then in each of them we will look for Mul arguments which will give us the atomic argument of the expression, now this term can be tested to have variable in the exponent.

  • Changes in the documentation

Also there were a few things that needed to fixed in the documentation. The docstring of expo_solver and check_expo were improved. Few changes were also done in transolve's documentation.

  • Worked on improvement of log solver

Apart from this I did some improvement in check_log to handle corner cases. As per the current logic check_log would return a “logcombined” equation to be further solved by log_solver, but this lead to a problem that the some equation (log(x**y) - y*log(x)) might get reduced to 0 and the check would fail, therefore this was handled by improving the condition as if condition not False. Apart from this single term expression needs to be properly handled.

Also I started getting familiar with lambert equations.

So these were the things that I worked on this week. The PR needs a bit more improvement to get merged, I will try to get it finished by mid of the coming week and start working on implementation of other solvers.

June 21, 2018

June 17, 2018

Hello everyone. Here is the brief summary of my work in the 5th week of GSoC period.

I started this week with testing miscellaneous algebraic test cases. Soon it was found that most test cases depend on rules of `Miscellaneous integration`. So I loaded those rules. There were few new structure in constraints. So parser too was updated for incorporating those. 

While testing, `ExpandIntegrand` did not function well. Matcher used in ExpandIntegrand was of sympy. I changed ExpandIntegrand using replace_all of matchpy. In few more functions I changed the structure using matchpy. In this week, a major part of the time was spent in utility functions. There are many changes. Also some of the test cases of last year was wrong. It gave different result in mathematica. The test cases which I have updated matches with Mathematica's output. I have pushed all changes of utility function in this PR.

Parallely I have also tested around 70 % of miscellaneous algebraic. I will complete the testing within one or two days. After this I will move on to exponential rules and exponential test cases.

So this is the last week of the first evaluation. I started with implementing log solver as part of transolve. As per the documentation of the transolve we will need two helpers for implementing log solver, check_log that will check whether the equation is logarithmic or not and log_solver that will solve the equation. Here’s the PR

Idea behind check_log

Heuristic is implemented to determine whether the equation is logarithmic or not. According to it the logarithmic equations can be reduced to simpler form using log identities. For this purpose we use SymPy’s function logcombine. If the equation is logarithmic it will be reduced and hence the number of log in the original and modified equation may differ. This will ensure that the equation is logarithmic.

Idea behind the log solver

The idea is simple, the reduced form from the check_log is used as the new target equation and is sent to solveset to handle. Solutions are retuned from solveset, but it may contain values that won’t satisfy the equation (log does not take negative values in real domain). Therfore to remove unwanted values we use checksol function of solve module which substitutes each solution in the equation and returns True if it satisfies otherwise False.

Apart from implementing helpers, I have added their documentation. Certain things needs to be done before the PR is ready for review: Tests needs to be added for the helpers and check_log needs to be improved a bit to handle corner cases.

In parallel I am also working on improving transolve's PR to make it merge as soon as possible. After these two gets completely fixed we will be focusing on implementing lambert equation solver.

In the coming week I will be focussing on finishing off the work of these two PR.

June 15, 2018

This week I worked on adding support for beams connected via hinge in #14773. Support for axially fixed beams and its API was implemented last week.

_solve_hinge_beams was added as a helper function to solve such Beams. This method resolves the composite Beam into its sub-beams and then equations of shear force, bending moment, slope and deflection are evaluated for both of them separately. These equations are then solved for unknown reactions and integration constants using the boundary conditions applied on the Beam. Equal deflection of both sub-beams at the hinge joint gives us another equation to solve the system.

So the final API looks like:


>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> l = symbols('l', positive=True)
>>> R1, M1, R2, R3, P = symbols('R1 M1 R2 R3 P')
>>> b1 = Beam(2*l, E, I)
>>> b2 = Beam(2*l, E, I)
>>> b = b1.join(b2,"hinge")
>>> b.apply_load(M1, 0, -2)
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(R2, l, -1)
>>> b.apply_load(R3, 4*l, -1
>>> b.apply_load(P, 3*l, -1)
>>> b.bc_slope = [(0, 0)]
>>> b.bc_deflection = [(0, 0), (l, 0), (4*l, 0)]
>>> b.solve_for_reaction_loads(M1, R1, R2, R3)
>>> b.reaction_loads
{R3: -P/2, R2: -5*P/4, M1: -P*l/4, R1: 3*P/4}
>>> b.slope().subs(x, 3*l)
>>> b.deflection().subs(x, 2*l)

Next Week

  • See for changes in #14786 to get it merged.
  • Add support for non-horizontal beams.
  • See for any remaining implementation from first two stages of my proposal.

The first phase of Coding Period has concluded.

This week, I started working on the convolution for -group using fwht - Dyadic (XOR) Convolution. The PR #14783 dealt with this addition to the module.

I had a useful discussion with Kalevi for clearing the API and naming convention.
The convolution method uses dyadic=True as the hint which uses convolution_fwht for the implementation. Appropriate documentation, doctests and unit tests are also included.

Successive reviews helped in refining the PR, before the final merge later in the week.

The usage for the same is:

>>> from sympy.discrete.convolution import convolution, convolution_fwht

>>> u, v, x, y = symbols('u v x y')
>>> convolution([u, v], [x, y], dyadic=True)
[u*x + v*y, u*y + v*x]
>>> convolution_fwht([u, v], [x, y]) == _

Plan for this phase has executed according to the timeline, and the first evaluation has been successful.

Looking forward to the next phase of Coding Period.

June 11, 2018

June 10, 2018

Hello everyone. Here is the brief work done in the 4th week.

In this week I have completed the testing of trinomial products. There are around 2700 test cases. I have tested them all in sympy. I have updated the PR .

Currently, a few tests are failing because of 2 major issues :
  1. Apart - Some features are unimplemented in apart of sympy. So expressions are not simplified.
  2. appellf1 - There is a missing implementation of appellf1 in sympy.
If the above two issues are solved, almost all tests will pass.

Utility functions have been improved a lot this week. The is_polynomial of sympy has certain issues and so the constraints were affected. I have re-written PolynomialQ. It is not full proof, but it handles most of the cases. There are many small changes in utility functions. They can be seen in the PR.

I am lagging behind my proposed timeline. But the work in rubi is time-consuming. When a test fails, finding the same rule in Mathematica, finding whether all constraints return the same result in Mathematica and sympy and finding whether utility functions are working in a different way takes time. I apologise for the same. I will try to speed up my work as much as possible.
In this week, I will be testing Miscellaneous algebra and Exponential tests.

June 09, 2018

This week me, Arihant and Jason discussed the API for creating composite Beam objects. Initially, we used Piecewise and SingularityFunction to represent our changing second_moment but then we agreed upon .join method to represent such beams. So the final API was like:

>>> b1 = Beam(2, E, 1.5*I)
>>> b2 = Beam(2, E, I)
>>> b = b1.join(b2, "fixed")
>>> b.length
>>> b.second_moment
Piecewise((1.5*I, x <= 2), (I, x <= 4))

Here b1.join(b2, "fixed") joins b2 at the right end of b1 via a fixed connection.All this was implemented in #14773 and hopefully it would be merged in coming few days.

I also created #14786 at the end of this week implementing apply_support and max_deflection methods.

apply_support is an easier way to apply support structures on our Beam object rather than adding all the reaction loads and moments and constraints on it by yourself. Its API is not finalised yet but for now it is something like:

>>>b.apply_support(position, type='hinge')

where position represents the position at which support was applied

and type is type of support structure. It can be either hinge, roller or cantilever.

Next Week

  • Add support for composite beams connected via hinge.
  • Add support for non-horizontal beams.
  • See for any remaining implementation from first two stages of my proposal.

Another week of Coding Period has concluded.

Starting this week, I worked on PR #14765 for implementing Fast Walsh Hadamard Transform (fwht).

As pointed out by Kalevi, symbolic coefficients could be supported by this transform as the general Kronecker matrix only contains +/-1, which means it essentialy requires only addition or subtraction to perform the transformation. Also, the PR review helped fix a minor issue related to string concatenation.

Usage for fwht looks like:

>>> from sympy import fwht, ifwht, symbols
>>> fwht([4, 2, 2, 0, 0, 2, -2, 0])
[8, 0, 8, 0, 8, 8, 0, 0]
>>> ifwht(_)
[4, 2, 2, 0, 0, 2, -2, 0]

>>> a, b, c, d = symbols('a b c d')
>>> fwht([a, b, c, d])
[a + b + c + d, a - b + c - d, a + b - c - d, a - b - c + d]
>>> ifwht(_)
[a, b, c, d]

Documentation, doctests, and unit tests are also added for this transform.

Looking forward to next week, where I will be implementing XOR convolution using fwht.

By the end of the previous week I had completed majority of the TODO’s of the PR #14736. This week I started on minor improvements suggested by Amit. This included:

  • Minor Documentation changes
    Included proof of correctness, typo fixes, rephrasing lines etc.

  • Removing flag variable from transolve.
    flag variable was passed as a function parameter in transolve and was used to check on the recursive call. The thought was that there might be a case when equation could not be solved by any of the helpers but during the process the equation might get modified, so we wanted to double check whether the modified equation could be solved again, thats why we used flag but Amit suggested on removing it as there wasn’t a case as of now and it will only make things unnecessarily complicated.

  • Also worked on XFAILS, mainly on solving equations containing only symbols. There was an exception raised in _invert_real, because of a relational comparison made with 0 which caused the faiure of the tests. It has been fixed by handling the exception.

  • Imported tests of log and lambert.

  • Another thing we discussed was about log solver. The helpers for solving logarithmic equations will be implemented in a seperated PR, to make the review and implementing task easy and independent.

After this I started a working on solving exponential equations in complex domain, though it turns out that we will be focussing on only the real domain as of now. But I have added tests for it as XFAIL.
To make exponents work in complex domain, we require the complex logarithm. If we have equation as

	z = e**w,
	where w is complex number and z is non-zero complex number,
	Ln(z) = ln|z| + I*(Arg(z) + 2*n*pi)
	where Ln(z) is the complex logarithm and ln|z| is the
        logarithm evaluated with real number argument.

Apart from this we also had a meeting yesterday in which we discussed about how we will be wrapping up things before the first evaluation.
I will be completing few leftovers of the current PR to make it merge and start working on implementing log solver (making a commit probably by tomorrow).

Amit also suggested on creating a coverage report so as to get an idea about the amount of tests covered by the code. The current coverage report can be found here. Other than this he also advised on reading Clean Code by Robert C. Martin which will help me improve in writing clean and efficient code.

The main target for the coming week will be merging PR #14736, implementing log solver (will try to merge this as well), starting with implementing lambert solver (try to add atleast a WIP PR) and reading the book.

Hope things go as planned!!

June 03, 2018

Hello everyone. Here is the update of my work in the third week of GSoC. 

Unlike last week, this week clarified some of the real problems of our implementation of rubi.
I began to freshly test trinomial products after getting the older test-suite. 

Initially, I came across the problem of Coeff and Sum. I solved this by redefining Coeff and introducing a function Sum_doit. After this, I realised With statement was not being parsed correctly for many cases. Parsetools was improved to take care of the with statements.

After this, I encountered with some utility functions where the output was not as expected. This is the major cause of the failing tests. Constraints too are affected by this. I tried to find and solve as much as possible. I have to trace all functions in cases of failing tests and compare the output with Mathematica. I improved few utility functions and updated in the PR. Also, there were some exceptions in Matchpy, where constraints were being checked taking x as a numerical value. It resulted in TypeErrors. So I updated the constraints in such a way that it avoids such exceptions.

After all this and some small changes, I almost have tested half of the trinomial products in the test-suite. Some issues are not solved yet, like : 
  • Sorting of variables.
  • Not implemented error in apart of sympy.
  • And few rules, which are not well defined.

Here is the brief work of this week:
  • Solved the issue of Sum and Coeff.
  • improved parsetools for with statements.
  • little modification to constraints definition.
  • improved utility functions
  • minor changes in parsetools.

I was supposed to completely test trinomial products within this week. I tried hard, but the debugging part is time taking. Finding the real issue for failing test, takes time. Also, it needs to be compared with Mathematica. But the good thing is that, after finding the issue and fixing it, tests are passing. So after this week, I can say that if we are good with our utility functions, we will be able to test more than 90% of the original rubi test suite.

In the upcoming week, I will do more testing and complete trinomial products.

The third week of Coding Period has concluded.

I started the week by finalizing the PR #14745. The PR has been merged successfully. The master branch of sympy now contains sympy.discrete.transforms and sympy.discrete.convolution. I have tested corner cases as well. Documentation and Doctests are complete for the transforms and types of convolution that are currently part of master.

Late this week, I pushed commits to PR #14712 with the aim of fixing failing tests in test_util.py and test_inequalities.py due to solveset. The remaining tests are failing as solvers can not currently solve the transcendental equations when rewritten in exponential form.

Looking forward to next week, where I will be working on the Fast Walsh Hadamard Transform (fwht).

June 02, 2018

I continued my work of week 2 in this week as well. Though I was travelling for 2-3 days, I was able to give most of the hours to the work dedicated for this week. I had to add a detailed descriptive documentation for transolve, for this I read documentation of the ode module as Amit and Harsh suggested, apart from this I read several other documentation of sympy modules. Made a commit regarding this in the PR.

As of now transolve supports solving majority of exponential equations. I have also imported exponential tests of solve and added a few of mine. Some of them needs another look, I have added them to XFAIL as of now. I am working on these tests to pass. Also done minor changes in the function, like removed force=True option from expand_log because using this option is not a healthy choice as the function expands logarithm without considering the assumptions (for exponents the variable should be real) which may sometime get a wrong result.

Idea behind transolve

The idea is simple, we are mainly focusing on making it modular and extensible. So to achieve this different identifying and solving helpers will be implemented that will identify the type of equation and then solve it. For detailed information refer to the PR

Idea behind exponential solver

Exponential equations are solved by using logarithms. Currently the expo_solver reduces the equation to log form which can further be handled by solveset itself. For this purpose expand_log function of sympy is used which reduces the equation using log identities. Take for example a simple exponential equation 3**(2*x) - 2**(x + 3), this equation can be reduced to 2*x*log(3) - (x+3)*log(2), this type of equation is easily solvable by solveset.

Once we approve on the documentation and the working of exponential solver I will proceed to implement logarithmic solver (probably in the coming week).

Hope things go as planned!!

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.