『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

完全正規直交系と直交行列

≪【前の記事】正射影ベクトルと射影行列

【Python線形代数】完全正規直交系と直交行列

完全正規直交系

ベクトル空間を張るベクトルの集合を基底とよびました。基底であるための条件は「互いに線形独立である」、「空間を張るメンバーが不足していない」の 2 つでしたが、さらに「互いに直交する」、「メンバーが単位ベクトルである」という2つの条件を付け加えた基底を 完全正規直交系(正規直交基底) とよびます。英語では complete orthonormal system と記述するので、その頭文字をとって CONS と表されることもあります。
 
たとえば以下の 3 組のベクトルは R3 を張る基底で、互いに直交しています。
 (1)a1=[110],a2=[110],a3=[001]
det(a1,a2,a3)0 なので、メンバーは互いに線形独立です。行列式の計算が面倒な人は Python のコードで確認してください:

# python_complete_orthonormal_system

# In[1]

import numpy as np
from scipy.linalg import det

# 配列を定義
X = np.array([[1, -1, 0],
              [1,  1, 0],
              [0,  0, 1]])

# 行列式を計算
print(det(X))

# 2

メンバー同士で互いに内積をとると 0 となります:
 (2)a1Ta2=0a2Ta3=0a3Ta1=0
メンバー自身の内積を計算してみると、
 (3)a1Ta1=2,a2Ta2=2,a3Ta3=1
となるので、a1a2 の大きさは 2a3 の大きさは 1 であることがわかります。a1a2 をそれぞれ 2 で割ると、すべてのメンバーの大きさを 1 に揃えることができます。
 (4)q1=12[110],q2=12[110],q3=[001]
{q1, q2, q3}完全正規直交系 (正規直交基底) です。
 
完全正規直交系であることは、クロネッカーのデルタ記号 δij を使って次のように表せます。
 (5)qiTqj=δij={0(ij)1(i=j)
すなわち、各メンバーが自分同士で内積をとる場合は 1 となり、他のメンバーとの間で内積を計算した場合は 0 となります。

直交行列

{q1, q2, q3} のメンバーを横に並べて行列をつくってみます。
 (6)Q=[q1q2q3]=[1212012120001]
QTQQQT を計算すると単位行列となります:

# In[2]

x = np.sqrt(2)/2

# 直交行列
Q = np.array([[ x, x, 0],
              [-x, x, 0],
              [ 0, 0, 1]])

print(Q.T @ Q)
print(Q @ Q.T)

# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

このように、正規直交基底のベクトルで構成される行列を直交行列とよび、次のように計算してみると常に QTQ=I が成り立つことがわかります。
 (7)QTQ=[q1Tq2Tq3T][q1q2q3]=[q1Tq1q1Tq2q1Tq3q2Tq1q2Tq2q2Tq3q3Tq1q3Tq2q3Tq3]
qiqj=δij より、対角成分だけが残るので
 (8)QTQ=[100010001]=I
となります。一般に Rn を張る基底のメンバー数は n なので、直交行列 Q は正方行列であり、QTQ=I が成り立つことから、QTQ の転置行列であると同時に逆行列であることもわかります。したがって、QQT=I も成り立ちます。

正規直交系

完全正規直交系の「完全」とは「基底であること」を意味しています。この条件を外した「互いに直交しつつ、各々の長さが 1 であるけれど、空間を張るメンバーが揃っているとは限らない」ベクトル集合を正規直交系とよびます。細かいことですが、メンバーが揃っていても揃っていなくても正規直交系です。つまり、完全正規直交系は正規直交系の部分集合です。揃っていないことを明示する場合は「不完全直交系」とよびます。

不完全直交系のベクトルで構成される行列 Q は矩形行列となり、QTQ=I は成り立ちますが、QQT=I は成立しません。つまり、QTQ の逆行列ではありません (このような行列を「左逆行列」とよぶこともあります)。たとえば、基底 (4) から q2 を外して、行列 Q を以下のように定義します。
 (9)Q=[q1q3]=[12012001]
このとき、QTQ は単位行列ですが、QQT は単位行列とはなりません:

# In[3]

x = np.sqrt(2)/2

# 不完全直交行列
Q = np.array([[x, 0],
              [x, 0],
              [0, 1]])

print(Q.T @ Q)
print(Q @ Q.T)

# [[1. 0.]
#  [0. 1.]]

# [[0.5 0.5 0. ]
#  [0.5 0.5 0. ]
#  [0.  0.  1. ]]

このように、系が不完全であれば行列演算の簡潔性の一部が失われることになります。とはいえ、完全であろうと不完全であろうと、QTQ=I が成り立つので、直交行列 Q による線形変換はベクトルの内積を保持します:
 (10)(Qx)T(Qy)=xTQTQy=xTIy=xTy
y=x であるときは、Qx∥=∥x が成り立ちます (直交行列によるノルム不変性)。
 
≫【次の記事】グラムシュミットの直交化法
≫ Pythonで学ぶ線形代数トップページ

コメント