<Eigendecomposition>
1. Install Packages
2. Geometry of Eigendecomposition
3. Eigendecomposition
Install Packages
# visualization을 위한 helper code입니다.
from urllib.request import urlretrieve
URL = 'https://go.gwu.edu/engcomp4plot'
urlretrieve(URL, 'plot_helper.py')
import sys
sys.path.append('../scripts/')
# 다음 세 custom function (1)plot_vector, (2)plot_linear_transformation, (3) plot_linear_transformations
# 을 사용할 것입니다.
from plot_helper import *
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import scipy as sp
import scipy.linalg
import sympy as sy
sy.init_printing()
np.set_printoptions(precision=3)
np.set_printoptions(suppress=True)
Geometry of Eigendecomposition
Eigenvectors of A = [[2, 1], [1, 2]]
Matrix A에 의한 vector i, j의 linear transformation 결과
A = np.array([[2,1], [1,2]])
print(A)
plot_linear_transformation(A)

(1, 0), (0, 1) 외에 다른 vector들 linear transformation
# 길이(norm)가 1인 vector들
alpha = np.linspace(0, 2*np.pi, 41) # x축과의 각도 (0~2pi)
vectors = list(zip(np.cos(alpha), np.sin(alpha)))
vectors = np.array(vectors)
newvectors = A @ vectors.T
newvectors = newvectors.T
plot_vector(vectors) # plot_vector는 주어진 vector들을 plot하는 custom function 입니다.

plot_vector(newvectors)

→ Matrix A는 원을 타원으로 만드는 linear transformation
위 타원의 semi major axis(장축의 절반), semi minor axis(단축의 절반)
= transform 된 newvectors의 길이가 가장 길고 짧은 두 vector
lengths = np.linalg.norm(newvectors, axis=1) # newvectos 각각의 norm
semi_major_index = np.argmax(lengths) # norm이 가장 긴 것이 타원의 장축
semi_major_vector = newvectors[semi_major_index]
semi_major_length = lengths[semi_major_index]
print(semi_major_vector) # 장축 vector
print(semi_major_length)

→ 장축은 y = x 위에 있는 vector, 즉 x축과 45도를 이루는 vector
semi_minor_index = np.argmin(lengths) # norm이 가장 짧은 것이 타원의 장축
semi_minor_vector = newvectors[semi_minor_index]
semi_minor_length = lengths[semi_minor_index]
print(semi_minor_vector) # 단축 vector
print(semi_minor_length)

→ 단축은 y = -x 위에 있는 vector, 즉 x축과 -45도를 이루는 vector
두 vector (2.121, 2.121), (-0.707, 0.707)의 원래 vector 구현
A_inv = np.linalg.inv(A)
v1 = A_inv @ semi_major_vector
v2 = A_inv @ semi_minor_vector
print(v1) # v1 -> A -> 장축
print(v2) # v2 -> A -> 단축

- v1과 semi major vector / v2와 semi minor vector는 각각 방향이 같다.
(v1과 semi major vector는 y=x, v2와 semi minor vector는 y=-x 위에 존재)
- Av1 = 3v1 / Av2 = 1v2
- A는 원을 타원으로 바꾸는 Matrix
- 이때, 타원의 장축, 단축이 각각 eigenvector가 된다.
→ A가 Symmetric Matrix 이기 때문에 성립
Scaling과 Rotation으로 A 만들기
plot_vector(vectors)

plot_vector(newvectors)

A로 만들어진 타원(newvectors)은 scaling과 rotation의 조합으로 만들 수 있어 보인다.
반지름인 1인 원(vectors)을 가로로 3배 늘린 다음, 시계 반대방향으로 45도 회전한다면?
가로로 3배 scaling
S = np.array([[3, 0], [0, 1]]) # 가로로 3배 scaling 하는 2x2 matrix
ellipse = (S @ vectors.T).T # S에 의해서 늘려진 vector들.
plot_vector(ellipse)

반시계 방향으로 45도 회전
theta = np.pi/4
R = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
rotated_ellipse = (R @ ellipse.T).T
plot_vector(rotated_ellipse)

- S와 R의 linear transformation으로 생성된 조합은 A와 비슷해 보이지만 사실 다르다.
→ vector의 방향이 바뀌었기 때문
v1의 실제 변환 과정
v1 = -v1 # eigenvector에 non-zero 상수를 곱하면 여전히 eigenvector이기 때문에, -1을 곱해줍니다 (좌표를 양수로 만들기 위해)
print(v1)
scaled_v1 = (S @ v1.T).T
rotated_scaled_v1 = (R @ scaled_v1.T).T
plot_vector([v1, rotated_scaled_v1])
print(rotated_scaled_v1)

→ v1이 크기뿐 아니라 방향마저 바뀌었다.
∴ A ≠ RS
A의 Eigendecomposion
rotation과 scaling의 조합으로 A를 만드는 방법
- rotation을 시계방향으로 45도 회전
- 이를 scaling
- 다시 반시계 방향으로 45도 회전
theta_list = [np.pi/8, np.pi/4, np.pi/2, np.pi]
for theta in theta_list:
R = np.array([[numpy.cos(theta), -numpy.sin(theta)], # 반시계방향으로 45도 회전하는 matrix
[numpy.sin(theta), numpy.cos(theta)]])
print(R)
R_inv = np.linalg.inv(R)
print(R_inv)
print()

