|
|
Subscribe / Log in / New account

Doing symbolic math with SymPy

LWN.net needs you!

Without subscribers, LWN would simply not exist. Please consider signing up for a subscription and helping to keep LWN publishing

December 22, 2020

This article was contributed by Lee Phillips

On November 29, version 1.7 of SymPy, a Python library for symbolic mathematics, was released. The new version brings a large number of enhancements and bug fixes, and some minor backward incompatibilities. While these are enumerated in detail in the release notes, we will take advantage of this opportunity to look at some of the things that can be done with SymPy and explore its interface options through several detailed examples.

What is SymPy?

SymPy performs symbolic mathematical manipulations using Python. Like others of its kind, it can solve algebraic and differential equations, simplify expressions, apply trigonometric identities, differentiate, and integrate; SymPy knows things about sets, manifolds, tensors, and many other mathematical objects. It offers a convenient interface to Matplotlib, the Python plotting library that I looked at back in 2015; this allows a seamless graphical exploration of results.

Although they are not limited to algebra, members of this category of software are universally called computer algebra systems (abbreviated CAS), so I will adopt this term here. Computer algebra systems are not used primarily for numerical work, as is a program such as Octave, which I reviewed recently. They combine the encoded knowledge of specialists in diverse mathematical fields with strategies of expression transformation to perform actual symbolic mathematical manipulations. These programs do not replace a human mathematician in creating new mathematical knowledge, but they can solve problems that can be reduced to a set of rules and mechanical procedures, such as finding an integral or factoring a polynomial.

Who uses SymPy?

Anyone who needs to carry out non-trivial mathematical manipulations can potentially benefit from a computer algebra system. It can be used to check work done by hand, to replace weighty tomes of formulas, to solve large systems of equations that cannot (or should not) be done with pencil and paper, or to explore, symbolically and graphically, a mathematical landscape.

There are many computer algebra systems available, both of the free-software variety and proprietary offerings. The most well-known of the commercial programs is certainly Mathematica, while SymPy is one of the most popular free-software computer algebra systems. Their predecessors go back decades. The first system of this kind was Macsyma, which arrived in the 1960s, and is still offered as a commercial product, though apparently only for Windows. I wrote about its free-software offshoot, Maxima, in a 2017 LWN article where I surveyed programs for symbolic mathematics available for Linux.

Maxima was for many years the standard general-purpose, free-software computer algebra system. Although it is still the preferred such program for many practitioners, the comparatively young SymPy has become a prominent choice over the past decade. This is due to several factors, such as its inclusion in other packages, in particular Sage, which is a large system that bundles and provides a unified interface to many numerical, graphical, and symbolic software packages. Another reason behind SymPy's wide adoption is that it is a Python library, so the large population familiar with Python's syntax will not be tripped up when using SymPy. In contrast, Maxima is written in Lisp and has its own syntax that the user is obligated to master.

Many who use SymPy do so within Sage; however, for those who don't need the other things that come with Sage, installing standalone SymPy makes more sense. For one, Sage takes up over a gigabyte of storage space, due to the large number of packages that it bundles, while my SymPy installation takes up just 63 megabytes, including its 45 standard modules. SymPy can be included in other Python code with a single import statement, and its liberal BSD license presents no obstacles to any form of distribution.

SymPy's only dependency is mpmath, which is a library for arbitrary precision arithmetic that is also BSD-licensed. Users installing from source will have to install mpmath before installing SymPy, but pip will install it automatically. SymPy and mpmath are included in projects such as the Anaconda data-science platform. In addition, there is a symbolic math package for Octave that implements SymPy inside of that numerical toolbox.

Using SymPy

Since SymPy is a Python library, it can be used wherever Python can be used. It can be imported into scripts, incorporated into applications, or used from any of Python's interactive environments, including the plain read-eval-print loop (REPL), the IPython enhanced REPL, or Jupyter.

Let's first try the IPython interface. After typing ipython in a terminal and getting the IPython startup message, the user types two commands, shown in the figure below, to start up the SymPy environment. The first command imports one function from SymPy, which is then run to bootstrap the rest. This function, init_session(), imports the rest of SymPy and then invokes the SymPy symbols() function three times.

