그램-슈미트 직교화
정리
모든 유한차원 내적공간은 정규직교기저를 갖는다.
설명
존재성 증명이라는 게 대개 그렇듯 길지도 않고 별것도 아닌것 같아보이지만 엄청나게 중요한 정리다. 선형대수학을 지탱하는 수많은 논리가 바로 이 정규직교기저가 존재한다는데에 의존하고 있기 때문이다.
증명
내적공간 $(V, \left\langle \cdot , \cdot \right\rangle)$ 을 생성하는 기저 중 하나를 $\left\{ \mathbf{x}_{1} , \cdots , \mathbf{x}_{n} \right\}$ 이라고 잡자. 새로운 벡터
$$ \mathbf{v}_{1} := {{ \mathbf{x}_{1} } \over { \left\| \mathbf{x}_{1} \right\| }} $$
와
$$ {\color{blue} \mathbf{v}_{2}} := {{ {\color{red} \mathbf{x}_{2} - ( \mathbf{x}_{2} \cdot \mathbf{v}_{1} ) \mathbf{v}_{1} } } \over { \left\| \mathbf{x}_{2} - ( \mathbf{x}_{2} \cdot \mathbf{v}_{1} ) \mathbf{v}_{1} \right\| }} = {{ \mathbf{x}_{2} - \text{Proj} ( \mathbf{x}_{1} ) } \over { \left\| \mathbf{x}_{2} - \text{Proj} ( \mathbf{x}_{1} ) \right\| }} $$
을 정의하자.
그림에서 나타낸 바와 같이 $\mathbf{v}_{1} \perp \mathbf{v}_{2}$ 가 성립한다. 위와 같은 프로세스는
$$ \mathbf{v}_{k} := {{ \mathbf{x}_{k} - \text{Proj} ( \mathbf{x}_{k-1} ) } \over { \left\| \mathbf{x}_{k} - \text{Proj} ( \mathbf{x}_{k-1} ) \right\| }} $$ 에 대해서 반복할 수 있으므로, 직교기저 $\left\{ \mathbf{v}_{1} , \cdots , \mathbf{v}_{n} \right\}$ 을 찾을 수 있다. 정의에 따라 $\mathbf{v}_{1} , \cdots , \mathbf{v}_{n}$ 들은 모두 그 크기가 $1$ 이므로 $\left\{ \mathbf{v}_{1} , \cdots , \mathbf{v}_{n} \right\}$ 는 정규직교벡터다.
■
사실 정규화는 그저 크기가 1이 되도록 놈을 나눠주면 그만이고, 핵심적인 것은 사영을 이용해 직교벡터를 찾는 것이다.
코드
그램-슈미트 직교화 정리의 증명은 그 자체로 알고리즘이나 마찬가지다. 실제로 주어진 랜덤행렬 X
에 대해 정규직교화를 거친 행렬 V
는 각 행벡터간의 내적이 $0$ 이고 크기가 $1$ 이라는 것을 확인할 수 있다.
julia> X = randn(3, 3)
3×3 Matrix{Float64}:
0.0582107 0.414695 0.730785
-0.740409 -0.885193 0.302674
1.25107 0.840262 0.176503
julia> V = gram_schmidt(X)
3×3 Matrix{Float64}:
0.0400097 0.739513 0.671952
-0.508902 -0.563652 0.650626
0.859894 -0.367989 0.353788
julia> V[1,:]'V[2,:], V[1,:]'V[3,:], V[2,:]'V[3,:]
(0.0, -8.326672684688674e-17, 1.1102230246251565e-16)
julia> norm(V[1,:]), norm(V[2,:]), norm(V[3,:])
(1.0, 0.9999999999999999, 1.0)
다음은 그램-슈미트 직교정규화를 행렬에서 수행하는 줄리아 코드다.
using LinearAlgebra
function gram_schmidt(A)
U = deepcopy(A)
for i in axes(A, 1)
for j in 1:(i-1)
U[:, i] -= (U[:, i]'U[:, j])*U[:, j]/norm(U[:, j])
end
U[:, i] /= norm(U[:, i])
end
return U
end
X = randn(3, 3)
V = gram_schmidt(X)
V[1,:]'V[2,:], V[1,:]'V[3,:], V[2,:]'V[3,:]
norm(V[1,:]), norm(V[2,:]), norm(V[3,:])
랴푸노프 스펙트럼
랴푸노프 스펙트럼을 계산할 땐 다음과 같이 정규직교 행렬 U
와 함께 유닛 볼의 축이 얼마나 바뀌는지를 측정하는 그냥 직교 행렬 V
를 동시에 계산하는 함수가 필요하다.
- 구체적인 사용례는 선형 시스템의 랴푸노프 스펙트럼 포스트 등에서 확인할 수 있다.
using LinearAlgebra
function gram_schmidt(J)
N = size(J, 1)
U, V = deepcopy(J), deepcopy(J)
U[:,1] = V[:,1] / norm(V[:,1])
for j in 2:N
for jp in 1:(j-1)
V[:,j] -= (J[:,j]'U[:,jp])*U[:,jp]
end
U[:,j] = V[:,j] / norm(V[:,j])
end
return U, V
end