グラム・シュミットの直交化法
前回記事では完全正規直交系の定義と性質について解説しました。今回は
直交化の手順
この基底を使って完全正規直交系
最初に基底から適当なベクトルを 1 つ選んで
選び方は自由ですが、とりあえず
自身の大きさで割って ノルム を
次に
これも
次は
をつくって
さらに次元の大きな空間の場合も同様にして、
によって順次
Pythonで直交化法を実装する
グラム・シュミットの直交化法を使って、基底を直交化するコードです。
# python_gram_schmidt_orthonormalization
# In[1]
import numpy as np
from scipy import linalg
# グラム・シュミット直交化関数
def schmidt(arr):
# 配列のデータ型を64バイト浮動小数点数型に変換
arr = np.array(arr, dtype=np.float64)
# 渡した配列の列数(基底に含まれるベクトル数)
k = arr.shape[1]
# 1列目のベクトルを選択
u = arr[:,[0]]
# uを正規化
q = u / linalg.norm(u)
# シュミットの直交化
for j in range(1, k):
u = arr[:,[j]]
for i in range(j):
u -= np.dot(q[:,i], arr[:,j]) * q[:,[i]]
qi = u / linalg.norm(u)
q = np.append(q, qi, axis=1)
return q
schmidt() に適当な基底を渡して完全正規直交系をつくってみます。
# In[2]
A = np.array([[3, 1, 1],
[1, 0, 1],
[2, 5, 0]])
Q = schmidt(A)
print(Q)
# [[ 0.80178373 -0.47847438 -0.35805744]
# [ 0.26726124 -0.24880668 0.93094934]
# [ 0.53452248 0.8421149 0.07161149]]
出力結果が完全正規直交系の性質を満たしているか確認しておきましょう。各々のベクトルは互いに直交します。たとえば、
# In[3]
print(Q[:, 0] @ Q[:, 1])
# -5.551115123125783e-17
前回学んだように、直交行列
# In[4]
# ベクトルvを定義
v = np.array([[1],
[2],
[3]])
# Qvを計算
Qv = np.dot(Q, v)
# vとQvのノルム(大きさ)
v_norm = linalg.norm(v)
Qv_norm = linalg.norm(Qv)
print(v_norm)
print(Qv_norm)
# 3.7416573867739413
# 3.7416573867739418
コメント
下記は誤植と思われますので、ご確認ください。
(3) 式の下の文章で、||u1|| で割って → ||u2||で割って
In[3]のプログラムで、print(x[:, 0] @ x[:, 1]) → print(Q[:, 0] @ Q[:, 1])
訂正しました。
いつもありがとうございます。