본문 바로가기
  • 조금 느려도, 꾸준히
Python/Numpy

Numpy 모듈을 활용한 행렬의 대각화 [시행착오(1)]

by chan 2019. 11. 26.
반응형

이번 글에서는 Numpy모듈을 이용하여 행렬의 고윳값을 구한 후 그로 파생된 닮은 행렬을 이용하여 원래 행렬을 다시 구해보는 과정과, 그 과정에서 필자가 저지른 실수에 대해 다뤄보려 한다.

 

import numpy as np

pycharm 가상환경에서 numpy모듈을 불러온다.

 

불러온 numpy모듈로 임의의 3*3 행렬 x를 만들어 보자

 

x = np.array([[1, 2, 3],
              [2, 3, 4],
              [2, 3, 1]])
              

 

numpy에서 세부적인 선형대수적 연산을 위해 제공하는 linalg모듈 (linear algebra: 선형대수) 을

이용하여 간단하게 고윳값과 고유벡터를 구할 수 있다.

 

xw, xv = np.linalg.eig(x)

 

이때 xw는 행렬 x의 고윳값, xv 는 행렬 x의 고유벡터를 열로 갖는 배열이다.

 

print('xw :',xw)
print() #가독성 위한 공백
print('xv :',xv)
--> 
xw : [ 7.15502799 -0.21626442 -1.93876357]

xv : [[-0.47946378 -0.82291798 -0.49434482]
      [-0.71737964  0.56645335 -0.41737969]
      [-0.50545123 -0.04400695  0.76250731]]
      
      

 

이때 대각화 가능한 행렬 A에 대하여

$$A = PDP^{-1}$$ (P 는 A의 고유벡터를 열로갖는 행렬, D는 고윳값을 대각성분으로 갖는 행렬)

가 성립하므로, 행렬 xv의 역행렬을 추가적으로 구해야 한다.

 

우리의 numpy 는 역행렬을 구하는 아주 편리한 기능 역시 제공하고 있다. inv() 모듈로서 구현 가능하다.

 

xv_inverse = np.linalg.inv(x)

 

이렇게 xv의 역행렬 xv_inverse 를 구해내었다.

 

이때 필자는 성급한 마음에 xv, xw, xv_inverse를 그냥 행렬곱해 버렸는데, 결과는 다음과 같았다.

 

print(np.matmul(xv,xw,xv_inverse))
-->
[[-2.29419113 -4.44617455 -5.08532195]
 [ 2.         -1.66666667  0.66666667]
 [-0.          0.33333333 -0.33333333]]
 
 

 기존의 x 행렬과는 전혀 다른 행렬이 도출되었다. 

 

위 식을 다시 보자.

 

$$A = PDP^{-1}$$

우변의 가운데에 자리하고 있는 행렬 D. 이 행렬의 포맷을 보자.

 

$$\left[\begin{array}{rrr}

\lambda_{1}&0&0 \\

0&\lambda_{2}&0 \\

0&0&\lambda_{3}

\end{array}\right]$$

 

대각성분을 각각 A의 고윳값들로 갖는 대각행렬이다.

 

그러나 필자가 행렬곱의 파라미터로 넘겨준 xw 는 

$$\left[\begin{array}{rrr} \lambda_{1} & \lambda_{2} & \lambda_{3} \end{array}\right]$$

이러한 꼴이다. 고로 당연히 원하는 결과를 얻지 못했다. 

 

따라서 오류를 수정하는 과정을 거쳐야 했다. diag() 모듈로 대각행렬을 생성한다.

xw_diag = np.diag([xw[0], xw[1], xw[2]])
-->
[[ 7.15502799  0.          0.        ]
 [ 0.         -0.21626442  0.        ]
 [ 0.          0.         -1.93876357]]
 
 

이로서 대각행렬까지 구했다. 

다시 행렬곱 연산을 수행한다.

print(np.matmul(xv, xw_diag, xv_inverse))
-->
[[-3.43057674  0.17796788  0.95841773]
 [-5.13287138 -0.1225037   0.80920053]
 [-3.61651769  0.00951714 -1.47832139]]
 

오우, 오히려 더 뚱단지 같은 결과값이 도출되었다.

 

우선 체크해볼 것이 있다.

1. 기존 고윳값과 고유벡터를 도출하는 과정에 있어서 오류 유무

2. 행렬 X 의 대각화 가능 여부

3. 코드상의 문제가 아닌 프로그램 연산 상의 오류 유무

 

위 3가지 것들을 우선적으로 확인하고, 재검토가 필요하다.

 

 

반응형

'Python > Numpy' 카테고리의 다른 글

Python Numpy - 넘파이 기본과 예제  (0) 2020.01.25

댓글