テンソルの添字記法は、数学や物理では広く使われている記法です。 テンソルの添字記法を使うと、ベクトルや行列よりも高階のテンソルの計算や、多くの行列が現れる計算を簡潔に記述できます。
Egisonは、テンソルの添字記法をそのままプログラムで使うことができます。 これは、スカラー仮引数・テンソル仮引数というプログラミング言語JのRankに似たアイデアに適切なシンボリックな添字の簡約ルールを組み合わせることにより、実現されています。 より直接的な記述で数式を表現できる数式処理システムの研究を進めていく過程で、この手法は発見されました。
このドキュメントでは、この手法について解説します。 このドキュメントは、テンソルの添字記法についての知識が読者にすでにあることを仮定しています。
テンソルの添字記法
例えば、テンソル解析で登場するリーマン曲率テンソルの公式を、Wolfram言語(Mathematica)による一般的な方法で記述したものと、Egisonで記述したものをくらべると以下のようになります。
Wolfram言語による記述では、テンソルのそれぞれの添字に対応する次元は全てM
であると仮定されています。
`R_(jkl)^i= (partial Gamma_(jl)^i)/(partial x^k) - (partial Gamma_(jk)^i)/(partial x^l) + Gamma_(jl)^m Gamma_(mk)^i - Gamma_(jk)^m Gamma_(ml)^i`
Wolfram言語による記述では、Table
式とSum
式による二重ループがプログラム中に現れているのに対し、Egisonによる記述では、数式と同様にフラットにこの式を記述できていることに注目してください。
これは、テンソルの添字記法をプログラミングで使うことによって実現されています。
特に、`\Gamma_{jk}^{m} \Gamma_{ml}^{i} - \Gamma_{jl}^{m} \Gamma_{mk}^{i}`を表現する際に、Wolfram言語で使われているSum
式に対応するループ構造がEgisonによる記述に現れていないのは、アインシュタインの縮約記法がEgisonで導入できているためです。
この例の中で特に注目してもらいたい箇所は、右辺第一項の`\frac{\partial \Gamma_{jk}^{i}}{\partial x^l}`を表現するEgisonプログラム∂/∂ Γ~i_j_k x~l
です。
Wolfram言語では、微分関数D
は、Table
式の中で、テンソルの成分に対して適用されています。
しかし、Egisonでは微分関数∂/∂
はテンソルに対してそのまま適用されています。
これは、微分関数∂/∂
がスカラー関数としてEgisonで定義されていることにより、可能になっています。
スカラー関数とは、スカラーに対して定義された関数で、引数としてテンソルが与えられた場合、テンソルの成分毎にその関数を自動で適用する関数です。
スカラー関数はEgisonによって新しく導入された関数の概念です。
スカラー関数を定義する際には、その引数としてスカラーのみを考えます。
つまり、この∂/∂
関数の定義の中で、引数がスカラーである場合の処理しかプログラマは記述する必要はありません。
それにもかかわらず、このスカラー関数という機構のおかげで、プログラム∂/∂ Γ~i_j_k x~l
は、4階のテンソルを返します。
スカラー関数に対して、テンソル関数という関数の概念があります。
テンソル関数は、引数としてテンソルが与えられた場合、引数のテンソルをテンソルとしてそのまま扱います。
スカラー関数として定義できない関数、例えば、行列式を計算する関数や、テンソル同士のかけ算を計算する関数を定義する際には、テンソル関数として定義します。
上記のプログラムにあらわれているテンソルのかけ算を計算するための関数.
は、テンソル関数としてEgisonで定義されています。
+
や-
、∂/∂
のようなスカラー関数と、.
のようなテンソル関数とを分類し、区別しているのが、この手法の肝です。
こうすることにより、任意の関数をテンソルに対して、特別な記述を必要とせずに適用できるようになります。
その結果、プログラミング全体にアインシュタインの縮約記法を含むテンソルの添字表記法を自然に導入できます。
スカラー仮引数とテンソル仮引数
前節の最後で述べたとおり、この手法のアイデアの核は、関数をスカラー関数とテンソル関数の2種類に分類し、区別するところにあります。 本節で解説するスカラー仮引数とテンソル仮引数は、ユーザーが定義した関数がどちらの種類の関数であるか指定するために用意された概念です。
Egisonでは、Schemeと同様lambda
構文を用いて関数を生成します。
その際、仮引数の先頭に$
、または%
を付加します。
$
が先頭に付加されている仮引数はスカラー仮引数となり、%
が先頭に付加された仮引数はテンソル仮引数となります。
スカラー仮引数は、引数としてテンソルが与えられた場合、テンソルの成分毎にその関数を適用します。
対して、テンソル仮引数は通常の仮引数と同様に、引数としてテンソルが与えられた場合、テンソルをテンソルとしてそのまま扱います。
スカラー関数の例として、min
関数の定義をします。
以下のプログラムはその定義です。
min
関数は、引数として数を2つ取り、そのうち小さい方の数を返す関数です。
min
関数は、以下のようにテンソルのことを意識することなく定義されます。
min
関数の仮引数は全てスカラー仮引数であり、$
が仮引数の先頭に付加されます。
$min
と関数名の前に$
が付いているが、これはEgisonの慣習でスカラー仮引数、テンソル仮引数とは関係ないので無視してよいです。
このmin
関数は、以下のように引数としてテンソルを扱うことができます。
これは、スカラー関数であるmin
関数の適用がテンソルの要素ごとに自動でマップされるためです。
テンソル関数の例として、テンソル同士のかけ算を計算する関数.
を定義します。
以下のプログラムはその定義です。
.
関数の仮引数は全てテンソル仮引数であり、%
が仮引数の先頭に付加されます。
添字を持ったテンソルが、テンソル関数の引数に与えられた場合、テンソルの添字を保持したままテンソルはテンソル関数に渡されます。
ここで、contract
構文は、上下に同じ添字がある場合に、縮約をおこなうための関数です。
contract
構文は、第1引数に縮約をおこなうための関数、第2引数に対象のテンソルを受け取ります。
以下のように.
関数を使って、ベクトルの内積、アダマール積、テンソル積が表現できます。
微分形式の表現
テンソルの添字が省略された場合の添字の補完のルールを上手に設計すると、ここまで説明してきた手法をそのまま使って、微分形式(共変テンソル)を扱う演算も簡潔に表現できるようになります。 本節ではこのことについて説明します。
一般に`n`階のテンソルに`k`個の添字がが付加されている場合、そのテンソルを`(n-k)`形式として扱うことにします。
例えば、3階のテンソルにω~i_j
と2つ添字が付加されていた場合は、そのテンソルを1形式として扱います。
同様のルールは数学でも使われています。
このルールに適合する省略された添字の補完のルールを考えてみましょう。
以下、例として、A
、B
はスカラーを値に持つ2形式とします。
以下のように、添字が省略された場合に、テンソルは微分形式として扱われます。 省略された添字については、以下のように同じ組み合わせの添字を自動的に補完します。
ほとんどの関数適用については、上記のように添字を補完すれば、微分形式の演算が表現できます。 ただし、ウェッジ積のような微分形式のための特別な演算の場合には、このような補完では適していないことがあります。 例えば、ウェッジ積の場合は、以下のように、引数のそれぞれに全て異なる添字を付加したいです。
そこで導入したのが、以下で使われている!
です。
!
が関数適用の前に付加されている場合は、後者の方法により、省略された添字を補完します。
!
を使う必要があるのは、ウェッジ積や外微分など微分形式のための特別な関数の定義の中だけです。
そのため、一般ユーザーは!
について意識する必要ありません。
実は、微分形式に対して、添字の付加のパターンは以上の2つで事足ります。 そして、後者のような添字の付加をしたいのは、微分形式のための特別な演算のみです。 よって、微分形式のための特別な関数のためにだけ、添字の補完方法を後者の補完方法に変更できるようにすればよいです。 その他の関数の場合は、デフォルトで前者の方法で、省略された添字を補完します。
このように、テンソルの添字が省略された場合の、添字の補完のルールを上手に設計することにより、微分形式の計算は表現できます。
外微分は以下のように実装できます。
ウェッジ積wedge
と外微分d
を使うと、以下のように曲率形式の公式を表現することが可能になります。
`Omega_j^i = d omega_j^i + omega_k^i ^^ omega_j^k`