SymPy で Matrix()
を使ったベクトル・行列の定義と演算,および勾配 (grad),発散 (div),回転 (rot) を定義してベクトル解析。
SymPy の import
from sympy.abc import *
from sympy import *
Matrix()
を使ったベクトルの定義
Matrix()
を使った3次元ベクトル $\boldsymbol{a} = (a_1, a_2, a_3)$ の定義例。成分は実数とします。
# 成分に使う変数の宣言
var('a1:4', real=True) # var('a1 a2 a3') と同じ
a = Matrix([a1, a2, a3])
a
$\boldsymbol{b} = (b_1, b_2, b_3), \ \boldsymbol{c} = (c_1, c_2, c_3)$ も同様に定義。以下のような書き方もできるようだ。
# Matrix() の中に変数の宣言を入れる方法
b = Matrix(var('b1:4', real=True))
c = Matrix(var('c1:4', real=True))
display(b)
display(c)
ベクトルの演算
たし算,引き算 +, -
ベクトルの足算引き算をしてみると,成分同士の足算引き算になっていることがわかります。
a + b
a - b
ベクトルの定数倍(スカラー倍) *
ベクトルの定数倍(スカラー倍)は,各成分にそれぞれ定数(スカラー)をかけたものになっています。
var('C')
C*a
ベクトルの内積 .dot()
ベクトルの内積は $\boldsymbol{a}\cdot\boldsymbol{b} = $a.dot(b)
です。
a.dot(b)
ベクトルの大きさ .norm()
ベクトル $\boldsymbol{a}$ の大きさ $|\boldsymbol{a}|$ は
$|\boldsymbol{a}| \equiv \sqrt{\boldsymbol{a}\cdot\boldsymbol{a}} =$ a.norm()
ベクトル $\boldsymbol{a}$ の大きさ $|\boldsymbol{a}|$ を計算してみます。
a.norm()
ベクトルの外積 .cross()
ベクトルの外積は $\boldsymbol{a}\times\boldsymbol{b} = $a.cross(b)
です。
a.cross(b)
外積は「反交換」
$\boldsymbol{a}\times\boldsymbol{b} {\color{red}{\neq}} \boldsymbol{b}\times\boldsymbol{a}$ であること,具体的には以下のように「反交換」であることを確認します。
$$\boldsymbol{a}\times\boldsymbol{b} = -\boldsymbol{b}\times\boldsymbol{a}$$
$\boldsymbol{a}\times\boldsymbol{b} + \boldsymbol{b}\times\boldsymbol{a} = \boldsymbol{0}$ となることを示せばいいです。
a.cross(b) + b.cross(a)
あるいは比較演算子 ==
を使って a.cross(b) == -b.cross(a)
が True
であることを示してもよいです。
a.cross(b) == -b.cross(a)
ベクトルの三重積
スカラー三重積
3つのベクトル $\boldsymbol{a}, \boldsymbol{b}, \boldsymbol{c}$ によるスカラー三重積は
$$\boldsymbol{a} \cdot (\boldsymbol{b}\times\boldsymbol{c})$$
であり,これは結局はスカラーとなります。スカラー三重積には,以下のような公式があります。
$$\boldsymbol{a} \cdot (\boldsymbol{b}\times\boldsymbol{c})
= \boldsymbol{b} \cdot (\boldsymbol{c}\times\boldsymbol{a})
= \boldsymbol{c} \cdot (\boldsymbol{a}\times\boldsymbol{b}) $$
○練習:スカラー三重積の公式
$\boldsymbol{a} \cdot (\boldsymbol{b}\times\boldsymbol{c})
= \boldsymbol{b} \cdot (\boldsymbol{c}\times\boldsymbol{a})$ が成り立つことを示せ。
ヒント:
a.dot(b.cross(c)) - b.dot(c.cross(a))
を expand()
でかっこをはずして展開してゼロになることを示せばよい。
同様にして,$\boldsymbol{b} \cdot (\boldsymbol{c}\times\boldsymbol{a})
= \boldsymbol{c} \cdot (\boldsymbol{a}\times\boldsymbol{b}) $ が成り立つことも示せ。
ベクトル三重積
3つのベクトル $\boldsymbol{a}, \boldsymbol{b}, \boldsymbol{c}$ によるベクトル三重積は
$$\boldsymbol{a} \times (\boldsymbol{b}\times\boldsymbol{c})$$
であり,これは結局はベクトルをつくります。ベクトル三重積には,以下のような公式があります。
$$\boldsymbol{a} \times (\boldsymbol{b}\times\boldsymbol{c})
= (\boldsymbol{a}\cdot\boldsymbol{c})\,\boldsymbol{b} –
(\boldsymbol{a}\cdot\boldsymbol{b})\,\boldsymbol{c} $$
○練習:ベクトル三重積の公式
$\boldsymbol{a} \times (\boldsymbol{b}\times\boldsymbol{c})
= (\boldsymbol{a}\cdot\boldsymbol{c})\,\boldsymbol{b} –
(\boldsymbol{a}\cdot\boldsymbol{b})\,\boldsymbol{c} $ を示せ。
○練習:ベクトルの内積・外積
$\displaystyle \boldsymbol{a} = \left(-\frac{1}{\sqrt{2}}, \frac{1}{\sqrt{2}}, \sqrt{3} \right), \ \boldsymbol{b} = \left(-1, 1, -\sqrt{2} \right)$ について以下の量を計算しなさい。
$$1. \ |\boldsymbol{a}|, \quad 2. \ |\boldsymbol{b}|, \quad 3. \ \boldsymbol{a}\cdot\boldsymbol{b}, \quad 4. \ \boldsymbol{a}\times\boldsymbol{b}$$
また,2つのベクトル $\boldsymbol{a}, \boldsymbol{b}$ のなす角を $\theta$ としたときの $\cos\theta$ および $\sin\theta$ の値を求めなさい。
まず,ベクトル $\boldsymbol{a}, \boldsymbol{b}$ を Matrix()
で定義し…
a = Matrix([-1/sqrt(2), 1/sqrt(2), sqrt(3)])
b = Matrix([-1, 1, -sqrt(2)])
display(a)
display(b)
$1. \ |\boldsymbol{a}| = $ a.norm()
であるから…
$2. \ |\boldsymbol{b}| = $ b.norm()
であるから…
$3. \ \boldsymbol{a}\cdot\boldsymbol{b} = $ a.dot(b)
であるから…
$4. \ \boldsymbol{a}\times\boldsymbol{b} = $ a.cross(b)
であるから…
$\boldsymbol{a}\cdot\boldsymbol{b} = |\boldsymbol{a}| |\boldsymbol{b}| \cos\theta$ より,$\displaystyle \cos\theta = \frac{\boldsymbol{a}\cdot\boldsymbol{b}}{|\boldsymbol{a}| |\boldsymbol{b}|} = \cdots$
uhen1 = a.dot(b)/(a.norm()*b.norm())
Eq(cos(theta), uhen1)
ちなみに $\theta = $ acos(uhen1)
であるから,2つのベクトル $\boldsymbol{a}, \boldsymbol{b}$ のなす角 $\theta$ を求めると…
th1 = acos(uhen1)
th1
$|\boldsymbol{a}\times\boldsymbol{b}| = |\boldsymbol{a}| |\boldsymbol{b}| \sin\theta$ より $\displaystyle \sin\theta = \frac{|\boldsymbol{a}\times\boldsymbol{b}|}{|\boldsymbol{a}| |\boldsymbol{b}|} = \cdots$
uhen2 = (a.cross(b)).norm()/(a.norm()*b.norm())
Eq(sin(theta), uhen2)
$\theta = $ asin(uhen2)
であるから,2つのベクトル $\boldsymbol{a}, \boldsymbol{b}$ のなす角 $\theta$ を求めると…
asin(uhen2)
acos(uhen1)
から求めた角度 $\theta$ と asin(uhen2)
から求めた角度 $\theta$ は異なっているが,これはどのように考えたらよいか。
ヒント: $\arccos x$ と $\arcsin x$ の定義域はどちらも $-1 \leq x \leq 1$ だが,値域は?
Matrix()
を使った行列の定義
Matrix()
を使った行列
$$ A = \begin{pmatrix}
a_{11} & a_{12} \\
a_{21} & a_{22}
\end{pmatrix}$$
の定義例。
var('a11:13, a21:23')
A = Matrix([[a11, a12],
[a21, a22]])
A
以下のような書き方もできるようだ。
# Matrix() の中に変数の宣言を入れる方法
B = Matrix([var('b11:13'),
var('b21:23')])
B
行列の演算
たし算,引き算 +, -
A + B
A - B
行列の積 *
A * B
B * A
行列の積に関しては交換則は成り立ちません。$A B \neq B A$
比較演算子 !=
を使って「左辺」と「右辺」等しくないことを確認します。
A * B != B * A
転置行列 .transpose()
行列 $A$ の転置行列は $A^{T} = $ transpose(A)
または A.transpose()
A
A.transpose()
逆行列 .inv()
行列 $A$ の逆行列 $\displaystyle A^{-1}$ は A**(-1)
または A.inv()
A.inv()
$A^{-1} A$ や $A A^{-1}$ が単位行列になることを確認します。
A**(-1) * A
# 上記の結果を簡単化
simplify(_)
# together で一緒に(通分)
together(A * (A.inv()))
行列式 .det()
$A$ の行列式 $\det A$ は A.det()
または det(A)
A.det()
det(A)
$\det A = \det A^T$ および $\displaystyle \det A^{-1} = \frac{1}{\det A}$ であることを確認します。
det(A) == det(A.transpose())
det(A.inv()) == 1/det(A)
○練習:行列の積の行列式
$\displaystyle \det\, (A B) = (\det A) \cdot (\det B)$ を確認する。
display(A)
display(B)
○練習:3次元の回転行列
3次元空間での $z$ 軸周りの角度 $\phi$ の回転を表す回転行列は以下のように書けます。
$$R(\phi) =
\begin{pmatrix}
\cos \phi & -\sin \phi & 0\\
\sin \phi & \cos \phi & 0\\
0 & 0 & 1
\end{pmatrix}
$$
def R(phi):
return Matrix([[cos(phi), -sin(phi), 0],
[sin(phi), cos(phi), 0],
[0, 0, 1]])
$\displaystyle 1.\ R(\phi)$ が直交行列であることを示せ。
直交行列とは,転置行列が逆行列になっている行列のことですから,以下を示せばよいです。
$$R(\phi) \,R^T(\phi) = I$$
ここで,$I$ は単位行列。
ちなみに,$R(\phi)$ の逆行列は $R(-\phi)$ であることも確認できます。
位置ベクトル $\boldsymbol{r} = (x, y, z)$ をこの回転行列で直交変換してみます。
# 位置ベクトルの定義
r = Matrix(var('x y z', real = True))
r
直交変換されたベクトルの大きさは,元のベクトル $\boldsymbol{r}$ の大きさと同じであることを確かめます。
まず,元のベクトル $\boldsymbol{r}$ の大きさ(の2乗)は…
r.dot(r)
直交変換されたベクトルは…
r1 = R(phi) * r
r1
このベクトルの大きさ(の2乗)は…
(r1.dot(r1)).simplify()
ベクトル $\boldsymbol{r}$ の大きさ $|\boldsymbol{r}|$ は r.norm()
ですが,なぜこれを使わずに大きさの2乗 $\boldsymbol{r}\cdot\boldsymbol{r}$ を使ったか,わかりますか?
r.norm()
r1.norm()
$\displaystyle 2. \ R(\beta) \, R(\alpha) = R(\alpha+\beta)$ を示せ。
これは,まず $z$ 軸のまわりに角度 $\alpha$ だけ回転させ,引き続き角度 $\beta$ だけ回転させる変換は,$z$ 軸のまわりに一度に角度 $\alpha+\beta$ 回転させる変換と同じだということを表します。
# 変数の宣言
var('alpha beta')
R(beta) * R(alpha)
ベクトル解析
SymPy にはベクトル解析のためのモジュール sympy.vector
があるようですが,簡単なので,以下のようにその都度定義してやってみます。
スカラー場の勾配(grad()
の定義)
スカラー場 $\varphi(\boldsymbol{r})$ の勾配を与える関数 grad()
を定義する。
$$\nabla \varphi \equiv \mbox{grad}\, \varphi = \left(\frac{\partial \varphi}{\partial x}, \frac{\partial \varphi}{\partial y},\frac{\partial \varphi}{\partial z}\right)$$
def grad(phi):
return Matrix([diff(phi,x), diff(phi,y), diff(phi,z)])
スカラー場 $\varphi(x,y,z)$ の勾配 $\nabla\varphi$ を確認します。
# varphi を x, y, z の関数として宣言
varphi = Function('varphi')(x,y,z)
grad(varphi)
勾配の計算例
位置ベクトル $$\boldsymbol{r} = (x, y, z)$$ の大きさ
$$r = |\boldsymbol{r}| = \sqrt{x^2 + y^2 + z^2}$$ について,以下の計算をしてみます。
$$\nabla r = \frac{\partial r}{\partial x} \boldsymbol{i}
+\frac{\partial r}{\partial y} \boldsymbol{j}
+\frac{\partial r}{\partial z} \boldsymbol{k} $$
# 位置ベクトルの定義
rvec = Matrix(var('x y z', real = True))
display(rvec)
r = rvec.norm()
display(r)
$\nabla r$ を計算します。
grad(r)
上の結果が
$$\nabla r =\frac{x}{r} \,\boldsymbol{i} + \frac{y}{r} \,\boldsymbol{j} + \frac{z}{r} \,\boldsymbol{k} = \frac{\boldsymbol{r}}{r}$$
となっていることを確認します。
grad(r) == rvec/r
また,電磁気学では以下のような計算をする必要も出てくるので,やっておきます。
$$\nabla \left(\frac{1}{r}\right) = – \frac{\boldsymbol{r}}{r^3}$$
grad(1/r)
grad(1/r) == -rvec/r**3
ベクトル場の発散 (div()
の定義)
ベクトル場の発散を定義する。
$$\nabla\cdot\boldsymbol{v} \equiv \mbox{div}\, \boldsymbol{v} = \frac{\partial v_x}{\partial x} + \frac{\partial v_y}{\partial y} + \frac{\partial v_z}{\partial z}$$
def div(v):
return diff(v[0], x) + diff(v[1], y) + diff(v[2], z)
ベクトル場 $\boldsymbol{B}$ の発散
$$\nabla\cdot\boldsymbol{B} = \mbox{div}\, \boldsymbol{B} =
\frac{\partial B_x}{\partial x} + \frac{\partial B_y}{\partial y} +\frac{\partial B_x}{\partial x}$$
を確認します。
# ベクトル場 B の定義
B_x = Function('B_x')(x,y,z)
B_y = Function('B_y')(x,y,z)
B_z = Function('B_z')(x,y,z)
Bvec = Matrix([B_x, B_y, B_z])
Bvec
# B の発散
div(Bvec)
発散 の計算例
$$\nabla\cdot \boldsymbol{r} = \frac{\partial x}{\partial x} + \frac{\partial y}{\partial y} +\frac{\partial z}{\partial z} = 1+1+1 = 3$$
(答えは空間の次元の数)
# 位置ベクトルが定義されていることを確認
rvec
div(rvec)
ベクトル場の回転 (rot()
の定義)
ベクトルの回転を以下のようにして定義します。
\begin{eqnarray}
\nabla\times\boldsymbol{v} &\equiv& \mbox{rot}\, \boldsymbol{v} \\
&=&\left( \frac{\partial}{\partial y} v_z – \frac{\partial}{\partial z} v_y, \frac{\partial}{\partial z} v_x – \frac{\partial}{\partial x} v_z, \frac{\partial}{\partial x} v_y – \frac{\partial}{\partial y} v_x\right)
\end{eqnarray}
def rot(v):
vx = v[0]
vy = v[1]
vz = v[2]
return Matrix(
[diff(vz, y) - diff(vy, z),
diff(vx, z) - diff(vz, x),
diff(vy, x) - diff(vx, y)]
)
ベクトル場 $\boldsymbol{A}$ の回転 $\nabla\times\boldsymbol{A} = \mbox{rot}\, \boldsymbol{A} $ を確認します。
# ベクトル場 A の定義
A_x = Function('A_x')(x,y,z)
A_y = Function('A_y')(x,y,z)
A_z = Function('A_z')(x,y,z)
Avec = Matrix([A_x, A_y, A_z])
Avec
rot(Avec)
回転の計算例
$$\nabla\times \left(\frac{\boldsymbol{r}}{r}\right)$$
rvec/r
rot(rvec/r)
○練習:発散や回転の計算
$\displaystyle 1. \ \nabla\cdot\left(\frac{\boldsymbol{r}}{r}\right)$
$\displaystyle 2. \ \nabla\cdot\left(\frac{\boldsymbol{r}}{r^n}\right)$
$\displaystyle 3. \ \nabla\times\left(\frac{\boldsymbol{r}}{r}\right)$
$\displaystyle 4. \nabla\times\left(\frac{\boldsymbol{r}}{r^n}\right)$
勾配 (grad) の発散 (div):ラプラシアンの定義
スカラー場 $\varphi$ の勾配 $\nabla \varphi$ の発散 $$\nabla\cdot(\nabla \varphi) = \nabla^2 \varphi$$
ここで
$$\nabla^2 \equiv \frac{\partial^2}{\partial x^2} + \frac{\partial^2}{\partial y^2} +\frac{\partial^2}{\partial z^2}$$
はラプラス演算子(ラプラシアン)。
varphi = Function('varphi')(x, y, z)
varphi
div(grad(varphi))
スカラーに作用するラプラシアンの定義
# スカラー関数に作用するラプラス演算子の定義
def laplacian(phi):
# スカラー関数 phi のみに適用
return div(grad(phi))
ラプラス演算子の計算例
$$\nabla^2 \left(\frac{1}{r}\right) = 0 \quad (r \neq 0)$$
を確認します。
laplacian(1/r).simplify()
勾配 (grad) の回転 (rot):恒等式
スカラー場 $\varphi$ の勾配 $\nabla \varphi$ の回転 $\nabla\times(\nabla \varphi) $。
恒等的に
$$\nabla\times(\nabla \varphi) = \boldsymbol{0}$$である。
grad(varphi)
rot(grad(varphi))
回転 (rot) の発散 (div):恒等式
ベクトル場 $\boldsymbol{a}$ の回転 $\nabla \times\boldsymbol{a} $ の発散 $\nabla\cdot(\nabla \times\boldsymbol{a}) $
恒等的に
\begin{eqnarray}
\nabla\cdot(\nabla \times\boldsymbol{a}) &=&
0 \end{eqnarray}
である。
まずはベクトル場 $\boldsymbol{a}$ の定義:
# ベクトル場 a の定義
a_x = Function('a_x')(x,y,z)
a_y = Function('a_y')(x,y,z)
a_z = Function('a_z')(x,y,z)
avec = Matrix([a_x, a_y, a_z])
avec
$\nabla\times \boldsymbol{a}$
rot(avec)
$\nabla\cdot\left(\nabla\times \boldsymbol{a}\right)$
div(rot(avec))
回転 (rot) の回転 (rot)
ベクトル場 $\boldsymbol{a}$ の回転 $\nabla \times\boldsymbol{a} $ の回転 $\nabla\times(\nabla \times\boldsymbol{a}) $
$$ \nabla\times(\nabla \times\boldsymbol{a}) = \nabla\left( \nabla\cdot\boldsymbol{a} \right) – \nabla^2 \boldsymbol{a} $$
が成り立つことを確認する。
ベクトルに作用するラプラシアンの定義
# ベクトルに作用する Laplacian を定義
def Laplacian(v):
return Matrix([laplacian(v[0]),
laplacian(v[1]),
laplacian(v[2])])
rot(rot(avec))
grad(div(avec)) - Laplacian(avec)
rot(rot(avec)) == grad(div(avec)) - Laplacian(avec)
○練習:ベクトルの外積の発散
以下の式が成り立つことを示せ。
$$\nabla\cdot\left( \boldsymbol{E}\times\boldsymbol{B}\right)
= \left(\nabla\times\boldsymbol{E} \right)\cdot\boldsymbol{B}
– \boldsymbol{E}\cdot\left(\nabla\times\boldsymbol{B} \right)$$
E_x = Function('E_x')(x,y,z)
E_y = Function('E_y')(x,y,z)
E_z = Function('E_z')(x,y,z)
B_x = Function('B_x')(x,y,z)
B_y = Function('B_y')(x,y,z)
B_z = Function('B_z')(x,y,z)
E = Matrix([E_x, E_y, E_z])
B = Matrix([B_x, B_y, B_z])
display(E)
display(B)
○練習:スカラーとベクトルの積の発散
以下の式が成り立つことを示せ。
$$\nabla\cdot\left( \varphi\,\boldsymbol{D}\right) =
\left(\nabla\varphi\right)\cdot\boldsymbol{D} +\varphi\left(\nabla\cdot\boldsymbol{D}\right)$$
varphi = Function('varphi')(x, y, z)
display(varphi)
D_x = Function('D_x')(x,y,z)
D_y = Function('D_y')(x,y,z)
D_z = Function('D_z')(x,y,z)
D = Matrix([D_x, D_y, D_z])
display(D)