[Starting IPython]

The purpose of the calls to symbols() is to define some names for variables that can be used in mathematical expressions. This is necessary because, in Python, you may not use undefined symbols in expressions, but in a computer algebra system you need to refer to variables somehow—symbols that, by definition, have not been assigned a value. init_session() establishes a handful of variables with conventional names, and of course the user is free to define as many more as required. Finally, init_printing() sets up any defaults for printing results to the terminal.

If the terminal in use supports Unicode, SymPy will form mathematical output from Unicode glyphs. To see what this looks like, we'll ask it to simply represent an integral for us, using the Integral() function, which returns an unevaluated integral. The figure below shows how the integral sign is built up to the required height using line segment glyphs, how Greek letters are used for mathematical constants, and the infinity symbol, which is entered on the command line using a double "o".

[Unicode IPython]

Now let's do a little math. As mentioned above, SymPy comes with a good number of specialized modules. In the following figure we import the geometry module, which knows about a variety of planar geometrical objects. We define a point at the origin, and a circle centered there, with a radius of one. Then we define two more points, and a line connecting them. This line should be horizontal and touch the circle at its highest point. The next two commands check on that.

[Geometry]

First we ask SymPy whether the line is tangent to the circle, and it confirms that it is. Then we ask where the line and circle intersect. The answer, at x = 0 and y = 1, is what we expected.

The qtconsole interface for SymPy has several advantages over the IPython interface. The most significant is that it can typeset math using LaTeX, which helps immensely in reading complicated expressions in the output. Other nice features are embedded graphs and automatic function documentation: when typing an open-parenthesis after a function name, the qtconsole will immediately pop up a box with the function signature, if it recognizes the name, and some documentation about the function, as shown in the figure below:

[Function info]

Hitting escape or clicking anywhere in the window dismisses the documentation box. Tab-completion works in qtconsole, as does accessing command history with the arrow keys, which is the same as it is in the IPython interface. At least on my machine, qtconsole is deaf to control-C, but I was able to cancel any pending input with the escape key.

The disadvantages of using the qtconsole are that it involves extra installs; on my machine I had to install the PyQt5 package with pip. It also did not, at first, handle my screen resolution correctly. Those with screen resolutions larger than 72 dots per inch will need to enter the command:

    init_printing(scale=2, forecolor='Black')

That will create larger LaTeX output. The scale factor can be set as desired, and the color setting creates more legible output than the default medium grey.

If using inline plots, which you get with the "%matplotlib inline" command, Matplotlib also needs to know about the screen resolution:

    matplotlib.rcParams['figure.dpi'] = 220

The number need not match the actual resolution, but can be set as a convenient way to get the desired figure size. All of the above commands are entered at the interactive prompt within the qtconsole session. After this is done, the interface performs well and is a pleasure to use.

The following figure is designed to convince the user of the advantage of LaTeX output. Simple-looking problems often lead to hairy expressions; the result of solving this innocent-looking integral would be difficult to parse using ASCII or even SymPy's well-executed Unicode output.

[TeX is nice]

The next example includes an embedded line graph and shows off SymPy's knowledge of special functions and integrals. It asks for the integral of a Gaussian, which is called the error function, written as erf(). The plot command uses _ in the argument, which stands for the most recently returned result. The basic plotting functions are imported automatically with SymPy.

[erf() plot]

Our last example demonstrates multiple integration and surface plotting. Before using this plotting function, plot3d must be imported from sympy.plotting. The plot command again refers to the previous result, and defines limits for the x and y coordinates.

[Surface plot]

The new release

The 1.7 release brings a few backward-incompatible changes. Some of these involve the naming of modules, so the import statements in existing scripts may need to be updated. Another possible disruption for some users is the dropping of support for Python 3.5; the minimum version now required by SymPy is Python 3.6.

The new version brings a handful of improvements to SymPy's understanding of trigonometric functions, absolute values, and other mathematical objects, which improve its ability to simplify expressions. Translation of the output to LaTeX now works better in some situations, and it is more convenient to substitute another plotting library for Matplotlib.

New capabilities were added to several modules, including physics, statistics, and the ordinary differential equation solver; the relevant sections of the release notes contain links to the issue tracker entries for each of these, which users of these packages may want to consult.

