SymPy - a Python library for symbolic mathematics
sympy.org
sympy.org
In addition to the already-excellent official tutorial https://docs.sympy.org/latest/tutorial/index.html , I have written a short printable tutorial summary of the functions most useful for students https://minireference.com/static/tutorials/sympy_tutorial.pd...
For anyone interested in trying SymPy without installing, there is also the online shell https://live.sympy.org/ which works great and allows you to send entire computations as a URL, see for example this comment that links to an important linear algebra calculation: https://news.ycombinator.com/item?id=23158095
SymPy vs Matlab: https://github.com/sympy/sympy/wiki/SymPy-vs.-Matlab
If you then or later need to do distributed ML, it is advantageous to be working in Python. Dask Distributed, Dask-ML, RAPIDS.ai (CuDF), PyArrow, xeus-cling
However, as a slightly-more-than-beginner user I have a frustrating time getting SymPy to take simplifications that I know are valid. As a result the generated answers are correct but so complicated that the "simple intuitive understanding" goal of the symbolic computation is lost.
This can come down to having implicit assumptions that I haven't told SymPy (such as variables being real-valued, or it being okay to take the principal roots of exp(I <stuff>)), but not always.
As a minimal example:
import sympy as sp # Import SymPy
# Define variables; note they're marked as real-valued
x = sp.Symbol('x', real=True);
t = sp.Symbol('t', real=True);
# Get our simple expression: 2*cos(t)*exp(x) but written in complex form
foo = sp.exp((x+sp.I*t)) + sp.exp((x-sp.I*t))
print(str(foo))
# Prints exp(-I*t + x) + exp(I*t + x)
print(str(foo.simplify()))
# Still prints exp(-I*t + x) + exp(I*t + x) -- SymPy thinks this is the simplest form?
print(str((foo/sp.exp(x)).simplify())) # Help it along
# Prints 2*cos(t)
Obviously, forcing SymPy to do the desired thing gets worse with more complicated expressions. Sometimes I can bash it into compliance with liberal use of `rewrite` or by demanding it simplify term-by-term, but if I'm deconstructing the expression only to reassemble it at the end then I'm not sure I'm still gaining much out of it as a computer algebra system.Your larger point is true though, at least from my experience.
bar = sp.exp(sp.I*(x + k - t)) - sp.exp(sp.I*(x+k+t))
The desired output would be 2 cos(t) exp(I(x+k)), but rewrite and simplify works on an all-or-nothing basis, affecting exp(I(x+k)) as well.My mental framework is to come at this from something like a signal engineering perspective, looking at amplitude-modulated single frequencies. However, expressing that intent in a way that SymPy understands is for now beyond me.
My problem may ultimately be one of documentation. The basic SymPy tutorials are quite nice, and the raw documentation for the functions... exists, but I have yet to find good examples of intermediate to advanced use discussing the "what and why" of accomplishing nontrivial goals.
I have used it to assist me in some formal proofs. (I hope to publish that later.)
Note that in my case, I hit a couple of bugs. See the GitHub issue tracker (https://github.com/sympy/sympy/issues). The bugs are easy to detect when you just get an exception (which was often the case for me). However, you can also simply get an incorrect result, which can be more tricky to detect. So be careful and maybe don't trust the results right away without double checking them in some other way.
solve(Eq(w*x + y*z,0), [w,x,y,z], dict=True)
returns the incorrect result ⎡⎧ -y⋅z ⎫⎤
⎢⎨w: ─────⎬⎥
⎣⎩ x ⎭⎦
which is invalid when x is zero. There are more compelling examples, but I don't know any off the top of my head. Interestingly, Wolfram Alpha seems to be better at returning the whole solution, so I use it in combination with Sympy.Things that the SageMath CAS can do that SymPy cannot yet:
- solve multivariate systems of inequalities
[0] https://doc.sagemath.org/html/en/faq/faq-general.html#why-di...
There is an effort to speed up SymPy core, SymEngine [4], but it's been in development for years now, and still isn't integrated into SymPy. Not sure why.
Case in point: 'expand("(2 + 3 * x + 4 * x * y)^60")' takes 5 seconds with SymPy; Sage (Pynac) does the same in 0.02 seconds.
In my case I got a 7x speedup.
> SymEngine is a standalone fast C++ symbolic manipulation library. Optional thin wrappers allow usage of the library from other languages, e.g.:
> [...] Python wrappers allow easy usage from Python and integration with SymPy and Sage (the symengine.py repository)
https://en.wikipedia.org/wiki/SymPy > Related Projects:
> SymEngine: a rewriting of SymPy's core in C++, in order to increase its performance. Work is currently in progress to make SymEngine the underlying engine of Sage too
On one hand it's great that it was written in Python and fairly extensible thanks to that, but on the other it's a shame, since it probably will never be fast enough for high performance symbolic computing.
That said I think CASes (Computer Algebra Systems) are heavily under-utilised nowadays. Schools and universities should use is as widely as possible i.e. it should be even more widely used than calculator is/once was. I believe that for every two hours of regular pen-and-paper exercises there should be at least one hour of CAS assisted computer exercises. It's pretty radical and sadly there aren't enough teachers (even in good universities/colleges), that know CASes enough to teach that, so it isn't gonna happen any time soon. Maybe I'm biassed here (I hated doing repeated exercises, such as algebraic simplifications, fraction simplifications etc. in high school), because I use CASes as crutches for doing tough math, but I believe sciences would benefit if more papers in math and physics was written as a code (less mistakes, plus it's not a mistake – it's a bug!). Hopefully it will happen someday and we will have "open source derivations" of formulas, theories, theorems etc. :)
That said, the thing about CASes I'm missing most is more hand guided, step-by-step and mathematical transformations assistant approach. Recently they added a bit of this kind of functionality to Mathematica 12 (sadly I use it most of the time, despite it being closed source) – functions like AddSides, MutiplySides, ApplySides – but I think it's still too automatic for what I have in mind. Hopefully when I finish my PhD I will have some time to work on the kind of "assistant CAS" I have in mind using projects like SymPy, Maxima and Reduce for some parts. What I have in mind is to make hand-like derivations using CAS and let it do small things, like I want to substitute log(a) as x in integral, so find dx for this substitution (actually SymPy has this functionality, even though slightly limited at the moment! [https://github.com/sympy/sympy/blob/58e1e9abade7c38c66871fd0...) and do more things this way (series, equations, inequalities, derivatives, limits, operators etc).
Yeah, it's probably more suited for series of blog posts than HN comment but if someone knows FOSS software that is focused on this kind of approach I'll be thankful for links to articles code etc.
Sage is a lot larger than Sympy (it's more than 1 million LOC AFAIK), but it still delegates to other libraries to do most types of underlying symbolic and numerical computations.
I usually use sympy (or rather some wrapper of symengine these days) when I'm writing a pure python script, sage otherwise.
For a lot of math and CS courses, I think having some knowledge of some sort of computer-assisted theorem proving. I think the most promising is maybe Lean these days (Coq still might take too long to learn): https://github.com/leanprover-community/mathlib
There’s also the SymEngine project, which is a rewrite of SymPy in C++ with bindings to other languages (like Python where it is a drop-in API replacement for SymPy). It’s not finished yet, but the CAS is a lot faster and it’s lambdify can give you an internal representation or an LLVM-compiled version, both of which are much faster than SymPy in compile-time and run-time for our expressions (which are often quite large, but simple in terms of the mathematical functions used).
Yeah, SymEngine is a great idea and it is a lot faster, but its functionality is very limited compared to SymPy. The development is slower than SymPy and I suppose its due to the fact that its in C++, which is more difficult to write after all. Therefore I don't believe it will ever catch up with SymPy features and it boils down to the two-language problem. I think Julia (with multiple dispatch, parametric type system and JIT) is a great candidate for CAS, but it's still very far behind SymPy (although the nice thing is that functionalities can be "borrowed" via PyCall until they are rewritten).
I’m damn sure not calculating permutation groups by hand.
But it can also be useful as a library, when you develop sth where some symbolic derivation can be useful.
A fun place to start is the Natural Number Game: https://wwwf.imperial.ac.uk/~buzzard/xena/natural_number_gam...
It's also much more targeted - it's only comparable to the symbolic math portion of Mathematica. To get a similar experience, you should use sympy in a Jupyter notebook environment, use numerical libraries (numpy, scipy, scikit-learn), and learn some plotting libraries (matplotlib, bokeh, or my favorite, plotnine).
Anyone has tips to reduce time required to simplify?
Another tip I don't think gets mentioned enough, try to provide domain information for your symbolic variables. By default all these systems assume the most general solution. But if you know x is a positive real value, you should tell that to SymPy.
Please describe how you managed to get Sage to use sympy, thanks.
https://doc.sagemath.org/html/en/reference/calculus/sage/cal...