SymPy — это библиотека Python для выполнения символьных вычислений. Это система компьютерной алгебры, которая может выступать как отдельное приложение, так и в качестве библиотеки для других приложений. Поработать с ней онлайн можно на https://live.sympy.org/. Поскольку это чистая библиотека Python, ее можно использовать даже в интерактивном режиме.
В SymPy есть разные функции, которые применяются в сфере символьных вычислений, математического анализа, алгебры, дискретной математики, квантовой физики и так далее. SymPy может представлять результат в разных форматах: LaTeX, MathML и так далее. Распространяется библиотека по лицензии New BSD. Первыми эту библиотеку выпустили разработчики Ondřej Čertík и Aaron Meurer в 2007 году. Текущая актуальная версия библиотеки — 1.6.2.
Вот где применяется SymPy:
Многочлены
Математический анализ
Дискретная математика
Матрицы
Геометрия
Построение графиков
Физика
Статистика
Комбинаторика
Установка SymPy
Для работы SymPy требуется одна важная библиотека под названием mpmath. Она используется для вещественной и комплексной арифметики с числами с плавающей точкой произвольной точности. Однако pip установит ее автоматически при загрузке самой SymPy:
pip install sympy
Такие дистрибутивы, как Anaconda, Enthough, Canopy и другие, заранее включают SymPy. Чтобы убедиться в этом, достаточно ввести в интерактивном режиме команду:
Символьные вычисления — это разработка алгоритмов для управления математическими выражениями и другими объектами. Такие вычисления объединяют математику и компьютерные науки для решения математических выражений с помощью математических символов.
Система компьютерной алгебры же, такая как SymPy, оценивает алгебраические выражения с помощью тех же символов, которые используются в традиционных ручных методах. Например, квадратный корень числа с помощью модуля math в Python вычисляется вот так:
Как можно увидеть, квадратный корень числа 7 вычисляется приблизительно. Но в SymPy квадратные корни чисел, которые не являются идеальными квадратами, просто не вычисляются:
from sympy import *
x = Symbol('x')
expr = integrate(x**x, x)
expr
Если выполнить эту команду в IDLE, то получится следующий результат:
Integral(x**x,x)
А в Jupyter:
Квадратный корень неидеального корня также может быть представлен в формате LaTeX с помощью привычных символов:
Символьные вычисления с помощью таких систем, как SymPy, помогают выполнять вычисления самого разного рода (производные, интегралы, пределы, решение уравнений, работа с матрицами) в символьном виде.
В пакете SymPy есть разные модули, которые помогают строить графики, выводить результат (LaTeX), заниматься физикой, статистикой, комбинаторикой, числовой теорией, геометрией, логикой и так далее.
Числа
Основной модуль в SymPy включает класс Number, представляющий атомарные числа. У него есть пара подклассов: Float и Rational. В Rational также входит Integer.
Класс Float
Float представляет числа с плавающей точкой произвольной точности:
Класс Integer в SymPy представляет целое число любого размера. Конструктор принимает рациональные и числа с плавающей точкой. В результате он откидывает дробную часть:
Также есть класс RealNumber, который является алиасом для Float. В SymPy есть классы-одиночки Zero и One, доступные через S.Zero и S.One соответственно.
>>> from sympy import S
>>> print(S.Half)
1/2
>>> print(S.NaN)
nan
Бесконечность представлена в виде объекта-символа oo или как S.Infinity:
ImaginaryUnit можно импортировать как символ I, а получить к нему доступ — через S.ImaginaryUnit.
Символы
Symbol — самый важный класс в библиотеке SymPy. Как уже упоминалось ранее, символьные вычисления выполняются с помощью символов. И переменные SymPy являются объектами класса Symbol.
Аргумент функции Symbol() — это строка, содержащая символ, который можно присвоить переменной.
Также в SymPy есть функция Symbols(), с помощью которой можно определить несколько символов за раз. Строка содержит названия переменных, разделенные запятыми или пробелами.
from sympy import symbols
x, y, z = symbols("x, y, z")
В модуле abc можно найти элементы латинского и греческого алфавитов в виде символов. Таким образом вместо создания экземпляра Symbol можно использовать метод:
Однако C, O, S, I, N, E и Q являются заранее определенными символами. Также символы с более чем одной буквы не определены в abc. Для них нужно использовать объект Symbol. Модуль abs определяет специальные имена, которые могут обнаружить определения в пространстве имен SymPy по умолчанию. сlash1 содержит однобуквенные символы, а clash2 — целые слова.
Индексированные символы (последовательность слов с цифрами) можно определить с помощью синтаксиса, напоминающего функцию range(). Диапазоны обозначаются двоеточием. Тип диапазона определяется символом справа от двоеточия. Если это цифра, то все смежные цифры слева воспринимаются как неотрицательное начальное значение.
Смежные цифры справа берутся на 1 больше конечного значения.
>>> from sympy.abc import a, b
>>> expr = (a + b)**2
>>> expr1 = expr.subs(b, a + b)
>>> expr1
Это дает такой вывод:
Функция simplify()
Функция simplify() используется для преобразования любого произвольного выражения, чтобы его можно было использовать как выражение SymPy. Обычные объекты Python, такие как целые числа, конвертируются в SymPy.Integer и так далее. Строки также конвертируются в выражения SymPy:
Любой объект Python можно конвертировать в объект SymPy. Однако учитывая то, что при преобразовании используется функция eval(), не стоит использовать некорректные выражения, иначе возникнет ошибка SimplifyError.
>>> sympify("x***2")
...
SympifyError: Sympify of expression 'could not parse 'x***2'' failed, because of exception being raised:
SyntaxError: invalid syntax (<string>, line 1)
Функция simplify() принимает следующий аргумент: strict=False. Если установить True, то преобразованы будут только те типы, для которых определено явное преобразование. В противном случае также возникнет ошибка SimplifyError. Если же поставить False, то арифметические выражения и операторы будут конвертированы в их эквиваленты SumPy без вычисления выражения.
Функция evalf()
Функция вычисляет данное числовое выражение с точностью до 100 цифр после плавающей точки. Она также принимает параметр subs, как объект словаря с числовыми значениями для символов. Например такое выражение:
По умолчанию точность после плавающей точки — 15, но это значение можно перезаписать до 100. Следующее выражение вычисляет, используя вплоть до 20 цифр точности:
>>> expr = a / b
>>> expr.evalf(20, subs={a: 100, b: 3})
33.333333333333333333
Функция lambdify()
Функция lambdify() переводит выражения SymPy в функции Python. Если выражение, которое нужно вычислить, затрагивает диапазон значений, то функция evalf() становится неэффективной. Функция lambdify действует как лямбда-функция с тем исключением, что она конвертирует SymPy в имена данной числовой библиотеки, обычно NumPy. По умолчанию же она реализована на основе стандартной библиотеки math.
Булевы функции расположены в модуле sympy.basic.booleanarg. Их можно создать и с помощью стандартных операторов Python: & (And), | (Or), ~ (Not), а также >> и <<. Булевы выражения наследуются от класса Basic.
BooleanTrue. Эта функция является эквивалентом True из Python. Она возвращает объект-одиночку, доступ к которому можно получить и с помощью S.true.
>>> from sympy import *
>>> from sympy.logic.boolalg import Or
>>> x, y = symbols('x y')
>>> x = True
>>> y = False
>>> Or(x, x|y)
Not. Результат этой функции — отрицание булево аргумента. True, если аргумент является False, и False в противном случае. В Python за это отвечает оператор ~. Пример:
>>> 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. Логический XOR (исключающий OR) возвращает True, если нечетное количество аргументов равняется True, а остальные — False. False же вернется в том случае, если четное количество аргументов True, а остальные — False. То же поведение работает в случае оператора ^.
>>> from sympy import *
>>> from sympy.logic.boolalg import Xor
>>> x, y = symbols('x y')
>>> x = True
>>> y = False
>>> Xor(x, y)
True
В предыдущем примере один(нечетное число) аргумент является True, поэтому Xor вернет True. Если же количество истинных аргументов будет четным, результатом будет False, как показано дальше.
>>> from sympy.logic.boolalg import Nor
>>> a, b = False, True
>>> Nor(a), Nor(a, b)
(True, False)
Хотя SymPy и предлагает операторы ^ для Xor, ~ для Not, | для Or и & для And ради удобства, в Python они используются в качестве побитовых. Поэтому если операнды будут целыми числами, результаты будут отличаться.
Equivalent. Эта функция возвращает отношение эквивалентности. Equivalent(A, B) будет равно True тогда и только тогда, когда A и B оба будут True или False. Функция вернет True, если все аргументы являются логически эквивалентными. В противном случае — False.
>>> from sympy.logic.boolalg import Equivalent
>>> a, b = True, False
>>> Equivalent(a, b), Equivalent(a, True)
( False, True)
Запросы
Модуль assumptions в SymPy включает инструменты для получения информации о выражениях. Для этого используется функция ask().
Следующие свойства предоставляют полезную информацию о выражении:
sympy.assumptions.ask(выражение)
algebraic(x) Чтобы быть алгебраическим, число должно быть корнем ненулевого полиномиального уравнения с рациональными коэффициентами. √2, потому что √2 — это решение x2 − 2 = 0. Следовательно, это выражения является алгебраическим.
complex(x) Предикат комплексного числа. Является истиной тогда и только тогда, когда x принадлежит множеству комплексных чисел.
composite(x) Предикат составного числа, возвращаемый ask(Q.composite(x)) является истиной тогда и только тогда, когда x — это положительное число, имеющее как минимум один положительный делитель, кроме 1 и самого числа.
even, odd ask() возвращает True, если x находится в множестве четных и нечетных чисел соответственно.
imaginary Свойство представляет предикат мнимого числа. Является истиной, если x можно записать как действительное число, умноженное на мнимую единицу.
integer Это свойство, возвращаемое Q.integer(x), будет истинным только в том случае, если x принадлежит множеству четных чисел.
rational, irrational Q.irrational(x) истинно тогда и только тогда, когда x — это любое реальное число, которое нельзя представить как отношение целых чисел. Например, pi — это иррациональное число.
positive, negative Предикаты для проверки того, является ли число положительным или отрицательным.
zero, nonzero Предикат для проверки того, является ли число нулем или нет.
SymPy умеет упрощать математические выражения. Для этого есть множество функций. Основная называется simplify(), и ее основная задача — представить выражение в максимально простом виде.
simplify
Это функция объявлена в модуле sympy.simplify. Она пытается применить методы интеллектуальной эвристики, чтобы сделать входящее выражение «проще». Следующий код упрощает такое выражение: sin^2(x)+cos^2(x)
Функция expand() делает выражение больше, а не меньше. Обычно это так и работает, но часто получается так, что выражение становится меньше после использования функции:
>>> x, y, z = symbols('x y z')
>>> expr = (x**2*z + 4*x*y*z + 4*y**2*z)
>>> factor(expr)
Вывод: ?(?+2?)2.
Функция factor() — это противоположность expand(). Каждый делитель, возвращаемый factor(), будет несокращаемым. Функция factor_list() предоставляет более структурированный вывод:
Эта функция берет любую рациональную функцию и приводит ее в каноническую форму p/q, где p и q — это разложенные полиномы без общих множителей. Старшие коэффициенты p и q не имеют знаменателей, то есть, являются целыми числами.
>>> expr1=x**2+2*x+1
>>> expr2=x+1
>>> cancel(expr1/expr2)
x + 1
Еще несколько примеров:
trigsimp
Эта функция используется для упрощения тригонометрических тождеств. Стоит отметить, что традиционные названия обратных тригонометрических функций добавляются в название функции в начале. Например, обратный косинус или арккосинус называется acos():
Можно сделать так, чтоб powsimp() объединяла только основания или степени, указав combine='base' или combine='exp'. По умолчанию это значение равно combine='all'. Также можно задать параметр force. Если он будет равен True, то основания объединятся без проверок.
Если здесь задать значение параметра force равным True, то указанные выше предположения будут считаться выполненными, если нет предположений о величине.
Производные
Производная функции — это ее скорость изменения относительно одной из переменных. Это эквивалентно нахождению наклона касательной к функции в точке. Найти дифференцирование математических выражений в форме переменных можно с помощью функции diff() из SymPy.
>>> from sympy import diff, sin, exp
>>> from sympy.abc import x, y
>>> expr = x*sin(x*x) + 1
>>> expr
Вывод: ?sin(?2)+1.
Чтобы получить несколько производных, нужно передать переменную столько раз, сколько нужно выполнить дифференцирование. Или же можно просто указать это количество с помощью числа.
Неоцененная производная создается с помощью класса Derivative. У него такой же синтаксис, как и функции diff(). Для оценки же достаточно использовать метод doit.
Интеграция
SymPy включает и модуль интегралов. В нем есть методы для вычисления определенных и неопределенных интегралов выражений. Метод integrate() используется для вычисления обоих интегралов. Для вычисления неопределенного или примитивного интеграла просто передайте переменную после выражения.
Для вычисления определенного интеграла, передайте аргументы следующим образом:
Пример определенного интеграла:
С помощью объекта Integral можно создать неоцененный интеграл. Он оценивается с помощью метода doit().
Трансформации интегралов
SymPy поддерживает разные виды трансформаций интегралов:
laplace_tranfsorm.
fourier_transform.
sine_tranfsorm.
cosine_transform.
hankel_transform.
Эти функции определены в модуле sympy.integrals.transforms. Следующие примеры вычисляют преобразования Фурье и Лапласа соответственно:
>>> 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)
Матрицы
В математике матрица — это двумерный массив чисел, символов или выражений. Теория манипуляций матрицами связана с выполнением арифметических операций над матричными объектами при соблюдении определенных правил.
Линейная трансформация — одно из важнейших применений матрицы. Она часто используется в разных научных областях, особенно связанных с физикой. В SymPy есть модуль matrices, который работает с матрицами. В нем есть класс Matrix для представления матрицы.
Примечание: для выполнения кода в этом разделе нужно сперва импортировать модуль matrices следующим образом.
Умножение матрицы возможно лишь в том случае, если количество колонок первой матрицы соответствует количеству колонок второй. Результат будет иметь такое же количество строк, как у первой матрицы и столько же колонок, сколько есть во второй.
Для вычисления определителя матрицы используется метод det(). Определитель — это скалярное значение, которое может быть вычислено из элементов квадратной матрицы.
SymPy предоставляет множество специальных типов классов матриц. Например, Identity, матрица из единиц, нолей и так далее. Эти классы называются eye, zeroes и ones соответственно. Identity — это квадратная матрица, элементы которой по диагонали равны 1, а остальные — 0.
В матрице diag элементы по диагонали инициализируются в соответствии с предоставленными аргументами.
В пакете SymPy есть класс Function, определенный в модуле sympy.core.function. Это базовый класс для всех математических функций, а также конструктор для неопределенных классов.
Следующие категории функций наследуются от класса Function:
Функции для комплексных чисел
Тригонометрические функции
Функции целого числа
Комбинаторные функции
Другие функции
Функции комплексных чисел
Набор этих функций определен в модуле sympy.functions.elementary.complexes.
re — Эта функция возвращает реальную часть выражения:
Функция abs возвращает абсолютное значение комплексного числа. Оно определяется как расстояние между основанием (0, 0) и точкой на комплексной плоскости. Эта функция является расширением встроенной функции abs() и принимает символьные значения.
Например, Abs(2+3*I), вернет √13.
conjugate — Функция возвращает сопряжение комплексного числа. Для поиска меняется знак мнимой части.
В SymPy есть определения всех тригонометрических соотношений: синуса, косинуса, тангенса и так далее. Также есть обратные аналоги: asin, acos, atan и так далее. Функции вычисляют соответствующее значение данного угла в радианах.
Одномерная функция ceiling, возвращающая самое маленькое целое число, которое не меньше аргумента. В случае с комплексными числами округление до большего целого для целой и мнимой части происходит отдельно.
floor — Возвращает самое большое число, которое не больше аргумента. В случае с комплексными числами округление до меньшего целого для целой и мнимой части происходит отдельно.
Комбинаторика — это раздел математики, в котором рассматриваются выбор, расположение и работа в конечной и дискретной системах.
factorial — Факториал очень важен в комбинаторике. Он обозначает число способов, которыми могут быть представлены объекты.
Кватернион
В математика числовая система кватернион расширяет комплексные числа. Каждый объект включает 4 скалярные переменные и 4 измерения: одно реальное и три мнимых.
Кватернион можно представить в виде следующего уравнения: q = a + bi + cj + dk, где a, b, c и d — это реальные числа, а i, j и k — квартенионные единицы, так что i2 == j2 == k2 = ijk.
Класс Quaternion расположен в модуле sympy.algebras.quaternion.
Поскольку символы = и == определены как символ присваивания и равенства в Python, их нельзя использовать для создания символьных уравнений. Для этого в SymPy есть функция Eq().
>>> x = ymbol('x')
>>> f = symbols('f', cls=Function)
>>> f(x)
?(?)
Здесь f(x) — это невычисленная функция. Ее производная:
Сначала создается объект Eq, соответствующий следующему дифференциальному уравнению.
Графики
SymPy использует библиотеку matplotlib в качестве бэкенда для рендеринга двухмерных и трехмерных графиков математических функций. Убедитесь, что на вашем устройстве установлена matplotlib. Если нет, установите с помощью следующей команды.
pip install matplotlib
Функции для работы с графиками можно найти в модуле sympy.plotting:
Функция plot() возвращает экземпляр класса Plot. Сам график может включать одно или несколько выражений SymPy. По умолчанию в качестве бэкенда используется matplotlib, но вместе нее можно взять texplot, pyglet или API Google Charts.
plot(expr,range,kwargs)
где expr — это любое валидное выражение SymPy. Если не сказано другое, то по умолчанию значение range равно (-10, 10).
Следующий график показывает квадрат для каждого значения в диапазоне от -10 до 10.
Чтобы нарисовать параметрический объемный график, используйте plot3d_parametric_surface().
Сущности
Модуль geometry в SymPy позволяет создавать двухмерные сущности, такие как линия, круг и так далее. Информацию о них можно получить через проверку коллинеарности или поиск пересечения.
Point
Класс point представляет точку Евклидового пространства. Следующие примеры проверяют коллинеарность точек:
>>> 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
Метод distance() класса Point вычисляет расстояние между двумя точками.
Line
Сущность Line можно получить из двух объектов Point. Метод intersection() возвращает точку пересечения двух линий.
>>> from sympy.geometry import Ellipse, Line
>>> e = Ellipse(Point(0, 0), 8, 3)
>>> e.area
24?
vradius может быть получен косвенно с помощью параметра eccentricity.
apoapsis — это наибольшее расстояние между фокусом и контуром.
метод equation эллипса возвращает уравнение эллипса.
Множества
В математике множество — это четко определенный набор объектов, которые могут быть числами, буквами алфавита или даже другими множествами. Set — это также один из встроенных типов в Python. В SymPy же есть модуль sets. В нем можно найти разные типы множеств и операции поиска пересекающихся элементов, объединения и так далее.
Set — это базовый класс для любого типа множества в Python. Но стоит отметить, что в SymPy он отличается от того, что есть в Python. Класс interval представляет реальные интервалы, а граничное свойство возвращает объект FiniteSet.
По аналогии со встроенным множеством, Set из SymPy также является коллекцией уникальных объектов.
ConditionSet — это множество элементов, удовлетворяющих заданному условию.
Union — составное множество. Оно включает все элементы из двух множеств. Если же какие-то повторяются, то в результирующем множестве будет только одна копия.
>>> from sympy import SymmetricDifference
>>> l1 = [3, 1]
>>> a = FiniteSet(*l1)
>>> b = FiniteSet(*l2)
>>> SymmetricDifference(a, b)
{1,2}
Вывод в консоль
В SymPy есть несколько инструментов для вывода. Вот некоторые из них:
str,
srepr,
ASCII pretty printer,
Unicode pretty printer,
LaTeX,
MathML,
Dot.
Объекты SymPy также можно отправить как ввод в другие языки программирования, такие как C, Fortran, JavaScript, Theano.
SymPy использует символы Юникод для рендеринга вывода. Если вы используете консоль Python для работы с SymPy, то лучше всего применять функцию init_session().
>>> 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
⌡
Если нет LaTeX, но есть matplotlib, то последняя будет использоваться в качестве движка рендеринга. Если и matplotlib нет, то применяется Unicode pretty printer. Однако Jupyter notebook использует MathJax для рендеринга LaTeX.
В терминале, который не поддерживает Unicode, используется ASCII pretty printer (как в выводе из примера).
Для ASCII printer есть функция pprinter() с параметром use_unicode=False.
Также доступ к Unicode printer можно получить из pprint() и pretty(). Если терминал поддерживает Unicode, то он используется автоматически. Если поддержку определить не удалось, то можно передать use_unicode=True, чтобы принудительно использовать Unicode.
Для получения LaTeX-формата используйте функцию latex().