Documentation and assistance

The starting place to learn how to use SymPy is the documentation based on the current release, which covers the various methods of installation, includes a nicely done tutorial aimed at people who might not know what a computer algebra system is, has a detailed reference to all the standard SymPy modules, and contains information about the SymPy project. This manual is mostly up-to-date and quite good, although it contains a few corners with obsolete information.

One wonderful feature of the documentation is that every code block comes with a button that opens a window where a live notebook interface called SymPy Live is running; the code in the block is copied to the window and executed.

There are some glitches, however. The documentation is up to date, covering, as of this writing, version 1.7.1; but the SymPy Live instance is still on 1.5. The consequence of that is that some code blocks in the documentation produce errors in the SymPy Live window. Another problem, unavoidable in a service such as this, is that the response is much slower in general than what a user will experience with a locally installed SymPy. Direct access to SymPy Live is also provided here, free for anyone to experiment with the software.

Users seeking help from others may want to turn to the general mailing list, hosted on Google Groups, or the Gitter channel; there is also an IRC channel called #sympy.

SymPy Gamma is an interesting project with SymPy at its core. It aspires to offer something similar to Wolfram Alpha, which is an online mathematical knowledge engine. SymPy Gamma presents several example topics in mathematics and the user can type in problems or questions. It has made impressive progress, but it not yet in the same league as Wolfram Alpha, in general failing to answer open-ended questions about mathematical objects, but presenting a nice variety of information in response to a more focused query.

If the user simply types a mathematical expression, the engine will reply with its typeset form, graph (only of single-variable expressions), roots, derivative, antiderivative, series expansion, and sometimes more, depending on the type of expression entered. This is all provided without the user needing to know the syntax for calculating these things, so this is a way to make some use of SymPy without having to learn anything about it, or even about Python, aside from the basic syntax related to mathematics.

Anyone in need of a general environment for computer-assisted mathematics will be well-served by either Maxima or SymPy. Which one to use depends on several factors, which include the availability and maturity of modules for any needed specialized areas of math or science. Lisp experts interested in possibly adding to the system or improving existing routines, while occasionally dropping down into the Lisp subsystem, will naturally gravitate towards Maxima. SymPy is a good choice for those already experienced with Python or who are interested in adding mathematical intelligence to a Python project.


Index entries for this article
GuestArticlesPhillips, Lee
PythonLibraries
PythonScientific computing


(Log in to post comments)

Doing symbolic math with SymPy

Posted Dec 23, 2020 7:17 UTC (Wed) by rsidd (subscriber, #2582) [Link]

Very impressive. I had looked at SymPy briefly several years ago, and tried to re-write some of the code from Sussman and Wisdom's "Structure and Interpretation of Classical Mechanics" in python. (The original, a unique and brilliant approach to classical mechanics, has code written in a particular version of scheme.) I should re-look at this.

Doing symbolic math with SymPy

Posted Jan 8, 2021 13:57 UTC (Fri) by sritchie (guest, #144048) [Link]

If you do decide to have another go, I might recommend taking a look at the Clojure port of "scmutils" that I maintain with Colin Smith: https://github.com/sicmutils/sicmutils. The port has generated a ton of documentation and tests, and I imagine it'd be an easier start to figure out where to begin your Clojure port.

This page has a sketch of the library's architecture (which closely mirrors the original scmutils): https://github.com/sicmutils/sicmutils/wiki/Library-Design

Cheers!

Doing symbolic math with SymPy

Posted Dec 23, 2020 16:57 UTC (Wed) by paulbarker (subscriber, #95785) [Link]

The article says "there is also an IRC channel called #sympy.". It may be helpful to add on which IRC network this channel can be found.

Doing symbolic math with SymPy

Posted Dec 23, 2020 17:07 UTC (Wed) by leephillips (subscriber, #100450) [Link]

It’s freenode.

Doing symbolic math with SymPy

Posted Dec 28, 2020 23:59 UTC (Mon) by asmeurer (guest, #117121) [Link]

The #sympy IRC channel is no longer used. If you want to chat about SymPy you should use the Gitter channel at gitter.im/sympy


Copyright © 2020, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds