
When solving problems of mathematical modeling of processes and objects, it is often very practical to use algorithms in the Python language using symbolic calculations. Based on the SymPy library, Python successfully copes with solving equations and systems, integrating and differentiating, calculating limits, decomposing into series and summing series, simplifying expressions, and searching for solutions to differential equations and systems.
When using symbolic calculations, the user is given the opportunity to control the operation of the program during its execution by entering any valid functions with a specified number of variables.
As a teacher in Computer Science and Programming, in the module on programming in Python, I introduce students to the possibilities of this language for research. Your attention is a series of articles in which you can familiarize yourself with symbolic calculations in Python. I want to immediately warn that these articles do not claim to be unique, since they are collected on the basis of materials from various sources, their goal is to teach students the basics of symbolic calculations.
')
The very first step to symbol computing is to import the functions of the SymPy module using pip, the Python package management system. If you have coped with this, we will immediately proceed to the declaration of variables.
Note. To shorten the record in all the following examples, the first line is not given: from sympy import *Explicit declaration of character variables
For symbolic computations using the
SymPy module
, character variables and functions must be declared as such. In programs for mathematical calculations, such as Mathematica or Maple, variables are immediately treated as symbolic. In Python, you must force them to be declared symbolic, and this can be done in several ways. The easiest way is to use the
symbols () or
var () functions. The first function returns a reference to a character object in the form of a variable. The second, without assignment, creates a character variable.
Code example>>> x,y,a,b = symbols('xya b')
The main difference between the
symbols () and
var () functions is that the first function returns a reference to a character object. For further use, it must be assigned to a variable. The second, without assignment, creates a character variable.
In the functions symbols () and var (), you can declare character variables with an index:
You can also assign a type and impose restrictions on the character variables directly in the symbols () and var () functions. Sometimes, without such limitations, obvious transformations do not work, for example, compare:
Code example >>> x = symbols('x', integer=True)
To create a container for a single character, use the argument
seq = True: >>> symbols('x',seq=True) (x,)
Determination of real values for character variables:
>>> x, y, z = symbols('x,y,z', real=True) >>> x.is_real and y.is_real and z.is_real True
S () function
Sometimes symbolic expressions can be interpreted as Python numeric constants, not SymPy. Therefore, to declare character variables, as well as to convert numeric constants to character, use the function S (), for example, compare:
>>> expr = x**2 + sin(y) + S(10)/2; expr x**2 + sin(y) + 5 >>> type(10) <class 'int'> >>> type(S(10)) # <class 'sympy.core.numbers.Integer'>
The difference between the Python constant and the symbolic constant is that the symbolic constant can be calculated with a given degree of accuracy, as shown in the following example in comparison with the standard
round () function:
z=1/7; z
Character Names
If it is necessary to use symbolic mathematics all the time in the current session, then you can import common symbolic names from the
sympy.abc module:
Code example >>> import sympy.abc >>> dir(sympy.abc) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_clash', '_clash1', '_clash2', 'a', 'alpha', 'b', 'beta', 'c', 'chi', 'd', 'delta', 'division', 'e', 'epsilon', 'eta', 'exec_', 'f', 'g', 'gamma', 'greeks', 'h', 'i', 'iota', 'j', 'k', 'kappa', 'l', 'lamda', 'm', 'mu', 'n', 'nu', 'o', 'omega', 'omicron', 'p', 'phi', 'pi', 'print_function', 'psi', 'q', 'r', 'rho', 's', 'sigma', 'string', 'symbols', 't', 'tau', 'theta', 'u', 'upsilon', 'v', 'w', 'x', 'xi', 'y', 'z', 'zeta']
The variable name from the namespace can be removed with the command
del name1, name2, .. :
>>> type(x) <class 'sympy.core.symbol.Symbol'> >>> del x,y >>> x NameError: name 'x' is not defined
To restore the values of standard constants, as well as the names of some functions, you need to reload the sympy module.
>>> from sympy import *
The subs (...) method
It should be remembered that when writing a symbolic expression, it can be automatically simplified, for example:
>>> a,b,c,d,x,y,z,u,v,w = symbols('abcdxyzuv w') >>> x - z + 20 -z- 15 + 3*sin(pi/2)+2*z x + 8
The
subs (...) method is used to calculate a character expression for given values of variables, for example:
>>> a, x = symbols('a x') >>> f= a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4 >>> f.subs(a,1)
If two arguments are used in the subs method, they are interpreted as subs (old, new), i.e. old identifier old is replaced by new new. The argument to the subs () method can be a sequence that must contain pairs (old, new), or it can be a character expression, for example:
>>> a,b,c,d,x,y,z = symbols('abcdxy z') >>> f=a*x**3 +b*y**2 + c*z+d >>> f.subs([(a,1),(b,2),(c,3),(d,4)])
We draw your attention to the following peculiarity of working with variables (character and regular Python variables). Run the following code:
>>> x='Hello' >>> pr=x+'world' >>> pr 'Helloworld' >>> x='AAA'
The rule here is that if a variable has changed, then the expression created earlier containing this variable is not automatically recalculated. This rule also works for regular Python variables.
Fraction Operations
The SymPy module can perform calculations with fractions and bring them to a common denominator, for example, compare:
>>> S(1)/3+S(2)/5 11/15 >>> 1/3+2/5 0.7333333333333334
The functions
Rational (numerator, denominator) and
Integer (...) are used to create rational fractions without decimal rounding:
>>> z=Rational(1, 7)+Rational(2, 5); z 19/35 >>> Integer(1)/Integer(5) 1/5 >>> 1/5 0.2 >>> z=Integer(1)/Integer(5)+Rational(2, 7); z 17/35
Rounding calculations
In symbolic calculations, the rule works - if nothing is said, do not do any rounding. See how in the first case Python converts the expression, but leaves the square root in the answer record and does not perform any rounding, and in the second, since one of the numbers is given with a decimal point, the result will be approximate:
>>> sqrt(20) 2*sqrt(5) >>> sqrt(20.0)
For any character object, there is an
evalf (...) method (
eval uate
f loat), which returns its decimal representation:
>>> sqrt(20).evalf()
In the
evalf ([n, ...]) method
, you can use an argument specifying the accuracy of the result (n = number of significant digits)
>>> sqrt(20).evalf(30) 4.47213595499957939281834733746 >>> pi.evalf(20) 3.1415926535897932385
You should also always remember that real arithmetic does not return an exact result, compare:
>>> from sympy import * >>> one=S('one') >>> one = cos(1)**2 + sin(1)**2 >>> one.evalf()
If the result is known to contain a calculation error, then using the
chop = True option of the
evalf () method, it can be removed. A very small value of the real or imaginary part of the result in this case is replaced by zero. Take the previous example:
>>> (one-1).evalf()
Infinity
After the first line
from sympy import * is executed, the infinity symbol -
oo (two letters „o) becomes available, with which you can also perform certain operations:
>>> oo+1 oo >>> 1000000<oo True >>> 1/oo 0
The infinity symbol is mainly used by the functions
limit () and
integrate () when defining the limits of integration, which we will discuss in one of the following articles.
Conclusion
The symbolic calculations considered in the article differ from numerical methods in that the results can be further investigated, for example, to determine the extremes of functions, solve equations with nested variables, and so on.
I hope my article will be useful to anyone interested in Python programming, students and those who are engaged in scientific research.