[[cos 𝜽, sin 𝜽], [-sin 𝜽, cos 𝜽]] = R^T
(∵ rotation = orthogonal Matrix)

for theta in theta_list:
R = np.array([[numpy.cos(theta), -numpy.sin(theta)], # 반시계방향으로 45도 회전하는 matrix
[numpy.sin(theta), numpy.cos(theta)]])
R_inv = np.linalg.inv(R)
print(R.T)
print(R_inv)
print()

rotation과 scaling을 조합한 Matrix A
theta = np.pi/4
R = np.array([[np.cos(theta), -np.sin(theta)], # 반시계방향으로 theta만큼 회전하는 matrix
[np.sin(theta), np.cos(theta)]])
plot_linear_transformation(R @ S @ R.T)

v1, v2

visualize R^T (시계방향으로 45도 회전)
plot_linear_transformation(R.T, v1, v2)

visualize S (scaling)
rotated_v1 = R.T @ v1
rotated_v2 = R.T @ v2
scaled_rotated_v1 = S @ rotated_v1
scaled_rotated_v2 = S @ rotated_v2
plot_linear_transformation(S, rotated_v1, rotated_v2)

visualize R (반시계 방향으로 45도 회전)
rotated_scaled_rotated_v1 = R@scaled_rotated_v1
rotated_scaled_rotated_v2 = R@scaled_rotated_v2
plot_linear_transformation(R, scaled_rotated_v1, scaled_rotated_v2)
print(rotated_scaled_rotated_v1, rotated_scaled_rotated_v2)

v1 → 3v1 / v2 → v2가 된다.
결론적으로,

→ rotate(-𝜽)는 eigenvector v1, v2를 one-hot vector로 변환
Eigendecomposition
Symmetric Matrix

- n x n Symmetric Matrix의 경우 항상 n개의 Orthogonal 한 Eigenvector를 가질 수 있다.
F = np.random.rand(5,5)
F_symmetric = F + F.T # A + A^T는 항상 symmetric입니다.
F_symmetric

eigenvalues, eigenvectors = np.linalg.eig(F_symmetric)
eigenvectors

from itertools import combinations
for i,j in combinations(range(5), 2):
print(eigenvectors[:,i] @ eigenvectors[:,j])
# 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
모든 Eigenvector의 dot product가 0이 된다.
∴ Symmetric Matrix로부터 n개의 Orthogonal Eigenvector를 얻을 수 있다.
Eigendecomposition
Eigendecomposition 유도

위 두 식을 matrix의 곱 형태로 표현

[s1v1, s2v2]는 다음과 같이 표현이 가능

V를 Eigenvector를 column으로 갖는 matrix(v1, v2)라고 하고, [[s1, 0], [0, s2]]를 D라고 하면 결론적으로,
AV = VD를 유도할 수 있다.
V의 역행렬이 존재할 시,

와 같은 형태로 A가 decompose 될 수 있으면, A를 diagonalizable이라고 한다.
V를 change of basis로 볼 시, VDV^-1의 의미
- V^-1: standard basis ({i, j})에서 eigenbasis ({v1, v2})로 basis를 change
- D = [[s1, 0], [0, s2]]: v1 방향의 성분 (eigenbasis에서의 좌표의 첫 번째 성분)에 s1을 곱해주고, v2 방향의 성분 (eigenbasis에서 좌표의 두 번째 성분)에 s2를 곱해준 다음, (i.e. elementwise scaling)
- 다시 standard basis로 되돌리는 행위

→ 어떤 두 matrix가 같은 linear transformation을 나타내는데 basis만 다른 경우에, 두 matrix는 similar 한 관계에 있다.
non-Symmetric Matrix인 B = [[1, 0], [1, 3]]의 Eigendecomposition을 visualize
B = np.array([[1,0], [1,3]])
plot_eigen(B)

eigenvalues, eigenvectors = np.linalg.eig(B)
eigenvalues

eigenvectors

- 갈색, 파란색 vector는 basis를 나타내고, 왼쪽 위의 빨간색 원은 길이가 1인 vector들의 set
(x는 빨간색 원 위의 vector 하나하나를 표현)
- V를 c라고 하고, v1, v2를 a, b라고 할 시(V = C, v1 = a, v2 = b), C^-1x는 standard basis에서 eigenbasis로 바꾸는 행위
→ basis i, j는 a, b로 변환, 빨간색 원은 바뀌지 않는다.
(∵ change of basis는 vector를 고정시킨 채 축만 바꾸기 때문에)
- DC^-1x는 DC^-1x의 basis를 다시 standard basis로 되돌리는 행위
→ 마찬가지로 change of basis는 vector를 고정시킨 채 축만 바꾸기 때문에 빨간색 원은 바뀌지 않고, basis만 a, b는 i, j로 변환
Eigendecomposition은 Computational Advantage를 비롯해, 다양한 application에 사용된다.
'Mathematics > Linear Algebra' 카테고리의 다른 글
| Advanced Eigendecomposition 2 (0) | 2022.05.13 |
|---|---|
| Advanced Eigendecomposition (0) | 2022.05.12 |
| Gram-Schmidt orthonormalization & QR decomposition (0) | 2022.05.09 |
| Determinant, Least Square (0) | 2022.05.04 |
| Basis, Span, Change of Basis (0) | 2022.05.03 |