Polys work marvelously. They are speedy, cover a vast domain of polynomials, can take in functions like cos(x), 1/x as generators. So, Polys are extended easy to domains which are not exactly polynomial mathematically. Sympy is sympy much thanks to polys. But it is not complete.
Due to the vast powers that the Expr/Poly class has provided us with, large expressions are easy to form and common in calculations, resulting in expression blowup. Factorizing a matrix with simple elements like x, x+1, x**2 in it give factor matrices with very large expressions, all of which, when simplified give simple and small expressions. It is evident that sympy lacks somewhere.
What is lacks is expressions under division. The polys are smart enough to handle addition, subtraction and division, but for division, it doesn’t use any of its computation power. Thus the fundamental for operations are not complete in the true sense.
Many algorithms, especially linear algebra, assume that the elements it is operating on belong to a field, that is division is possible. Sympy expr’s will perform brilliantly if division is made clean.
Look here.
In [13]: a
Out[13]: x
In [14]: a=(a+1)**-1
In [15]: a
Out[15]:
1
─────
x + 1
In [16]: a=(a+1)**-1
In [17]: a
Out[17]:
1
─────────
1
1 + ─────
x + 1
In [18]: a=(a+1)**-1
In [19]: a
Out[19]:
1
─────────────
1
1 + ─────────
1
1 + ─────
x + 1
In [20]: a=(a+1)**-1
In [21]: a
Out[21]:
1
─────────────────
1
1 + ─────────────
1
1 + ─────────
1
1 + ─────
x + 1
In [22]: a=(a+1)**-1
In [23]: a
Out[23]:
1
─────────────────────
1
1 + ─────────────────
1
1 + ─────────────
1
1 + ─────────
1
1 + ─────
x + 1
In [24]: a.simplify()
Out[24]:
3⋅x + 5
───────
5⋅x + 8
The big expression on 23 simplified to the simplest Rational Function. Why wasn’t it simplified automatically ?
According to me, a should be simplified automatically, the very first time in Out[17]. Out[17] should be
x + 1 ───── x + 2
This would be easy with a Frac class.
The reason why I’m pitching so much for a Frac class is because, when I knew that sympy polys can take in cos(x), 1/x as gens, I knew that if we implement the Frac class, almost all of symbolic needs are done for. The fundamental four operators, +,-,*,/ will be implemented in the true sense in sympy. Of course things like sqrt will still not be supported by the Frac class, but it is often to see things like
⎽⎽⎽ ╲╱ x + x ───────── 3/2 x + 1
which can be treated as a Frac with generator x**1/2.
Sympy will be able to operate on common expressions like
4⋅sin(x) + 5⋅cos(x) + 4 ───────────────────────── 11⋅sin(x) + 2⋅cos(x) + 12
Currently, if the above expression is a, then
In [49]: (a+1)**-1
Out[49]:
1
─────────────────────────────
4⋅sin(x) + 5⋅cos(x) + 4
───────────────────────── + 1
11⋅sin(x) + 2⋅cos(x) + 12
which is just sad.
Hence, IMHO, the Frac class would be a great step forward for sympy, and would be a great asset of sympy.
vks
June 23, 2011 at 9:17 pm
I don’t think it should be simplified automatically. If the user tells sympy explicitly to use a Frac class it’s ok, but we should not make this decision over the head of the user.
Aaron Meurer
June 24, 2011 at 8:57 am
I think maybe he was making the point that if he had built the expression using Frac(), then it would be canonicalized automatically.
saptman
June 24, 2011 at 9:20 am
I had reiterated over this exact same philosophy for the boolean algebra functionality. There, all the NNF forms were being calculated automatically so a given expression was automatically simplified. This is not a good behaviour as Sympy (rather any other good software) should only do that which it is explicitly told to do, nothing more and nothing less.
asmeurer
June 25, 2011 at 10:05 am
I’ve written some of my ruminations on automatic simplification on the wiki (see https://github.com/sympy/sympy/wiki/Automatic-Simplification), if you are interested.