Julia
テンソル

JuliaとEinsum.jlで計量テンソルを計算してみた(アインシュタインの縮約記法)

Juliaでアインシュタインの縮約記法が使えるパッケージEinsum.jlを使ってみました。

実は、Juliaを始めたのはこれが目的だったり。

使い方はEinsum.jlのREADME.mdを参照。

Juliaのインストール方法については前回記事参照のこと。


Einsumパッケージをインストール

前回同様、Juliaを立ち上げてパッケージをインストールします。

ターミナルで

$ julia

julia>[
(v1.0) pkg> add Einsum

これでOK。


問題

テンソル代数の問題はテンソル解析 (基礎数学選書 23) p179より。

以前の記事で、同じ教科書の別の問題をNumPyで解いてました。

過去記事1:https://qiita.com/MTNakata/items/c23b221fcafa23a095eb

過去記事2:https://qiita.com/MTNakata/items/8c431ca225c5576de18a

以下のような、直交基底$\Sigma${$e_1,e_2,e_3$}から基底$\Sigma'${$e'_1,e'_2,e'_3$}への変換式

\begin{aligned}

&e'_1 = 2 e_1 \\
&e'_2 = -e_1 + e_2 \\
&e'_3 = e_1 -2 e_2 + 3 e_3
\end{aligned}

を持つ場合に基底$\Sigma'$の計量テンソル$g'_{ab}$を求める問題。


準備

共変の基底ベクトル$e_i$は行ベクトルを表すので、変換式を行列で書き直すと

\begin{pmatrix}

e'_1 & e'_2 & e'_3
\end{pmatrix}
=
\begin{pmatrix}
e_1 & e_2 & e_3
\end{pmatrix}
\,
\begin{pmatrix}
2 & -1 & 1 \\
0 & 1 & -2 \\
0 & 0 & 3
\end{pmatrix}

のようになります。

アインシュタインの縮約記法で書くと以下の通り。

e'_a = e_i \, \bar{A^i{}_a}

$\bar{A}$は行列$A$の逆行列です。

$\bar{A}$をA_invに、$A$をAに、Juliaで変数代入します。

func1 = [2,0,0] #変換式1を列ベクトルで

func2 = [-1,1,0] #変換式2を列ベクトルで
func3 = [1,-2,3] #変換式3を列ベクトルで
A_inv = [func1 func2 func3]

#3×3 Array{Int64,2}:
# 2 -1 1
# 0 1 -2
# 0 0 3

A = inv(A_inv)

#3×3 Array{Float64,2}:
# 0.5 0.5 0.166667
# 0.0 1.0 0.666667
# 0.0 0.0 0.333333

Juliaで逆行列を求めるには、inv()を使います。

Python(というかNumPy)と行列の書き方が違うので違和感はありますが、なんとなくJuliaのほうがすっきりしているかな。

慣れればこっちのほうがラクそう。


解答

計量テンソル(共変・反変)の変換式は以下の通り。

\begin{aligned}

g'_{ab} &= \bar{A^i{}_a} \, \bar{A^j{}_b} g_{ij} \\
&= \bar{A^i{}_a} \, \bar{A^j{}_b} \delta_{ij}
= \bar{A^i{}_a} \, \bar{A^i{}_b}
\end{aligned}

\begin{aligned}

g'^{ab} &= A^a{}_i \, A^b{}_j g^{ij} \\
&= A^a{}_i \, A^b{}_j \delta_{ij}
= A^a{}_i \, A^b{}_i
\end{aligned}

ここで、$g_{ij}, g^{ij}$は基底$\Sigma$の計量テンソル。$g'_{ab}, g'^{ab}$は基底$\Sigma'$の計量テンソル。

$\Sigma$は直交基底なので$g_{ij}=g^{ij}=\delta_{ij}$です。

では、早速Juliaで計算していきます。

Jupyter notebookを立ち上げて、Einsumパッケージを読み込みます。

using Einsum

まずは、$g'_{ab}$を計算。

\begin{aligned}

g'_{ab} = \bar{A^i{}_a} \, \bar{A^i{}_b}
\end{aligned}

@einsum g1[a,b] := A_inv[i,a] * A_inv[i,b]

#3×3 Array{Int64,2}:
# 4 -2 2
# -2 2 -3
# 2 -3 14

次に、$g'^{ab}$を計算。

\begin{aligned}

g'^{ab} = A^a{}_i \, A^b{}_i
\end{aligned}

@einsum g2[a,b] := A[a,i] * A[b,i]

#3×3 Array{Float64,2}:
# 0.527778 0.611111 0.0555556
# 0.611111 1.44444 0.222222
# 0.0555556 0.222222 0.111111

数式そのままで書けて、とてもわかりやすいですね。