SymPy is an open source computer algebra system written in pure Python. It is built with a focus on extensibility and ease of use, through both interactive and programmatic applications. These characteristics have led SymPy to become a popular symbolic library for the scientific Python ecosystem. This paper presents the architecture of SymPy, a description of its features, and a discussion of select submodules. The supplementary material provide additional examples and further outline details of the architecture and features of SymPy.
SymPy is a full featured computer algebra system (CAS) written in the Python (
Python is a dynamically typed programming language that has a focus on ease of use and readability.
This paper assumes a moderate familiarity with the Python programming language.
Due in part to this focus, it has become a popular language for scientific computing and data science, with a broad ecosystem of libraries (Unlike many CAS’s, SymPy does not invent its own programming language. Python itself is used both for the internal implementation and end user interaction. By using the operator overloading functionality of Python, SymPy follows the embedded domain specific language paradigm proposed by
SymPy is designed with a strong focus on usability as a library. Extensibility is important in its application program interface (API) design. Thus, SymPy makes no attempt to extend the Python language itself. The goal is for users of SymPy to be able to include SymPy alongside other Python libraries in their workflow, whether that be in an interactive environment or as a programmatic part in a larger system.
Being a library, SymPy does not have a builtin graphical user interface (GUI). However, SymPy exposes a rich interactive display system, and supports registering display formatters with Jupyter (
The remainder of this paper discusses key components of the SymPy library. Section ‘Overview of capabilities’ enumerates the features of SymPy and takes a closer look at some of the important ones. The Section ‘Numerics’ looks at the numerical features of SymPy and its dependency library, mpmath. Section ‘Physics Submodule’ looks at the domain specific physics submodules for performing symbolic and numerical calculations in classical mechanics and quantum mechanics. Section ‘Architecture’ discusses the architecture of SymPy. Section ‘Projects that Depend on SymPy’ looks at a selection of packages that depend on SymPy. Conclusions and future directions for SymPy are given in ‘Conclusion and Future Work’. All examples in this paper use SymPy version 1.0 and mpmath version 0.19.
Additionally, the
The following statement imports all SymPy functions into the global Python namespace.
The three greaterthan signs denote the user input for the Python interactive session, with the result, if there is one, shown on the next line.
>>> from sympy import *
All the examples in this paper can be tested on
This section gives a basic introduction of SymPy, and lists its features. A few features—assumptions, simplification, calculus, polynomials, printers, solvers, and matrices—are core components of SymPy and are discussed in depth. Many other features are discussed in depth in the
Symbolic variables, called symbols, must be defined and assigned to Python variables before they can be used. This is typically done through the
>>> x, y, z = symbols('x y z')
creates three symbols representing variables named
Expressions are created from symbols using Python’s mathematical syntax. For instance, the following Python code creates the expression (
>>> (x**2  2*x + 3)/y
(x**2  2*x + 3)/y
Although SymPy’s extensive feature set cannot be covered in depth in this paper, bedrock areas, that is, those areas that are used throughout the library, are discussed in their own subsections below. Additionally,
Feature (submodules)  Description 

Calculus ( 
Algorithms for computing derivatives, integrals, and limits. 
Category Theory ( 
Representation of objects, morphisms, and diagrams. Tools for drawing diagrams with Xypic ( 
Code Generation ( 
Generation of compilable and executable code in a variety of different programming languages from expressions directly. Target languages include C, Fortran, Julia, JavaScript, Mathematica, MATLAB and Octave, Python, and Theano. 
Combinatorics & Group Theory ( 
Permutations, combinations, partitions, subsets, various permutation groups (such as polyhedral, Rubik, symmetric, and others), Gray codes ( 
Concrete Math ( 
Summation, products, tools for determining whether summation and product expressions are convergent, absolutely convergent, hypergeometric, and for determining other properties; computation of Gosper’s normal form ( 
Cryptography ( 
Block and stream ciphers, including shift, Affine, substitution, Vigenère’s, Hill’s, bifid, RSA, Kid RSA, linearfeedback shift registers, and Elgamal encryption. 
Differential Geometry ( 
Representations of manifolds, metrics, tensor products, and coordinate systems in Riemannian and pseudoRiemannian geometries ( 
Geometry ( 
Representations of 2D geometrical entities, such as lines and circles. Enables queries on these entities, such as asking the area of an ellipse, checking for collinearity of a set of points, or finding the intersection between objects. 
Lie Algebras ( 
Representations of Lie algebras and root systems. 
Logic ( 
Boolean expressions, equivalence testing, satisfiability, and normal forms. 
Matrices ( 
Tools for creating matrices of symbols and expressions. Both sparse and dense representations, as well as symbolic linear algebraic operations (e.g., inversion and factorization), are supported. 
Matrix Expressions ( 
Matrices with symbolic dimensions (unspecified entries). Block matrices. 
Number Theory ( 
Prime number generation, primality testing, integer factorization, continued fractions, Egyptian fractions, modular arithmetic, quadratic residues, partitions, binomial and multinomial coefficients, prime number tools, hexidecimal digits of 
Plotting ( 
Hooks for visualizing expressions via matplotlib ( 
Polynomials ( 
Polynomial algebras over various coefficient domains. Functionality ranges from simple operations (e.g., polynomial division) to advanced computations (e.g., Gröbner bases ( 
Printing ( 
Functions for printing SymPy expressions in the terminal with ASCII or Unicode characters and converting SymPy expressions to 
Quantum Mechanics ( 
Quantum states, bra–ket notation, operators, basis sets, representations, tensor products, inner products, outer products, commutators, anticommutators, and specific quantum system implementations. 
Series ( 
Series expansion, sequences, and limits of sequences. This includes Taylor, Laurent, and Puiseux series as well as special series, such as Fourier and formal power series. 
Sets ( 
Representations of empty, finite, and infinite sets (including special sets such as the natural, integer, and complex numbers). Operations on sets such as union, intersection, Cartesian product, and building sets from other sets are supported. 
Simplification ( 
Functions for manipulating and simplifying expressions. Includes algorithms for simplifying hypergeometric functions, trigonometric expressions, rational functions, combinatorial functions, square root denesting, and common subexpression elimination. 
Solvers ( 
Functions for symbolically solving equations, systems of equations, both linear and nonlinear, inequalities, ordinary differential equations, partial differential equations, Diophantine equations, and recurrence relations. 
Special Functions ( 
Implementations of a number of well known special functions, including Dirac delta, Gamma, Beta, Gauss error functions, Fresnel integrals, Exponential integrals, Logarithmic integrals, Trigonometric integrals, Bessel, Hankel, Airy, Bspline, Riemann Zeta, Dirichlet eta, polylogarithm, Lerch transcendent, hypergeometric, elliptic integrals, Mathieu, Jacobi polynomials, Gegenbauer polynomial, Chebyshev polynomial, Legendre polynomial, Hermite polynomial, Laguerre polynomial, and spherical harmonic functions. 
Statistics ( 
Support for a random variable type as well as the ability to declare this variable from prebuilt distribution functions such as Normal, Exponential, Coin, Die, and other custom distributions ( 
Tensors ( 
Symbolic manipulation of indexed objects. 
Vectors ( 
Basic operations on vectors and differential calculus with respect to 3D Cartesian coordinate systems. 
The assumptions system allows users to specify that symbols have certain common mathematical properties, such as being positive, imaginary, or integer. SymPy is careful to never perform simplifications on an expression unless the assumptions allow them. For instance, the simplification
In SymPy,
By default, SymPy performs all calculations assuming that symbols are complex valued. This assumption makes it easier to treat mathematical problems in full generality.
>>> t = Symbol('t')
>>> sqrt(t**2)
sqrt(t**2)
By assuming the most general case, that
Assumptions are set on
>>> t = Symbol('t', positive=True)
>>> sqrt(t**2)
t
Some of the common assumptions are
SymPy assumes that two expressions
Assumptions are only needed to restrict a domain so that certain simplifications can be performed. They are not required to make the domain match the input of a function. For instance, one can create the object
The assumptions system additionally has deductive capabilities. The assumptions use a threevalued logic using the Python built in objects
Basic implications between the facts are used to deduce assumptions. Deductions are made using the Rete algorithm (
For historical reasons, this algorithm is distinct from the
>>> i = Symbol('i', integer=True)
>>> i.is_rational
True
Furthermore, expressions compute the assumptions on themselves based on the assumptions of their arguments. For instance, if
The generic way to simplify an expression is by calling the
The
It is often preferable to apply more directed simplification functions. These apply very specific rules to the input expression and are typically able to make guarantees about the output. For instance, the

expand the expression 

factor a polynomial into irreducibles 

collect polynomial coefficients 

rewrite a rational function as 

compute the partial fraction decomposition of a rational function 

simplify trigonometric expressions ( 

expand hypergeometric functions ( 
Examples for these simplification functions can be found in
SymPy provides all the basic operations of calculus, such as calculating limits, derivatives, integrals, or summations.
Limits are computed with the
>>> limit(x*sin(1/x), x, oo)
1
As a more complex example, SymPy computes
>>> limit((2*exp((1cos(x))/sin(x))1)**(sinh(x)/atan(x)**2), x, 0)
E
Derivatives are computed with the
>>> diff(sin(x)*exp(x), x)
exp(x)*sin(x) + exp(x)*cos(x)
Integrals are calculated with the
and
>>> s, t = symbols('s t', positive=True)
>>> integrate(exp(s*t)*log(t), (t, 0, oo)).simplify()
(log(s) + EulerGamma)/s
>>> integrate((2*x**2*(log(x) + 1)*exp(x**2) +
... (exp(x**2) + 1)**2)/(x*(exp(x**2) + 1)**2*(log(x) + 1)), x)
log(log(x) + 1) + 1/(exp(x**2) + 1)
Summations are computed with the
>>> i, n = symbols('i n')
>>> summation(2**i, (i, 0, n  1))
2**n  1
>>> summation(i*factorial(i), (i, 1, n))
n*factorial(n) + factorial(n)  1
Series expansions are computed with the
>>> series(sin(x), x, 0, 6)
x  x**3/6 + x**5/120 + O(x**6)
>>> integrate(x**x, x)
Integral(x**x, x)
>>> Sum(2**i, (i, 0, n  1))
Sum(2**i, (i, 0, n  1))
SymPy implements a suite of algorithms for polynomial manipulation, which ranges from relatively simple algorithms for doing arithmetic of polynomials, to advanced methods for factoring multivariate polynomials into irreducibles, symbolically determining real and complex root isolation intervals, or computing Gröbner bases.
Polynomial manipulation is useful in its own right. Within SymPy, though, it is mostly used indirectly as a tool in other areas of the library. In fact, many mathematical problems in symbolic computing are first expressed using entities from the symbolic core, preprocessed, and then transformed into a problem in the polynomial algebra, where generic and efficient algorithms are used to solve the problem. The solutions to the original problem are subsequently recovered from the results. This is a common scheme in symbolic integration or summation algorithms.
SymPy implements dense and sparse polynomial representations.
In a dense representation, the coefficients for all terms up to the degree of each variable are stored in memory. In a sparse representation, only the nonzero coefficients are stored.
Both are used in the univariate and multivariate cases. The dense representation is the default for univariate polynomials. For multivariate polynomials, the choice of representation is based on the application. The most common case for the sparse representation is algorithms for computing Gröbner bases (Buchberger, F4, and F5) (Some examples for the
SymPy has a rich collection of expression printers. By default, an interactive Python session will render the
Many Python libraries distinguish the
>>> phi0 = Symbol('phi0')
>>> str(Integral(sqrt(phi0), phi0))
'Integral(sqrt(phi0), phi0)'
A twodimensional (2D) textual representation of the expression can be printed with monospace fonts via
Alternately, the
>>> pprint(Integral(sqrt(phi0 + 1), phi0), use_unicode=False)
/

 __________
 \/ phi0 + 1 d(phi0)

/
The function
>>> print(latex(Integral(sqrt(phi0 + 1), phi0)))
\int \sqrt{\phi_{0} + 1}\, d\phi_{0}
Users are encouraged to run the
Other printers such as MathML are also available. SymPy uses an extensible printer subsystem, which allows extending any given printer, and also allows custom objects to define their printing behavior for any printer. The code generation functionality of SymPy relies on this subsystem to convert expressions into code in various target programming languages.
SymPy has equation solvers that can handle ordinary differential equations, recurrence relationships, Diophantine equations,
See
There are two functions for solving algebraic equations in SymPy:
solve(f, *symbols, **flags)
solveset(f, symbol, domain=S.Complexes)
The
An important difference between the two functions is that the output API of
Both functions implicitly assume that expressions are equal to 0. For instance,
Some examples for
Besides being an important feature in its own right, computations on matrices with symbolic entries are important for many algorithms within SymPy. The following code shows some basic usage of the
>>> A = Matrix([[x, x + y], [y, x]])
>>> A
Matrix([
[x, x + y],
[y, x]])
SymPy matrices support common symbolic linear algebra manipulations, including matrix addition, multiplication, exponentiation, computing determinants, solving linear systems, singular values, and computing inverses using LU decomposition, LDL decomposition, GaussJordan elimination, Cholesky decomposition, Moore–Penrose pseudoinverse, or adjugate matrices.
All operations are performed symbolically. For instance, eigenvalues are computed by generating the characteristic polynomial using the Berkowitz algorithm and then finding its zeros using polynomial routines.
>>> A.eigenvals()
{x  sqrt(y*(x + y)): 1, x + sqrt(y*(x + y)): 1}
Internally these matrices store the elements as Lists of Lists (LIL) (
Similar to the polynomials submodule, dense here means that all entries are stored in memory, contrasted with a sparse representation where only nonzero entries are stored.
For storing sparse matrices, theSymPy also supports matrices with symbolic dimension values.
Block matrices are also implemented in SymPy.
When symbolic matrices are combined with the assumptions submodule for logical inference, they provide powerful reasoning over invertibility, semidefiniteness, orthogonality, etc., which are valuable in the construction of numerical linear algebra systems (
More examples for
While SymPy primarily focuses on symbolics, it is impossible to have a complete symbolic system without the ability to numerically evaluate expressions. Many operations directly use numerical evaluation, such as plotting a function, or solving an equation numerically. Beyond this, certain purely symbolic operations require numerical evaluation to effectively compute. For instance, determining the truth value of
Floatingpoint numbers in SymPy are implemented by the
Because Python
>>> Float(1.1)
1.10000000000000
>>> Float(1.1, 30) # precision equivalent to 30 digits
1.10000000000000008881784197001
>>> Float("1.1", 30)
1.10000000000000000000000000000
The
>>> (pi + 1).evalf(25)
4.141592653589793238462643
>>> cos(exp(100)).evalf(25)  1
0
Applying the
>>> (cos(exp(100))  1).evalf(25)
6.919482633683687653243407e88
The
The implementation of arbitraryprecision floatingpoint arithmetic is supplied by the mpmath library (
>>> import mpmath
>>> mpmath.mp.dps = 30 # 30 digits of precision
>>> mpmath.mpf("0.1") + mpmath.exp(50)
mpf('0.100000000000000000000192874984794')
>>> print(_) # prettyprinted
0.100000000000000000000192874985
Like SymPy, mpmath is a pure Python library. A design decision of SymPy is to keep it and its required dependencies pure Python. This is a primary advantage of mpmath over other multiple precision libraries such as GNU MPFR (
Internally, mpmath represents a floatingpoint number (−1)^{s}
Most mpmath and SymPy functions use the same naming scheme, although this is not true in every case. For example, the symbolic SymPy summation expression
The mpmath library supports special functions, rootfinding, linear algebra, polynomial approximation, and numerical computation of limits, derivatives, integrals, infinite series, and solving ODEs. All features work in arbitrary precision and use algorithms that allow computing hundreds of digits rapidly (except in degenerate cases).
The double exponential (tanhsinh) quadrature is used for numerical integration by default. For smooth integrands, this algorithm usually converges extremely rapidly, even when the integration interval is infinite or singularities are present at the endpoints (
A wide array of higher mathematical functions is implemented with full support for complex values of all parameters and arguments, including complete and incomplete gamma functions, Bessel functions, orthogonal polynomials, elliptic functions and integrals, zeta and polylogarithm functions, the generalized hypergeometric function, and the Meijer Gfunction. The Meijer Gfunction instance
>>> mpmath.mp.dps = 15
>>> mpmath.meijerg([[],[0]], [[0.5,1,1.5],[]], 10000)
mpf('2.4392576907199564e94')
Equivalently, with SymPy’s interface this function can be evaluated as:
>>> meijerg([[],[0]], [[S(1)/2,1,S(3)/2],[]], 10000).evalf()
2.43925769071996e94
Symbolic integration and summation often produce hypergeometric and Meijer Gfunction closed forms (see Section ‘Calculus’); numerical evaluation of such special functions is a useful complement to direct numerical integration and summation.
SymPy includes several submodules that allow users to solve domain specific physics problems. For example, a comprehensive physics submodule is included that is useful for solving problems in mechanics, optics, and quantum mechanics along with support for manipulating physical quantities with units.
One of the core domains that SymPy suports is the physics of classical mechanics. This is in turn separated into two distinct components: vector algebra and mechanics.
The
The following Python code demonstrates how a vector is created using the orthogonal unit vectors of three reference frames that are oriented with respect to each other, and the result of expressing the vector in the
>>> from sympy.physics.vector import ReferenceFrame
>>> A, B, C = symbols('A B C', cls=ReferenceFrame)
>>> B.orient(A, 'body', (pi, pi/3, pi/4), 'zxz')
>>> C.orient(B, 'axis', (pi/2, B.x))
>>> v = 1*A.x + 2*B.z + 3*C.y
>>> v
A.x + 2*B.z + 3*C.y
>>> v.express(A)
A.x + 5*sqrt(3)/2*A.y + 5/2*A.z
The
The
Symbolic quantum operators and states may be defined, and one can perform a full range of operations with them.
>>> from sympy.physics.quantum import Commutator, Dagger, Operator
>>> from sympy.physics.quantum import Ket, qapply
>>> A, B, C, D = symbols('A B C D', cls=Operator)
>>> a = Ket('a')
>>> comm = Commutator(A, B)
>>> comm
[A,B]
>>> qapply(Dagger(comm*a)).doit()
<a*(Dagger(A)*Dagger(B)  Dagger(B)*Dagger(A))
Commutators can be expanded using common commutator identities:
>>> Commutator(C+B, A*D).expand(commutator=True)
[A,B]*D  [A,C]*D + A*[B,D] + A*[C,D]
On top of this set of base objects, a number of specific quantum systems have been implemented in a fully symbolic framework. These include:
Many of the exactly solvable quantum systems, including simple harmonic oscillator states and raising/lowering operators, infinite square well states, and 3D position and momentum operators and states.
Second quantized formalism of nonrelativistic manybody quantum mechanics (
Quantum angular momentum (
Quantum information and computing (
Here are a few short examples of the quantum information and computing capabilities in
>>> from sympy.physics.quantum.qubit import Qubit
>>> from sympy.physics.quantum.gate import XGate
>>> q = Qubit('0101')
>>> q
0101>
>>> X = XGate(1)
>>> qapply(X*q)
0111>
Qubit states can also be used in adjoint operations, tensor products, inner/outer products:
>>> Dagger(q)
<0101
>>> ip = Dagger(q)*q
>>> ip
<01010101>
>>> ip.doit()
1
Quantum gates (unitary operators) can be applied to transform these states and then classical measurements can be performed on the results:
>>> from sympy.physics.quantum.qubit import measure_all
>>> from sympy.physics.quantum.gate import H, X, Y, Z
>>> c = H(0)*H(1)*Qubit('00')
>>> c
H(0)*H(1)*00>
>>> q = qapply(c)
>>> measure_all(q)
[(00>, 1/4), (01>, 1/4), (10>, 1/4), (11>, 1/4)]
Lastly, the following example demonstrates creating a threequbit quantum Fourier transform, decomposing it into one and twoqubit gates, and then generating a circuit plot for the sequence of gates (see
>>> from sympy.physics.quantum.qft import QFT
>>> from sympy.physics.quantum.circuitplot import circuit_plot
>>> fourier = QFT(0,3).decompose()
>>> fourier
SWAP(0,2)*H(0)*C((0),S(1))*H(1)*C((0),T(2))*C((1),S(2))*H(2)
>>> c = circuit_plot(fourier, nqubits=3)
Software architecture is of central importance in any large software project because it establishes predictable patterns of usage and development (
A computer algebra system stores mathematical expressions as data structures. For example, the mathematical expression
In SymPy every symbolic expression is an instance of the class
Some internal classes, such as those used in the polynomial submodule, do not follow this rule for efficiency reasons.
the superclass of all SymPy types providing common methods to all SymPy treeelements, such as traversals. The children of a node in the tree are held in theFor example, consider the expression
>>> x, y = symbols('x y')
>>> expr = x*y + 2
By order of operations, the parent of the expression tree for
>>> type(expr)
<class 'sympy.core.add.Add'>
>>> expr.args
(2, x*y)
Descending further down into the expression tree yields the full expression. For example, the next child node (given by
>>> expr.args[0]
2
>>> type(expr.args[0])
<class 'sympy.core.numbers.Integer'>
>>> expr.args[0].args
()
Symbols or symbolic constants, like
>>> exp(1)
E
>>> exp(1).args
()
>>> x.args
()
A useful way to view an expression tree is using the
The
>>> srepr(expr)
"Add(Mul(Symbol('x'), Symbol('y')), Integer(2))"
Every SymPy expression satisfies a key identity invariant:
expr.func(*expr.args) == expr
This means that expressions are rebuildable from their
>>> (x + 1)**2 == x**2 + 2*x + 1
False
because they are different as expression trees (the former is a
Another important property of SymPy expressions is that they are immutable. This simplifies the design of SymPy, and enables expression interning. It also enables expressions to be hashed, which allows expressions to be used as keys in Python dictionaries, and is used to implement caching in SymPy.
Python allows classes to override mathematical operators. The Python interpreter translates the above
While the core of SymPy is relatively small, it has been extended to a wide variety of domains by a broad range of contributors. This is due, in part, to the fact that the same language, Python, is used both for the internal implementation and the external usage by users. All of the extensibility capabilities available to users are also utilized by SymPy itself. This eases the transition pathway from SymPy user to SymPy developer.
The typical way to create a custom SymPy object is to subclass an existing SymPy class, usually
See
The
Many SymPy functions perform various evaluations down the expression tree. Classes define their behavior in such functions by defining a relevant
Listing 1 presents an example of this extensibility. It gives a stripped down version of the
Listing 1: A minimal implementation of sympy.gamma.
from sympy import Function, Integer, factorial, polygamma
class gamma(Function):
@classmethod
def eval(cls, arg):
if isinstance(arg, Integer) and arg.is_positive:
return factorial(arg  1)
def _eval_is_real(self):
x = self.args[0]
# noninteger means real and not integer
if x.is_positive or x.is_noninteger:
return True
def _eval_rewrite_as_factorial(self, z):
return factorial(z  1)
def fdiff(self, argindex=1):
from sympy.core.function import ArgumentIndexError
if argindex == 1:
return self.func(self.args[0])*polygamma(0, self.args[0])
else:
raise ArgumentIndexError(self, argindex)
The gamma function implemented in SymPy has many more capabilities than the above listing, such as evaluation at rational points and series expansion.
Due to being written in pure Python without the use of extension modules, SymPy’s performance characteristics are generally poorer than that of its commercial competitors. For many applications, the performance of SymPy, as measured by clock cycles, memory usage, and memory layout, is sufficient. However, the boundaries for when SymPy’s pure Python strategy becomes insufficient are when the user requires handling of very long expressions or many small expressions. Where this boundray lies depends on the system at hand, but tends to be within the range of 10^{4}–10^{6} symbols for modern computers.
For this reason, a new project called SymEngine (
The development version of SymPy has recently started to use SymEngine as an optional backend, initially in
There are several projects that depend on SymPy as a library for implementing a part of their functionality. A selection of these projects are listed in
Project name  Description 

An open source analog of Wolfram  Alpha that uses SymPy ( 

A CAS designed specifically for the resolution of problems encountered in field theory ( 

An implementation of a symbolic toolbox for Octave using SymPy ( 

A Julia interface to SymPy, provided using PyCall ( 

A free, online CAS featuring Mathematica compatible syntax and functions ( 

An iOS App that detects handwritten math as input and uses SymPy Gamma to evaluate the math input and generate the relevant steps to solve the problem ( 

A robot kinematics compiler provided by 

A free opensource mathematics software system, which builds on top of many existing opensource packages, including SymPy ( 

Multibody Dynamics with Python ( 

A Python package for geometric algebra (previously 

A Python package for analyzing and visualizing volumetric data ( 

A Python package for solving partial differential equations (PDEs) in 1D, 2D, and 3D by the finite element (FE) method ( 

Quantum Monte Carlo in Python ( 

An experimental Python package for teaching linear circuit analysis ( 
SymPy is a robust computer algebra system that provides a wide spectrum of features both in traditional computer algebra and in a plethora of scientific disciplines. It can be used in a firstclass way with other Python projects, including the scientific Python stack.
SymPy supports a wide array of mathematical facilities. These include functions for assuming and deducing common mathematical facts, simplifying expressions, performing common calculus operations, manipulating polynomials, pretty printing expressions, solving equations, and representing symbolic matrices. Other supported facilities include discrete math, concrete math, plotting, geometry, statistics, sets, series, vectors, combinatorics, group theory, code generation, tensors, Lie algebras, cryptography, and special functions. SymPy has strong support for arbitrary precision numerics, backed by the mpmath package. Additionally, SymPy contains submodules targeting certain specific physics domains, such as classical mechanics and quantum mechanics. This breadth of domains has been engendered by a strong and vibrant user community. Anecdotally, many of these users chose SymPy because of its ease of access. SymPy is a dependency of many external projects across a wide spectrum of domains.
SymPy expressions are immutable trees of Python objects. Unlike many other CAS’s, SymPy is designed to be used in an extensible way: both as an enduser application and as a library. SymPy uses Python both as the internal language and the user language. This permits users to access the same methods used by the library itself in order to extend it for their needs.
Some of the planned future work for SymPy includes work on improving code generation, improvements to the speed of SymPy using SymEngine, improving the assumptions system, and improving the solvers submodule.
Christopher P. Smith is an employee of Polar Semiconductor, Inc., Bloomington, Minnesota, United States; Mateusz Paprocki and Matthew Rocklin are employees of Continuum Analytics, Inc., Austin, Texas, United States; Andy R. Terrel is an employee of Fashion Metric, Inc, Austin, Texas, United States.
The following information was supplied regarding data availability:
The source for the paper is at