Summary

행렬의 고유값(eigenvalue)을 계산하는 방법은 여러가지가 있다. 그 중에 하나가 유사행렬(Similar matrix)을 이용한 고유값이고, 여기에는 QR 분해가 이용된다.

A = QR 분해가 된다고 하자. A의 QR 분해결과물인 Q와 R을 역순으로 놓고 이것을 A1 이라고 한다. 그리고 A1 을 다시 QR 분해를 한다.

여기서 한 가지 포인트는 A0와 A1 이 유사행렬이라는 것이다. Q0 = A0 R0-1 이고, A1 = R0 Q0 에서 대입하면, A1 = R0 A0 R0-1 이 되니까, 유사행렬이 된다.

그리고 유사행렬은 고유값이 동일하다. 즉, A0, A1 은 같은 고유값을 가진다.

이 단계를 몇번 하다보면, An 행렬의 대각선 아래는 거의 0에 가까운 작은 숫자들이 된다. 즉, 상삼각행렬에 가깝게 되고, 행렬의 대각선에 위치하는 값들이 A 행렬의 고유값이 된다.

행렬 A 에 대한 고유값 확인

이제 R code로 확인해보자. 임의의 행렬 A 가 있고, 고유값을 확인하면 10, 5 임을 알 수가 있다.

# 임의의 행렬 A 가 있다.
A <- matrix(c(8, 3, 2, 7), nrow = 2, byrow = T)
A
##      [,1] [,2]
## [1,]    8    3
## [2,]    2    7
# 고유값을 확인해본다.
eigen(A)
## eigen() decomposition
## $values
## [1] 10  5
## 
## $vectors
##           [,1]       [,2]
## [1,] 0.8320503 -0.7071068
## [2,] 0.5547002  0.7071068

QR 분해 예제

이제, QR 분해 예제를 보자.

# qr 분해를 한다.
temp <- qr(A)

# Q, R 행렬을 구한다.
Q <- qr.Q(temp)
R <- qr.R(temp)

Q
##            [,1]       [,2]
## [1,] -0.9701425 -0.2425356
## [2,] -0.2425356  0.9701425
R
##           [,1]      [,2]
## [1,] -8.246211 -4.608177
## [2,]  0.000000  6.063391
# Q*R 이 원래 행렬을 구성함을 확인한다.
Q %*% R
##      [,1] [,2]
## [1,]    8    3
## [2,]    2    7

QR 분해를 이용한 고유값 계산

이제는 QR 분해를 이용해서 고유값을 구해보자.

# step 1: QR 분해를 하고, A 가 구해지는지 check 한다.
temp <- qr(A)
Q0 <- qr.Q(temp)
R0 <- qr.R(temp)

A0 <- Q0 %*% R0
A0
##      [,1] [,2]
## [1,]    8    3
## [2,]    2    7
# step 2: A1을 구하고, 대각선의 값이 고유값 10, 5에 근접한지 check한다.
A1 <- R0 %*% Q0
A1
##           [,1]      [,2]
## [1,]  9.117647 -2.470588
## [2,] -1.470588  5.882353
temp <- qr(A1)
Q1 <- qr.Q(temp)
R1 <- qr.R(temp)

# step 3: A2을 구하고, 대각선의 값이 고유값 10, 5에 근접한지 check한다.
A2 <- R1 %*% Q1
A2
##          [,1]     [,2]
## [1,] 9.655172 1.862069
## [2,] 0.862069 5.344828
temp <- qr(A2)
Q2 <- qr.Q(temp)
R2 <- qr.R(temp)

# step 4: A3을 구하고, 대각선의 값이 고유값 10, 5에 근접한지 check한다.
A3 <- R2 %*% Q2
A3
##            [,1]      [,2]
## [1,]  9.8623853 -1.458716
## [2,] -0.4587156  5.137615

행렬 A3 의 대각선을 보면, 10, 5에 가까운 숫자로 변함을 보게 된다. 이 단계를 몇번하면, 고유값을 구하게 된다.

Updated: 2020-10-07

위의 변환과정을 함수로 구현한다.

# 정사각행렬 A 와 반복횟수를 입력하면 해당 반복 이후의 A 행렬을 구한다.
my_qr <- function(A, iteration = 5) 
{
  for(i in 1:iteration)
  {
    temp <- qr(A)
    Q <- qr.Q(temp)
    R <- qr.R(temp)
    
    A <- R %*% Q
  }
  return(A)
}

# A 를 QR 법으로 50회 실행하고 대각선에 고유값이 나타나는지? 하삼각 부분은 0에 가깝게 구성되는지 확인한다.
B <- my_qr(A, 50)
B
##              [,1] [,2]
## [1,] 1.000000e+01    1
## [2,] 3.416071e-15    5