0. はじめに
本稿では SymPy における文字の定義を整理します.
SymPy とは代数計算を目的とした Python の ライブラリです.1
SymPy がインストールされていることは前提します.
import sympy as sy
print(sy.__version__)
# 1.11
1. abc
まずプログラムの頭でできることは abc モジュールから用意された文字を import することです.2
from sympy.abc import x,y,z
print(x,y,z)
print(type(x))
# x y z
# <class 'sympy.core.symbol.Symbol'>
abc モジュールのソースコードを見ると使用可能な文字の一覧がわかります.
a, b, c, d, e, f, g, h, i, j = symbols('a, b, c, d, e, f, g, h, i, j')
k, l, m, n, o, p, q, r, s, t = symbols('k, l, m, n, o, p, q, r, s, t')
u, v, w, x, y, z = symbols('u, v, w, x, y, z')
A, B, C, D, E, F, G, H, I, J = symbols('A, B, C, D, E, F, G, H, I, J')
K, L, M, N, O, P, Q, R, S, T = symbols('K, L, M, N, O, P, Q, R, S, T')
U, V, W, X, Y, Z = symbols('U, V, W, X, Y, Z')
alpha, beta, gamma, delta = symbols('alpha, beta, gamma, delta')
epsilon, zeta, eta, theta = symbols('epsilon, zeta, eta, theta')
iota, kappa, lamda, mu = symbols('iota, kappa, lamda, mu')
nu, xi, omicron, pi = symbols('nu, xi, omicron, pi')
rho, sigma, tau, upsilon = symbols('rho, sigma, tau, upsilon')
phi, chi, psi, omega = symbols('phi, chi, psi, omega')
lambda ではなく重複を避けて lamda とされていることに注意しましょう.
symbols 関数については後述することにしましょう.
2. Symbol
次に1つ文字を定義するやり方です.
それが Symbol
です.
from sympy import Symbol
# from sympy import *
x = Symbol("x")
xi = Symbol("xi")
print(x,xi)
# x xi
最も基本的な方法なので多くのサンプルコードで使用されています.
3. symbols
複数の文字を一度に定義するには symbols
を使います.式の区切りにはスペースかコンマを入れます.出力はタプルです.
from sympy import symbols
xyz = symbols("x y z")
print(xyz)
print(xyz == symbols("x, y, z"))
# (x, y, z)
# True
文字式で四則演算等が行なえます.
x,y,z = xyz
print(x * y * z)
print(x + y + z)
# x*y*z
# x + y + z
4.【応用】整数添字付き記号を定義する
応用としてコロンを用いた添字記法を見てみましょう.ここでは整数添字,つまり
x = (x_{\mu})_{\mu \in M},\quad M ⊆ \mathbb{Z}
を表現する方法を典型的なものとして例に取ります.
4.1 非負整数
$M ⊆ \mathbb{N} = {0,1,2,3,\dots}$ の時は symbols
と :
を使って以下のように文字式を生成することができます.
from sympy import symbols
x = symbols("x0:"+str(3+1))
print(x)
# (x0, x1, x2, x3)
4.2 負数
最後に,$M \subsetneq \mathbb{N} $ の時つまり負の数を添え字にもつ場合を考えます.
Python 3.8.6 の時点で "x_-1"
という表記が可能なのでこれを使います.
級数展開の部分和を以下のプログラムで計算できます.負冪は Laurent 展開の時に出てきます.
Symbol
には(群や多元環としての)積の可換性を指定するオプションがあり今回は係数を冪の前に表示するために非可換にしておきます.係数同士も非可換になります.
非負添字の Coefplus
と負添字の Coefminus
をタプルとして結合します.
そして係数と冪の積和を取り多項式(正確には有理式)を生成します.
N0 = 4
def Coefs(x: str,N: int = N0,com: bool =False):
Coefplus = symbols(x+'0:'+str(N+1),commutative=com)
Coefminus = symbols(x+'_-1:'+str(N+1),commutative=com)[::-1]# [::-1] means reversed
return Coefplus + Coefminus
def _polynomial(a_str,x,N=N0):
return sum([Coefs(a_str)[n] * x**n for n in range(-N,N+1)])
x = Symbol("x",commutative = False)
print(x + Coefs("a")[0] == Coefs("a")[0] + x)
print(x * Coefs("a")[0] == Coefs("a")[0] * x)
print(_polynomial("a",x))
# True
# False
# a0 + a1*x + a2*x**2 + a3*x**3 + a4*x**4 + a_-1*x**(-1) + a_-2*x**(-2) + a_-3*x**(-3) + a_-4*x**(-4)
最終行は以下のような $-4$ 次から $4$ 次までの出力です.
a_{0} + a_{1} x + a_{2} x^{2} + a_{3} x^{3} + a_{4} x^{4} + a_{-1} x^{-1} + a_{-2} x^{-2} + a_{-3} x^{-3} + a_{-4} x^{-4}
4.3 可換性
積の可換性を変更すると出力,つまり積の順番も変わり得ます.可換演算について順番をうまく指定する方法は特にないのでその時は順序を無視して計算してよいです.
参考例
例えば.殆どの記法,特に Python では和は可換演算です.差はその逆演算だから和に書き換えられて,特に反可換です.
もし仮に $x - \alpha $ と表示させたい所 $- \alpha + x $ と出力されたとしても,そのまま計算すればよいです.
from sympy.abc import x, alpha
print(x - alpha)
# -alpha + x
5. その他補足
5.1 アルファベット
コロンの文法で連続アルファベットの組を生成することができます.
print(symbols('w:z'))
print(symbols('a:z'))
# (w, x, y, z)
# (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)
5.2 var
var
関数でアルファベットを global 変数として定義することを宣言できます.
from sympy import var
var('X, Y', commutative=False)
print(X * Y - Y * X)
# X*Y - Y*X
ソースコードに
Create symbols and inject them into the global namespace.
Explanation
===========
This calls :func:`symbols` with the same arguments and puts the results
into the *global* namespace. It's recommended not to use :func:`var` in
library code, where :func:`symbols` has to be used::
とあります.VSCode 上では未定義として扱われ Warning が出ます.
5.3 display
本稿では簡単のため出力に print
を用いましたが LaTeX 式のイタリック表記等ができてそれがしたい時は display
関数を使います.
6. おわりに
SymPy を使って記号計算を行うことができ,高い表現力をもちほとんど場合軽いです.
sympy.abc, Symbol, symbols
を使いこなすことで複雑な計算処理を手計算なしに終わらせることができます.