四元数を行列で計算すれば内積や外積の「内」と「外」が視覚的に分かることに気付いたのでメモします。最後に行列を生成する簡単なプログラムを掲載します。
【注】歴史的な由来は未確認です。
シリーズの記事です。
- 多項式の積を計算
- 外積と愉快な仲間たち
- ユークリッド空間のホッジ双対とバブルソート
- 四元数を作ろう
- 四元数と行列で見る内積と外積の「内」と「外」 ← この記事
- 八元数を作ろう
- 八元数の積をプログラムで確認
- 外積の成分をプログラムで確認
- 多元数の積の構成
- 十六元数を作ろう
関連するコードをまとめたリポジトリです。
この記事には関連記事があります。
- 2017.12.04 八元数と7次元の外積 ← お勧め
- 2017.03.06 実ベクトルで考える複素ベクトル
四元数
複素数 $a+bi$ を二元数と捉えた場合、虚数の種類を増やして $a+bi+cj+dk$ としたのが四元数です。
$i, j, k$ はそれぞれ別の虚数で、以下の関係があります。
i^2=j^2=k^2=ijk=-1 \\
ij=-ji=k,\ jk=-kj=i,\ ki=-ik=j
※ 詳細は四元数を作ろうを参照してください。
行列による乗積表
$i,j,k$ の積は乗積表として表形式にまとめられますが、ここでは行列で示します。
\begin{align}
\left(\begin{matrix} i \\ j \\ k \end{matrix}\right)
\left(\begin{matrix} i & j & k \end{matrix}\right)
&=\left(\begin{matrix} ii & ij & ik \\ ji & jj & jk \\ ki & kj & kk \end{matrix}\right) \\
&=\left(\begin{matrix} -1 & k & -j \\ -k & -1 & i \\ j & -i & -1 \end{matrix}\right)
\end{align}
※ この種のベクトル計算を直積と呼びます。詳細は外積と愉快な仲間たちを参照してください。
3次元ベクトル
虚数 $i,j,k$ を3次元ベクトル空間の基底だと考えれば、四元数の虚部 $ai+bj+ck$ は3次元ベクトルだと見なせます。
ai+bj+ck\mapsto\left(\begin{matrix} a \\ b \\ c \end{matrix}\right)
※ 実部は無視します。
内積と外積
2本のベクトルを四元数で表して掛け算します。
\begin{align}
&(ai+bj+ck)(di+ej+fk) \\
&=ai(di+ej+fk) \\
&\quad +bi(di+ej+fk) \\
&\quad +cj(di+ej+fk) \\
&=ad\underbrace{ii}_{-1}+ae\underbrace{ij}_{k}+af\underbrace{ik}_{-j} \\
&\quad +bd\underbrace{ji}_{-k}+be\underbrace{jj}_{-1}+bf\underbrace{jk}_{i} \\
&\quad +cd\underbrace{ki}_{j}+ce\underbrace{kj}_{-i}+cf\underbrace{kk}_{-1} \\
&=-\underbrace{(ad+be+cf)}_{内積} \\
&\quad +\underbrace{(bf-ce)i+(cd-af)j+(ae-bd)k}_{外積}
\end{align}
実部が内積のマイナス、虚部が外積となります。
\begin{align}
内積 &\left(\begin{matrix}a\\b\\c\end{matrix}\right)\cdot\left(\begin{matrix}d\\e\\f\end{matrix}\right)=ad+be+cf \\
外積 &\left(\begin{matrix}a\\b\\c\end{matrix}\right)×\left(\begin{matrix}d\\e\\f\end{matrix}\right)=\left(\begin{matrix}bf-ce\\cd-af\\ae-bd\end{matrix}\right)
\end{align}
※ 内積がマイナスになっている点については、四元数が先にあって内積の概念が確立されたため、初期の内積は四元数と同じ符号で扱われていたそうです。符号にマイナスが付かないように修正したクリフォード代数というものがあります。詳細は外積と愉快な仲間たちを参照してください。
ここまではよくある説明です。
行列で計算
同じ計算を行列の二次形式でやってみます。
\begin{align}
&(ai+bj+ck)(di+ej+fk) \\
&=\left(\begin{matrix} i & j & k \end{matrix}\right)
\left(\begin{matrix} a \\ b \\ c \end{matrix}\right)
\left(\begin{matrix} d & e & f \end{matrix}\right)
\left(\begin{matrix} i \\ j \\ k \end{matrix}\right) \\
&=\left(\begin{matrix} i & j & k \end{matrix}\right)
\left(\begin{matrix} ad & ae & af \\ bd & be & bf \\ cd & ce & cf \end{matrix}\right)
\left(\begin{matrix} i \\ j \\ k \end{matrix}\right) \\
&=-(ad+be+cf) \\
&\quad +(bf-ce)i+(cd-af)j+(ae-bd)k
\end{align}
ここで3行目中央の行列に注目します。
\left(\begin{matrix}
\underbrace{ad}_{内} & \underbrace{ae}_{外} & \underbrace{af}_{外} \\
\underbrace{bd}_{外} & \underbrace{be}_{内} & \underbrace{bf}_{外} \\
\underbrace{cd}_{外} & \underbrace{ce}_{外} & \underbrace{cf}_{内}
\end{matrix}\right)
内側が内積で、外側が外積の成分です!
プログラム
行列を記述するのは大変なので、プログラムで生成してみました。(リポジトリ)
open System
let matrix m =
printfn @"\left(\begin{matrix}"
m |> Seq.map (String.concat " & ")
|> String.concat (@" \\" + Environment.NewLine)
|> printfn "%s"
printfn @"\end{matrix}\right)"
let v = [["a"]; ["b"]; ["c"]]
let w = [["d" ; "e" ; "f"]]
matrix v
matrix w
printfn "="
v
|> Seq.mapi (fun i r ->
w.[0] |> Seq.mapi (fun j c ->
if i = j then "内" else "外"
|> sprintf @"\underbrace{%s%s}_{%s}" r.[0] c))
|> matrix
\left(\begin{matrix}
a \\
b \\
c
\end{matrix}\right)
\left(\begin{matrix}
d & e & f
\end{matrix}\right)
=
\left(\begin{matrix}
\underbrace{ad}_{内} & \underbrace{ae}_{外} & \underbrace{af}_{外} \\
\underbrace{bd}_{外} & \underbrace{be}_{内} & \underbrace{bf}_{外} \\
\underbrace{cd}_{外} & \underbrace{ce}_{外} & \underbrace{cf}_{内}
\end{matrix}\right)