SymPy is a Python library for performing symbolic calculations. It is a computer algebra system that can act as a standalone application as well as a library for other applications. You can work with it online at https://live.sympy.org/. Because it is a pure Python library, it can even be used interactively. SymPy has various functions that apply to symbolic computation, mathematical analysis, algebra, discrete mathematics, quantum physics, and so on. SymPy can present the result in different formats: LaTeX, MathML and so on. The library is distributed under the New BSD license. The first to release this library developers Ondřej Čertík and Aaron Meurer in 2007. The current version of the library is 1.6.2. This is where SymPy is used:
- Polynomials
- Mathematical Analysis
- Discrete Mathematics
- Matrices
- Geometry
- Graphing
- Physics
- Statistics
- Combinatorics
Table of Contents
Installing SymPy
SymPy requires an important library called mpmath
. It is used for real and complex arithmetic with floating point numbers of arbitrary precision. However, pip will install it automatically when you load SymPy itself:
pip install sympy
Distributions such as Anaconda, Enthough, Canopy, and others include SymPy in advance. To make sure this is the case, just enter the command interactively:
>>> import sympy
>>> sympy.__version__
'1.6.2'
The source code can be found on GitHub.
Symbolic computing in SymPy
Symbolic computing is the development of algorithms to control mathematical expressions and other objects. Such computing combines mathematics and computer science to solve mathematical expressions using mathematical symbols. A computer algebra system, on the other hand, such as SymPy evaluates algebraic expressions using the same symbols used in traditional manual methods. For example, the square root of a number using the math module in Python is calculated like this:
import math
print(math.sqrt(25), math.sqrt(7))
The output is as follows:
5.0 2.6457513110645907
As you can see, the square root of number 7 can be calculated approximately. But in SymPy the square roots of numbers which are not perfect squares are simply not computed:
import sympy
print(sympy.sqrt(7))
This is the output of this code: sqrt(7)
. This can be simplified and show the result of the expression symbolically like this:
>>> import math
>>> print(math.sqrt(12))
3.4641016151377544
>>> import sympy
>>> print(sympy.sqrt(12))
2*sqrt(3)
In the case of math module, it will return a number, but in SymPy, it will return a formula. To render mathematical symbols in LaTeX code SymPy, use Jupyter notebook:
from sympy import *
x = Symbol('x')
expr = integrate(x**x, x)
expr
If you run this command in IDLE, you get the following result:
Integral(x**x,x)
And in Jupyter: The square root of a non-ideal root can also be represented in LaTeX format using familiar symbols:
Symbolic calculations with systems such as SymPy help you perform calculations of all kinds (derivatives, integrals, limits, solving equations, working with matrices) in symbolic form. The SymPy package has various modules that help you build graphs, output results (LaTeX), deal with physics, statistics, combinatorics, numerical theory, geometry, logic, and so on.
Numbers
The main module in SymPy includes a Number
class representing atomic numbers. It has a couple of subclasses: Float
and Rational
. Rational
also includes Integer
.
The Float class
Float
represents floating point numbers of arbitrary precision:
>>> from sympy import Float
>>> Float(6.32)
6.32
SymPy can convert an integer or a string to a floating-point number:
>>> Float(10)
10.0
When converting to a floating-point number, you can also specify the number of digits for precision:
>>> Float('1.33E5')
133000.0
You can represent a number as a fraction using an object of the Rational
class, where the denominator is not 0: If you pass a floating-point number to the
Rational()
constructor, it will return a fraction: You can specify a denominator constraint for simplicity:
Rational(0.2).limit_denominator(100)
The fraction 1/5 instead of 3602879701896397/18014398509481984 will come out. If you pass a string to the constructor, a rational number of any precision will be returned: You can also get a rational number by passing two numbers as arguments. The numerator and denominator are available as properties:
>>> a=Rational(3, 5)
>>> print(a)
3/5
>>> print("numerator:{}, denominator:{}".format(a.p, a.q))
numerator:3, denominator:5
The Integer class
The Integer
class in SymPy represents an integer of any size. The constructor accepts rational and floating point numbers. As a result, it discards the fractional part:
>>> Integer(10)
10
>>> Integer(3.4)
3
>>> Integer(2/7)
There is also a RealNumber
class, which is an alias for Float
. SymPy has Zero
and One
single classes, accessible through S.Zero
and S.One
, respectively.
>>> S.Zero
>>> S.One
1
Other single-number objects are Half
, NaN
, Infinity
, and ImaginaryUnit
.
>>> from sympy import S
>>> print(S.Half)
1/2
>>> print(S.NaN)
nan
Infinity is represented as an object-symbol oo
or as S.Infinity
:
ImaginaryUnit
can be imported as an I
symbol and accessed through S.ImaginaryUnit
.
Symbols
Symbol is the most important class in the SymPy library. As mentioned before, symbol calculations are done with symbols. And SymPy variables are objects of the Symbol
class. The Symbol()
argument is a string that contains a symbol that can be assigned to a variable.
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> y = Symbol('y')
>>> expr = x**2 + y**2
>>> expr
The code above is the equivalent of this expression: The symbol may include more than one letter:
from sympy import Symbol
s = Symbol('side')
s**3
SymPy also has a Symbols()
function that can be used to define more than one symbol at a time. The string contains variable names separated by commas or spaces.
from sympy import symbols
x, y, z = symbols('x, y, z')
In the module abc, you can find elements of the Latin and Greek alphabets as symbols. Thus, instead of creating an instance of Symbol
, you can use a method:
from sympy.abc import x, z
C, O, S, I, N, E and Q, however, are predefined symbols. Also symbols with more than one letter are not defined in abc. You have to use the Symbol
object for them. The module abs defines special names that can detect definitions in the default SymPy namespace. clash1
contains single-letter characters, and clash2
contains whole words.
>>> from sympy.abc import _clash1, _clash2
>>> _clash1
{'C': C,'O': O,'Q': Q,'N': N,'I': I,'E': E,'S': S}
>>> _clash2
{'beta': beta,'zeta': zeta,'gamma': gamma,'pi': pi}
Indexed characters (a sequence of words with digits) can be defined using syntax similar to range()
. Ranges are denoted by a colon. The type of range is determined by the character to the right of the colon. If it is a digit, all adjacent digits to the left are treated as non-negative starting values. The adjacent digits on the right are taken to be 1 greater than the final value.
>>> from sympy import symbols
>>> symbols('a:5')
(a0,a1,a2,a3,a4)
>>> symbols('mark(1:4)')
(mark1,mark2,mark3)
Substitution of parameters
One of the basic operations in mathematical expressions is substitution. The subs()
function replaces all instances of the first parameter with the second.
>>> from sympy.abc import x, a
>>> expr = sin(x) * sin(x) + cos(x) * cos(x)
>>> expr
This code will give the output equivalent to such an expression. And with the code
expr.subs(x,a)
we will get the same formula, but with a
instead of x
. This function is useful when we need to calculate a certain expression. For example, we need to calculate the values of an expression by replacing a
with 5
:
>>> from sympy.abc import x
>>> from sympy import sin, pi
>>> expr = sin(x)
>>> expr1 = expr.subs(x, pi)
>>> expr1
The function is also used to replace a subexpression with another subexpression. In the following example, b
is replaced by a+b
.
>>> from sympy.abc import a, b
>>> expr = (a + b)**2
>>> expr1 = expr.subs(b, a + b)
>>> expr1
This gives this output:
The simplify() function
The simplify()
function is used to convert any arbitrary expression so that it can be used as a SymPy expression. Ordinary Python objects, such as integers, are converted to SymPy.Integer
and so on. Strings are also converted into SymPy expressions:
>>> expr = "x**2 + 3*x + 2"
>>> expr1 = sympify(expr)
>>> expr1.subs(x, 2)
12
Any Python object can be converted to a SymPy object. However, given that the conversion uses the eval()
function, you should not use incorrect expressions or you will get a SimplifyError
.
>>> sympify("x***2")
...
SympifyError: Sympify of expression 'could not parse 'x***2'' failed, because of exception being raised:
SyntaxError: invalid syntax (, line 1)
The simplify()
function takes the following argument: strict=False
. If you set it to True
, only those types will be converted for which an explicit conversion is defined. Otherwise the SimplifyError
will occur. If set to False
, the arithmetic expressions and operators will be converted to their SumPy equivalents without evaluating the expression.
The function evalf()
The function evaluates the given numeric expression to 100 digits after the floating point. It also takes the subs
parameter as a dictionary object with numeric values for symbols. For example this expression:
from sympy.abc import r
expr = pi * r**2
expr
Will give this result: ??2
Calculate the expression using evalf()
and replace r with 5:
>>> expr.evalf(subs={r: 5})
78.5398163397448
The default precision after the floating point is 15, but this value can be overwritten to 100. The following expression calculates using up to 20 digits of precision:
>>> expr = a / b
>>> expr.evalf(20, subs={a: 100, b: 3})
33.333333333333333333
The lambdify() function
The lambdify()
function translates SymPy expressions into Python functions. If the expression to be calculated affects a range of values, evalf()
becomes ineffective. The lambdify
function acts like a lambda function with the exception that it converts SymPy to the names of a given number library, usually NumPy. By default, however, it is implemented based on the standard math library.
>>> expr =1 / sin(x)
>>> f = lambdify(x, expr)
>>> f(3.14)
627.8831939138764
An expression can have more than one variable. In that case, the first argument of the function is the list of variables, and after that, the expression itself:
>>> expr = a**2 + b**2
>>> f = lambdify([a, b], expr)
>>> f(2, 3)
13
But to use numpy as the main library, it must be passed as an argument to lambdify()
.
f = lambdify([a, b], expr, "numpy")
This function used two numpy arrays: a
and b
. In the case of them, the execution is much faster:
>>> import numpy
>>> l1 = numpy.arange(1, 6)
>>> l2 = numpy.arange(6, 11)
>>> f(l1, l2)
array([ 37, 53, 73, 97, 125], dtype=int32)
Logical expressions
Boolean functions are located in the module sympy.basic.booleanarg
. You can also create them using standard Python operators: &
(And), |
(Or), ~
(Not), and >>
and <<
. Boolean expressions are inherited from the Basic
class. BooleanTrue. This function is the equivalent of True
from Python. It returns a single object, which can also be accessed with S.true
.
>>> from sympy import *
>>> x = sympify(true)
>>> x, S.true
(True, True)
BooleanFalse. And this function is the equivalent of False
. You can get it with S.False
.
>>> from sympy import *
>>> x = sympify(false)
>>> x, S.false
(False,False)
And. The boolean AND function evaluates two arguments and returns False
if at least one of them is False
. This function replaces the &
operator .
>>> from sympy import *
>>> from sympy.logic.boolalg import And
>>> x, y = symbols('x y')
>>> x = True
>>> y = True
>>> And(x, y), x & y
Or. Evaluates two expressions and returns True
if at least one of them is True
. The same behavior can be obtained using the |
operator.
>>> from sympy import *
>>> from sympy.logic.boolalg import Or
>>> x, y = symbols('x y')
>>> x = True
>>> y = False
>>> Or(x, x|y)
Not. The result of this function is the negation of a Boolean argument. True if the argument is False
, and False
otherwise. In Python, the ~
operator is responsible for this. Example:
>>> from sympy import *
>>> from sympy.logic.boolalg import Or,And,Not
>>> x, y = symbols('x y')
>>> x = True
>>> y = False
>>> Not(x), Not(y)
(False, True)
Xor. A logical XOR (exclusive OR) will return True if an odd number of arguments are True
and the rest are False
. False, on the other hand, will be returned if an even number of arguments are True
and the rest are False
. The same behavior works for the ^
operator.
>>> from sympy import *
>>> from sympy.logic.boolalg import Xor
>>> x, y = symbols('x y')
>>> x = True
>>> y = False
>>> Xor(x, y)
True
In the previous example one (odd number) argument is True
, so Xor
will return True
. If the number of true arguments is even, the result will be False
, as shown next.
>>> Xor(x, x^y)
False
Nand. Performs the NAND boolean operation. Evaluates the arguments and returns True
if at least one of them is False
, and False
if they are true.
>>> from sympy.logic.boolalg import Nand
>>> a, b, c = (True, False, True)
>>> Nand(a, c), Nand(a, b)
(False, True)
Nor. Executes the NOR logical operation. Evaluates the arguments and returns False
if one of them is True
, or True
if all of them are False
.
>>> from sympy.logic.boolalg import Nor
>>> a, b = False, True
>>> Nor(a), Nor(a, b)
(True, False)
Although SymPy offers the operators ^
for Xor
, ~
for Not
, |
for Or
, and &
for And
for convenience, in Python they are used as bitwise operators. So if the operands are integers, the results will be different. Equivalent. This function returns an equivalence relation. Equivalent(A, B)
will be True if and only if A and B are both True
or False
. The function will return True
if all arguments are logically equivalent. Otherwise it will return False
.
>>> from sympy.logic.boolalg import Equivalent
>>> a, b = True, False
>>> Equivalent(a, b), Equivalent(a, True)
(>> False, True)
Queries
SymPy’s Queries
module includes tools for getting information about expressions. The ask()
function is used for this. The following properties provide useful information about an expression:
>> expression
algebraic(x) To be algebraic, the number must be the root of a nonzero polynomial equation with rational coefficients. √2, because √2 is the solution of x2 – 2 = 0. Hence, this expression is algebraic. complex(x) The predicate of a complex number. It is true if and only if x belongs to the set of complex numbers. composite(x) A predicate of a composite number returned by ask(Q.composite(x))
is true if and only if x is a positive number with at least one positive divisor other than 1 and the number itself. even, odd ask()
returns True
if x is in the set of even and odd numbers, respectively. imaginary Represents the predicate of an imaginary number. It is true if x can be written as a real number multiplied by an imaginary one. integer This property, returned by Q.integer(x)
, will only be true if x belongs to the set of even numbers. rational, irrational Q.irrational(x)
is true if and only if x is any real number that cannot be represented as a ratio of integers. For example, pi is an irrational number. positive, negative Predicates to test whether a number is positive or negative. zero, nonzero Predicate to check if a number is zero or nonzero.
>>> from sympy import *
>>> x = Symbol('x')
>>> x = 10
>>> ask(Q.algebraic(pi))
False
>>> ask(Q.complex(5-4*I)), ask(Q.complex(100))
(True, True)
>>> x, y = symbols("x y")
>>> x, y = 5, 10
>>> ask(Q.composite(x)), ask(Q.composite(y))
(False, True)
>>> ask(Q.even(x)), ask(Q.even(y))
(True, None)
>>> ask(Q.imaginary(x)), ask(Q.imaginary(y))
(True, False)
>>> ask(Q.even(x)), ask(Q.even(y)), ask(Q.odd(x)), ask(Q.odd(y))
(True, True, False, False)
>>> ask(Q.positive(x)), ask(Q.negative(y)), ask(Q.positive(x)), ask(Q.negative(y))
(True, True)
>>> ask(Q.rational(pi)), ask(Q.irrational(S(2)/3))
(False, False)
>>> ask(Q.zero(oo)), ask(Q.nonzero(I))
(False, False)
Simplifying functions
SymPy can simplify mathematical expressions. There are many functions for this. The main one is called simplify()
, and its main purpose is to make expressions as simple as possible.
simplify
This function is declared in the sympy.simplify
module. It tries to apply intelligent heuristics to make the input expression “simpler”. The following code simplifies such an expression: sin^2(x)+cos^2(x)
>>> x = Symbol('x')
>>> expr = sin(x)**2 + cos(x)**2
>>> simplify(expr)
1
expand
One of the most common simplification functions in SymPy. It is used to decompose polynomial expressions. For example:
>>> a, b = symbols('a b')
>>> expand((a+b)**2)
And here the output is as follows: ?2+2??+?2.
>>> expand((a+b)*(a-b))
The conclusion is: ?2-?2. The expand()
function makes the expression larger, not smaller. This is usually how it works, but it often happens that the expression gets smaller after the function is used:
>>> expand((x + 1)*(x - 2) - (x - 1)*x)
-2
factor
This function takes a polynomial and decomposes it into irreducible multipliers by rational numbers.
>>> x, y, z = symbols('x y z')
>>> expr = (x**2*z + 4*x*y*z + 4*y**2*z)
>>> factor(expr)
Conclusion: ?(?+2?)2. The factor()
function is the opposite of expand()
. Each divisor returned by factor()
will be irreducible. The factor_list()
function provides a more structured output:
>>> expr=(x**2*z + 4*x*y*z + 4*y**2*z)
>>> factor_list(expr)
(1, [(z, 1), (x + 2*y, 2)])
collect
This function collects additional terms of an expression with respect to the list of expressions, up to powers with rational exponents.
>>> expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
>>> expr
Conclusion: ?3-?2?+2?2+??+?-3. The result of collect()
:
>>> expr = y**2*x + 4*x*y*z + 4*y**2*z + y**3 + 2*x*y
>>> collect(expr, y)
Output: ?3+?2(?+4?)+?(4??+2?).
cancel
This function takes any rational function and casts it to the canonical form p/q, where p and q are expanded polynomials without common multipliers. The higher coefficients of p and q have no denominators, i.e., they are integers.
>>> expr1=x**2+2*x+1
>>> expr2=x+1
>>> cancel(expr1/expr2)
x + 1
Some more examples:
trigsimp
This function is used to simplify trigonometric identities. It is worth noting that the traditional names of inverse trigonometric functions are added to the function name at the beginning. For example, the inverse cosine or arc cosine is called acos()
:
>>> from sympy import trigsimp, sin, cos
>>> from sympy.abc import x, y
>>> expr = 2*sin(x)**2 + 2*cos(x)**2
>>> trigsimp(expr)
2
The trigsimp
function uses heuristics to apply the most appropriate trigonometric identity.
powersimp
This function reduces expressions by combining degrees with similar bases and degree values.
>>> expr = x**y*x**z*y**z
>>> expr
Conclusion: ??????. You can make powsimp()
combine only bases or degrees by specifying combine='base'
or combine='exp'
. The default is combine='all'
. You can also specify the force
parameter. If it is True
, the bases will be combined without checks.
>>> powsimp(expr, combine='base', force=True)
Conclusion: ??(??)?
combsimp
Combinatorial expressions involving factorials and binomials can be simplified with combsimp()
. SymPy has a factorial()
function. To simplify the previous combinatorial expression, this function is used as follows.
>>> combsimp(expr)
?(?-2)(?-1)
thebinomial(x, y)
is the number of ways in which you can choose elements of y from the set of elements of x. It can also be written as xCy.
logcombine
This function takes logarithms and combines them using the following rules:
log(x) + log(y) == log(x*y)
– both positive.a*log(x) == log(x**a)
if x is positive and real.
>>> logcombine(a*log(x) + log(y) - log(z))
?log(?)+log(?)-log(?)
If the force
parameter is set to True
here, the above assumptions are considered to be met if there are no assumptions about the value.
Derivatives
The derivative of a function is its rate of change with respect to one of the variables. It is equivalent to finding the slope of a tangent to a function at a point. You can find the differentiation of mathematical expressions in the form of variables by using the diff()
function from SymPy.
>>> from sympy import diff, sin, exp
>>> from sympy.abc import x, y
>>> expr = x*sin(x*x) + 1
>>> expr
The output is ?sin(?2)+1. To get multiple derivations, you need to pass the variable as many times as you want to differentiate. Alternatively, you can simply specify this number with a number.
>>> diff(x**4, x, 3)
24?
You can also call the diff()
method of an expression. It works similarly to a function.
>>> expr = x*sin(x*x) + 1
>>> expr.diff(x)
The output is: 2?2cos(?2)+sin(?2). The unvalued derivative is created using the Derivative
class. It has the same syntax as the diff()
function. To evaluate it, it is sufficient to use the doit
method.
Integration
SymPy includes a module for integrals. It has methods for calculating definite and indefinite integrals of expressions. The integrate()
method is used to calculate both integrals. To calculate an indefinite or primitive integral, simply pass the variable after the expression. To calculate a definite integral, pass the arguments as follows: Example of a definite integral:
You can use the
Integral
object to create an unevaluated integral. It is evaluated using the doit()
method.
Transformations of Integrals
SymPy supports different kinds of transformations of integrals:
- laplace_transform.
- fourier_transform.
- sine_transform.
- cosine_transform.
- hankel_transform.
These functions are defined in the sympy.integrals.transforms
module. The following examples compute Fourier and Laplace transforms, respectively:
>>> from sympy.integrals import laplace_transform
>>> from sympy.abc import t, s, a
>>> laplace_transform(t**a, t, s)
(s**(-a)*gamma(a + 1)/s, 0, re(a) > -1)
Matrices
In mathematics, a matrix is a two-dimensional array of numbers, symbols, or expressions. The theory of matrix manipulation involves performing arithmetic operations on matrix objects while following certain rules. Linear transformation is one of the most important applications of the matrix. It is often used in various scientific fields, especially those related to physics. SymPy has a matrices
module that works with matrices. It has a Matrix
class to represent a matrix. Note: to execute the code in this section, you must first import the matrices module as follows.
>>> from sympy.matrices import Matrix
>>> m=Matrix([[1, 2, 3], [2, 3, 1]])
>>> m
⎡1 2 3⎤
⎣2 3 1⎦
A matrix is a modifiable object. There is also an ImmutableMatrix
class in the module to get an immutable matrix.
The basic interaction
The shape
property returns the size of the matrix.
>>> m.shape
(2, 2)
The row()
and col()
methods return the column or row of the corresponding number.
>>> m.row(0)
[1 2 3]
>>> m.col(1)
⎡2⎤
⎣3⎦
The slice
operator from Python can be used to get one or more elements of a row or column. The Matrix class also has row_del()
and col_del()
methods which remove the specified row/column from the selected matrix.
>>> m.row(1)[1:3]
[3, 1]
>>> m.col_del(1)
>>> m
⎡1 3⎤
⎣2 1⎦
Similarly, row_insert()
and col_insert()
add rows and columns to the designated indexes:
>>> m1 = Matrix([[10, 30]])
>>> m = m.row_insert(0, m1)
>>> m
⎡10 30⎤
⎢ 1 3 ⎥
⎣ 2 1 ⎦
Arithmetic operations
The familiar +, -, and * operators are used for addition, multiplication, and division.
>>> M1 = Matrix([[3, 0], [1, 6]])
>>> M2 = Matrix([[4, 5], [6, 4]])
>>> M1 + M2
⎡7 5 ⎤
⎣7 10 ⎦
Matrix multiplication is possible only if the number of columns of the first matrix corresponds to the number of columns of the second matrix. The result will have the same number of rows as the first matrix and the same number of columns as the second matrix. To calculate the determinant of a matrix, use the det()
method. The determinant is a scalar value that can be calculated from the elements of a square matrix.
>>> M = Matrix([[4, 5], [6, 4]])
>>> M.det()
-14
Matrix constructors
SymPy provides many special types of matrix classes. For example, Identity, a matrix of ones, zeros, and so on. These classes are called eyes
, zeroes
, and ones
, respectively. Identity is a square matrix whose elements on the diagonal are 1 and the rest are 0. In the
diagonal
matrix, the elements on the diagonal are initialized according to the arguments provided.
>>> from sympy.matrices import diag
>>> diag(1, 3)
⎡1 0 ⎤
⎣0 3 ⎦
All elements in matrix zero
are initialized as zeros.
>>> from sympy.matrices import zeros
>>> zeros(2, 3)
⎡0 0 0⎤
⎣0 0 0⎦
By analogy, in the matrix ones
the elements are equal to 1:
>>> from sympy.matrices import zeros
>>> ones(2, 3)
⎡1 1 1⎤
⎣1 1 1⎦
The Function class
The SymPy package has a Function
class defined in the sympy.core.function
module. It is a base class for all mathematical functions and a constructor for undefined classes. The following categories of functions are inherited from the Function
class:
- Functions for complex numbers
- Trigonometric functions
- Integer Functions
- Combinatorial Functions
- Other functions
Functions for complex numbers
A set of these functions is defined in the module sympy.functions.elementary.complexes
. re – This function returns the real part of an expression:
>>> from sympy import *
>>> re(5+3*I)
5
>>> re(I)
im – Returns the imaginary part of the expression:
>>> im(5+3*I)
3
>>> im(I)
1
sign – This function returns the complex sign of an expression… For a real expression the sign will be:
- 1 if the expression is positive,
- 0 if the expression is zero,
- -1 if the expression is negative.
If the expression is imaginary, the signs are as follows:
- l if the expression is positive,
- -l if the expression is negative.
>>> sign(1.55), sign(-1), sign(S.Zero)
(1,-1,0)
>>> sign(-3*I), sign(I*2)
(-I, I)
The function abs returns the absolute value of a complex number. It is defined as the distance between the base (0, 0) and a point on the complex plane. This function is an extension of the built-in abs()
function and accepts character values. For example, Abs(2+3*I)
, will return √13. conjugate – The function returns the conjugate of a complex number. It changes the sign of the imaginary part to find it.
>>> conjugate(4+7*I)
4-7?
Trigonometric Functions
SymPy has definitions for all trigonometric ratios: sine, cosine, tangent, and so on. There are also inverse analogues: asin, acos, atan, and so on. The functions calculate the corresponding value of a given angle in radians.
>>> sin(pi/2), cos(pi/4), tan(pi/6)
(1, sqrt(2)/2, sqrt(3)/3)
>>> asin(1), acos(sqrt(2)/2), atan(sqrt(3)/3)
(pi/2, pi/4, pi/6)
The integer functions
A set of functions for working with integers. A one-dimensional integer function that returns the smallest integer that is not smaller than the argument. In the case of complex numbers, rounding to the greater integer for the integer and imaginary parts is done separately.
>>> ceiling(pi), ceiling(Rational(20, 3)), ceiling(2.6+3.3*I)
(4, 7, 3 + 4*I)
floor – Returns the largest number that is not greater than the argument. In the case of complex numbers, rounding to a smaller integer for the integer and imaginary parts is done separately.
>>> floor(pi), floor(Rational(100, 6)), floor(6.3-5.9*I)
(3, 16, 6 - 6*I)
frac – The function represents the fraction of x.
>>> frac(3.99), frac(10)
(0.990000000000000, 0)
Combinatorial functions
Combinatorics is a branch of mathematics that deals with choice, arrangement, and operation in finite and discrete systems. factorial – Factorial is very important in combinatorics. It refers to the number of ways that objects can be represented.
Quaternion
In mathematics, the number system quaternion extends the complex numbers. Each object includes 4 scalar variables and 4 dimensions: one real and three imaginary. A quaternion can be represented as the following equation: q = a + bi + cj + dk, where a, b, c and d are real numbers and i, j and k are quartenial units, so that i2 == j2 == k2 = ijk. The Quaternion
class is located in the module sympy.algebras.quaternion
.
>>> from sympy.algebras.quaternion import Quaternion
>>> q = Quaternion(2, 3, 1, 4)
>>> q
2+3?+1?+4?
Quaternions are used in both pure and applied mathematics, as well as in computer graphics, computer vision, and so on.
add()
This method of the Quaternion
class allows you to add two objects of the class:
>>> q1=Quaternion(1,2,4)
>>> q2=Quaternion(4,1)
>>> q1.add(q2)
5+3?+4?+0?
It is also possible to add a number or symbol to a Quaternion
object.
>>> q1+2
3+2?+4?+0?
>>> q1+x
(?+1)+2?+4?+0?
mul()
This method performs the multiplication of two quaternions.
>>> q1 = Quaternion(1, 2)
>>> q2 = Quaternion(2, 4, 1)
>>> q1.mul(q2)
(-6)+8?+1?+2?
inverse()
Returns the inverse quaternion.
pow()
Returns the degree of the quaternion.
>>> q1.pow(2)
(-3)+4?+0?+0?
exp()
Calculates the exponent of the quaternion.
Equations
Because = and == are defined as assignment and equality symbols in Python, they cannot be used to create symbolic equations. SymPy has the Eq()
function for that.
>>> x, y = symbols('x y')
>>> Eq(x, y)
?=?
Since x=y
is only possible if x-y=0
, the equation above can be written as:
>>> Eq(x-y, 0)
x-y=0
The solver
module of SymPy offers the solveset()
function:
solveset(equation,variable,domain)
The default domain
parameter is S.Complexes
. With solveset()
you can solve an algebraic equation.
>>> solveset(Eq(x**2-9, 0), x)
{-3,3}
>>> solveset(Eq(x**2-3*x, -2), x)
{1,2}
Linear Equation
To solve linear equations, you must use the linsolve()
function. For example, the equations might be:
- x-y=4
- x+1=1
The
linsolve()
function can also solve linear equations in matrix form:
>>> a, b = symbols('a b')
>>> a = Matrix([[1, -1], [1, 1]])
>>> b = Matrix([4, 1])
>>> linsolve([a, b], y)
The output will be the same.
Nonlinear Equation
The nonlinsolve()
function is used for such equations. An example of such an equation:
>>> a, b = symbols('a b')
>>> nonlinsolve([a**2 + a, a - b], [a, b])
{(-1, -1),(0, 0)}
Differential Equation
To begin, create a function by passing cls=Function
to the symbols
function. Use dsolve
to solve differential equations.
>>> x = ymbol('x')
>>> f = symbols('f', cls=Function)
>>> f(x)
?(?)
Here f(x) is an uncalculated function. Its derivative is: First, an object
Eq
corresponding to the following differential equation is created.
Graphs
SymPy uses the matplotlib library as a backend for rendering 2D and 3D graphs of mathematical functions. Make sure that matplotlib is installed on your device. If not, install it using the following command.
pip install matplotlib
Functions for working with graphs can be found in the sympy.plotting
module:
plot
– two dimensional line graphs.plot3d
– three dimensional line graphs.plot_parametric
– two-dimensional parametric graphs.plot3d_parametric
– three dimensional parametric graphs.
The plot()
function returns an instance of the Plot
class. The plot itself can include one or more SymPy expressions. By default, matplotlib is used as the backend, but texplot, pyglet or the Google Charts API can be used along with it.
plot(expr,range,kwargs)
where expr
is any valid SymPy expression. Unless it says otherwise, the default value of range
is (-10, 10). The following graph shows the square for each value in the range -10 to 10.
>>> from sympy.plotting import plot
>>> from sympy import *
>>> x = Symbol('x')
>>> plot(x**2, line_color='red')
To draw multiple graphs for the same range, you must specify multiple expressions in front of the tuple.
>>> plot(sin(x), cos(x), (x, -pi, pi))
You can also specify a separate range for each expression.
plot((expr1,range1),(expr2,range2))
You can also use the following optional keyword arguments in plot()
.
line_color
– defines the color of the chart line.title
– title of the chart.xlabel
– label for the X axis.ylabel
– label for the y-axis.
>>> plot((sin(x), (x,-pi,pi)), line_color='red', title='Example SymPy plot')
The
plot3d()
function renders a three-dimensional graph.
>>> from sympy.plotting import plot3d
>>> x, y = symbols('x y')
>>> plot3d(x*y, (x, -10, 10), (y, -10, 10))
Similar to a 2D plot, a 3D plot can include multiple plots for individual ranges:
>>> plot3d(x*y, x/y, (x, -5, 5), (y, -5, 5))
The plot3d_parametric_line()
function renders a three-dimensional linear parametric graph:
>>> from sympy.plotting import plot3d_parametric_line
>>> plot3d_parametric_line(cos(x), sin(x), x, (x, -5, 5))
To draw a parametric volumetric graph, use
plot3d_parametric_surface()
.
Entities
The geometry
module in SymPy allows you to create two-dimensional entities such as line, circle and so on. You can get information about them through collinearity checking or intersection searching.
Point
The class point
represents a point in Euclidean space. The following examples check for collinearity of points:
>>> from sympy.geometry import Point
>>> from sympy import *
>>> x = Point(0, 0)
>>> y = Point(2, 2)
>>> z = Point(4, 4)
>>> Point.is_collinear(x, y, z)
True
>>> a = Point(2, 3)
>>> Point.is_collinear(x, a)
False
>>> x.distance(y)
2√2
The distance()
method of the Point
class calculates the distance between two points.
Line
The Line
entity can be derived from two Point
objects. The intersection()
method returns the intersection point of two lines.
>>> from sympy.geometry import Point, Line
>>> p1, p2 = Point(0, 5), Point(5, 0)
>>> l1 = Line(p1,p2)
>>> l2 = Line(Point(0, 0), Point(5, 5))
>>> l1.intersection(l2)
[Point2D(5/2, 5/2)]
>>> l1.intersection(Line(Point(0,0), Point(2,2))
[Point2D(5/2, 5/2)]
>>> x, y = symbols('x y')
>>> p = Point(x, y)
>>> p.distance(Point(0, 0))
Output: √?2+?2
Triangle
This function creates a Triangle
entity from three points.
Ellipse
An elliptical geometric entity is created with a Point
object that points to the center and the horizontal and vertical radii.
ellipse(center,hradius,vradius)
>>> from sympy.geometry import Ellipse, Line
>>> e = Ellipse(Point(0, 0), 8, 3)
>>> e.area
24?
- vradius can be obtained indirectly using the eccentricity parameter.
apoapsis
is the greatest distance between the focus and the contour.- the ellipse
equation
method returns the ellipse equation.
Sets
In mathematics, a set is a well-defined set of objects that can be numbers, letters of the alphabet, or even other sets. Set is also one of the built-in types in Python. SymPy, on the other hand, has a sets
module. Here you can find all kinds of sets and operations to find intersecting elements, unions, and so on. Aset
is a base class for any type of set in Python. But it’s worth noting that SymPy has a different one than Python does. The interval
class represents real intervals and the boundary property returns a FiniteSet
object.
>>> from sympy import Interval
>>> s = Interval(1, 10).boundary
>>> type(s)
sympy.sets.sets.FiniteSet
A FiniteSet
is a collection of discrete numbers. It can be obtained from any sequence, be it a list or a string.
>>> from sympy import FiniteSet
>>> FiniteSet(range(5))
{{0,1,...,4}}
>>> numbers = [1, 3, 5, 2, 8]
>>> FiniteSet(*numbers)
{1,2,3,5,8}
>>> s = "HelloWorld"
>>> FiniteSet(*s)
{?,?,?,?,?,?,?}
Similar to a built-in set, a Set from SymPy is also a collection of unique objects. A ConditionSet
is a set of elements that satisfy a given condition.
Union
is a composite set. It includes all elements from the two sets. If some are repeated, the resulting set will have only one copy.
>>> from sympy import Union
>>> l1 = [3, 7]
>>> l2 = [9, 7, 1]
>>> a = FiniteSet(*l1)
>>> b = FiniteSet(*l2)
>>> Union(a, b)
{1,3,7,9}
Intersection
, on the other hand, includes only those elements that are in both sets.
>>> from sympy import Intersection
>>> Intersection(a, b)
{7}
ProductSet
represents the Cartesian product of elements from both sets.
>>> from sympy import ProductSet
>>> l1 = [1, 2]
>>> l2 = [2, 3]
>>> a = FiniteSet(*l1)
>>> b = FiniteSet(*l2)
>>> set(ProductSet(a, b))
{(1, 2), (1, 3), (2, 2), (2, 3)}
Complement(a, b)
excludes those elements that are not in b
.
>>> from sympy import Complement
>>> l1 = [3, 1]
>>> a = FiniteSet(*l1)
>>> b = FiniteSet(*l2)
>>> Complement(a, b), Complement(b, a)
(FiniteSet(1), FiniteSet(2))
SymmetricDifference
stores only noncommon elements of both sets.
>>> from sympy import SymmetricDifference
>>> l1 = [3, 1]
>>> a = FiniteSet(*l1)
>>> b = FiniteSet(*l2)
>>> SymmetricDifference(a, b)
{1,2}
Output to console
SymPy has several tools for output. Here are some of them:
- str,
- srepr,
- ASCII pretty printer,
- Unicode pretty printer,
- LaTeX,
- MathML,
- Dot.
SymPy objects can also be sent as input to other programming languages such as C, Fortran, JavaScript, Theano. SymPy uses Unicode characters to render the output. If you use the Python console to work with SymPy, it is best to use init_session()
.
>>> from sympy import init_session
>>> init_session()
Python console for SymPy 1.6.2 (Python 3.8.5-64-bit) (ground types: python)
...
Let’s run these commands:
>>> from __future__ import division
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)
>>> init_printing()
>>> Integral(sqrt(1/x), x)
⌠
⎮ ___
⎮ ╱ 1
⎮ ╱ ─ dx
⎮ ╲╱ x
⌡
If there is no LaTeX, but matplotlib is present, the latter will be used as the rendering engine. If there is no matplotlib either, then the Unicode pretty printer is used. However, the Jupyter notebook uses MathJax to render LaTeX. A terminal that does not support Unicode uses the ASCII pretty printer (as in the output from the example). For the ASCII printer there is a function pprinter()
with the parameter use_unicode=False
.
>>> pprint(Integral(sqrt(1/x), x), use_unicode=False)
/
|
| ___
| / 1
| / - dx
| / x
|
/
You can also access the Unicode printer with pprint()
and pretty()
. If the terminal supports Unicode, it is used automatically. If support could not be detected, you can pass use_unicode=True
to force the use of Unicode. Use latex()
to get LaTeX format.
>>> print(latex(Integral(sqrt(1/x), x))
int sqrt{frac{1}{x}}, dx
The printer mathml is also available. There is a pint_mathml()
function for it.
>>> from sympy.printing.mathml import print_mathml
>>> print_mathml(Integral(sqrt(1/x),x))
x
x
-1
>>> mathml(Integral(sqrt(1/x),x))
xx-1