👩‍💻LEARN : ML&Data/Book Study

[알고리즘 구현으로 배우는 선형대수] #3. 다양한 행렬

쟈니유 2023. 4. 7. 21:18
728x90

 

그동안 텐서플로우, 코세라 머신러닝, 알고리즘과 자료구조 등을 먼저 했다..계획했던 커리큘럼 사이에 껴서

원래 계획이 약 2주간 미뤄졌따 ...🫥 오늘도..달려야한다...

 


#3. 다양한 행렬

 

전치행렬(transposed matrix)

개념 및 성질

  • 정의 : 기존 행렬의 행과 열을 바꾼 행렬 
    • uij →uji가 된다 

  • 성질 
    • (At)t = A 
    • (A+-B)t = At+-Bt
    • (a*A)t = aAt
    • (AB)t = BtAt 

파이썬 실습

A =[[1,5],[3,4],[6,2]]

def transpose(A):
  n = len(A)       #행 row
  p = len(A[0])    #열 column

  At=[]
  for i in range(0,p):   #행에 대한 반복 : 전치행렬에서는 행열 위치가 바뀌기 때문에 기존 열의 수인 p 만큼 반복  
    row=[]
    for j in range(0,n): #열에 대한 반복 
      val = A[j][i]      #A의 j행i열 설정 
      row.append(val)
    At.append(row)
  return At 

transpose(A)
#결과 : [[1, 3, 6], [5, 4, 2]]

라이브러리 활용 

import numpy as np

A = np.array([[1,5],[3,4],[6,2]])
At = np.transpose(A)           
#간단하겐 아래처럼도 가능
A.T

 

대칭행렬(symmetric matrix)

개념 및 성질

  • 정의 : 기존 행렬과 전치 행렬이 동일한 정사각 행렬을 의미. 행-열번호를 바꿔도 똑같음  (A = At)

  • 성질 
    • 대칭 행렬간 덧셈, 뺄셈,제곱 시 모두 결과는 대칭행렬
    • 곱셈은 반드시 대칭이지 않음 
    • 일반 행렬에 해당 행렬의 전치행렬 At를 곱하면 그 결과는 반드시 대칭행렬이 됨 (A*At=At*A=대칭) 

대각행렬(diagonal matrix)

개념 및 성질

  • 정의 : 주 대각 원소가 아닌 원소들이 모두 0 인 정사각 행렬 
    • 대각 행렬의 역행렬 (D -1) : 각 대각원소자리에 대각원소의 역수로 대체 
  • 성질 :
    • 대각행렬 거듭 제곱 시 각 대각원소를 제곱시키면 됨 
    • 일반 행렬 A에 대각행렬 D를 곱할때
      • AD : 기존 행렬의 열 값이 대각원소의 배수가 됨
      • DA : 기존 행렬의 행 값이 대각원소의 배수가 됨 

파이썬 실습

#대각행렬화 함수 

def diag(A):
  n = len(A)
  D = []
  for i in range(0,n):      #행에대한 반복 
    row = []
    for j in range(0,n):    #열에대한 반복
      if i==j:              #행열 번호가 동일하다면(대각원소라면)
        row.append(A[i][j]) #해당 대각원소를 row에 넣어라 
      else:
        row.append(0)
    D.append(row)
  return D 

A =[[1,2,3],[4,5,6],[7,8,9]]
diag(A)
#[[1, 0, 0], [0, 5, 0], [0, 0, 9]]

#주어진 행렬의 대각화 시, 대각원소 추출

def diag_ele(A):
  n = len(A)
  d = []
  for i in range(0,n):
    d.append(A[i][i])
  return d 

#대각원소가 주어졌을 때, 대각행렬 생성

def ele2diag(a):
  n = len(a)
  D = []
  for i in range(0,n):
    row = []
    for j in range(0,n):
      if i ==j:
        row.append(a[i])
      else:
        row.append(0)
    D.append(row)
  return D

라이브러리 실습

import numpy as np

A = np.array([[1,2,3],[4,5,6],[7,8,9]])
#A의 대각원소 구하기 
D = np.diag(A)        #결과값 : [1,5,9]

#대각원소들로 대각행렬만들기
np.diag(D)

단위행렬(identity matrix) 

개념 및 성질

  • 정의 : 주 대각 원소들이 모두 1이고 나머지 원소는 모두 0 인 대각 행렬 (=항등행렬) 
  • 성질 
    • 행렬 A에 I를 곱하면 곱하는 위치와 관계 없이 모두 자기자신 행렬 A가 나옴 

파이썬 실습 & 라이브러리 실습

#파이썬으로 단위행렬 만들기 

def identify(n) : #n*n의 단위행렬 
  I = []
  for i in range(0,n):
    row =[]
    for j in range(0,n):
      if i==j:
        row.append(1)
      else :
        row.append(0)
    I.append(row)
  return I 

#numpy로 단위행렬 만들기 
I = np.identity(5)

영행렬(zero matrix)

개념 및 성질

  • 정의 : 행렬의 모든 구성 원소가 0인 행렬

파이썬 실습&라이브러리 실습

#영행렬 만들기 

def zero_mat(n,p) : n*p영행렬 만들기 
  Z = []

  for i in range(0,n):
    row = []
    for j in range(0,p):
      row.append(0)
    Z.append(row)
  return Z 

#numpy 활용 
Z = np.zeros((n,p))

삼각행렬

개념 및 성질

  • 정의 : 행렬의 주 대각 원소 위 or 아래가 0의 모양이 되어 삼각형 모양의 행렬이 된 것 
    • 0이 아닌 값이 위에 있으면 상 삼각, 아래에 있으면 하 삼각 
  • 성질
    • 삼각행렬간 덧셈, 뺄셈, 행렬곱의 결과는 삼각행렬
    • 상삼각행렬의 전치는 하삼각, 하삼각행렬의 전치는 상삼각행렬
    • 삼각행렬의 역행렬 또한 삼각행렬 

파이썬 실습&라이브러리 실습

#상삼각 만들기
def u_tri(A):
  n = len(A)
  p = len(A[0])
  utri = []

  for i in range(0,n):
    row=[]
    for j in range(0,p):
      if i>j:                    #하삼각일 경우 i<j로만 변경하면 됨 
        row.append(0)
      else:
        row.append(A[i][j])
    utri.append(row)

  return utri

#넘파이로 삼각 만들기 
np.triu(A)   #상삼각
np.tril(A)   #하삼각

토플리츠행렬

개념 및 성질

요렇게 생간 애...

  • 1행의 원소들이 다음 행으로 갈 수록 한칸씩 오른쪽으로 이동, 앞의 빈 자리는 새로운 원소들이 메꾸는 형태 
  • 토플리츠 행렬 T의 i행j열 원소는 다음과 같이 정의할 수 있음(t:원소)
    • Tij = Ti+1,j+1=ti-j 
  • 시계열 분석 시 자주 사용됨 

 

파이썬 실습 & 라이브러리 실습

a = [1,0,-2,-4]
b = [1,3,5,7,9]

#파이썬 버전 
def toeplitz(a,b):
  n1 = len(a)
  n2 = len(b)
  A = []
  for i in range(0,n1):
    row = []
    for j in range(0,n2):
      if i > j:              #행의 번호가 열의 번호보다 크다면 
        row.append(a[i-j])   #리스트a의 i-j번째 원소를 추가해라>새로 추가되는 애 
      else:                  #행의 번호가 열의 번호와 같거나 작다면
        row.append(b[j-i])   #리스트b의 J-i번째 원소를 추가해라 
    A.append(row)
  return A 

#scipy 버전 
from scipy.linalg import toeplitz
A = toeplitz(a,b)

#출력결과
[[ 1  3  5  7  9]
 [ 0  1  3  5  7]
 [-2  0  1  3  5]
 [-4 -2  0  1  3]]

이중대각행렬(bidiagonal matrix)

개념 및 성질

정의 : 대각 원소 뿐 아니라 대각 원소의 바로 위 혹은 아래쪽 원소가 0 이 아닌 행렬 

파이썬 실습

#upper bidiagonal 

def u_bidiag(A):
  n = len(A)
  p = len(A[0])

  res =[]
  for i in range(0,n):
    row=[]
    for j in range(0,p):
      if i>j or j-i>1 :     #0이 되는 경우는 행>열이거나 열-행 차이가 1보다 큰 경우 
        row.append(0)
      else:
        row.append(A[i][j])
    res.append(row)
  return res 

#lower bidiagonal

def l_bidiag(A):
  n = len(A)
  p = len(A[0])

  res =[]
  for i in range(0,n):
    row=[]
    for j in range(0,p):
      if i<j or i-j>1 :     #0이 되는 경우는 행<열이거나 행-열 차이가 1보다 큰 경우 
        row.append(0)
      else:
        row.append(A[i][j])
    res.append(row)
  return res

라이브러리 실습

import numpy as np

#1.행렬A의 대각원소를 구함
diag_ele = np.diag(A)

#2.대각원소 바탕으로 대각 행렬 구하기
np.diag(diag_ele) 

#3.대각원소보다 위쪽에 있는 원소 추출하기 
u_diag_ele = np.diag(A,k=1)    #대각원소 1쪽 위에 있는 원소를 추출 (-1 하면 아래쪽 원소 가능)

#4.위쪽 원소들 넣은 버전의 행렬 만들기
np.diag(u_diag_ele,k=1)

#5. 두개 합치기 
u_diag = np.diag(diag_ele)  + np.diag(u_diag_ele,k=1)

하우스홀더행렬

개념 및 성질

  • 정의 : 어떤 행렬을 다른 형태로 변환할 때 사용하는 행렬 중 하나 (정사각 행렬)로 다음과 같은 수식을 따르는 행렬 H를 의미함 
    • v*vt : 외적→ n*n의 행렬로 도출됨 , vt*v : 내적 → 스칼라  

  • 성질
    • 모든 열이 정규 직교(orthomal)

파이썬 실습

..은 너무 길어서 우선 패스 

라이브러리 실습

import numpy as np 

v = np.array([1,0,2,3])
n = len(v)

#외적 구하기
outermat = np.outer(v,v)
#내적 구하기
inner_val = np.inner(v,v)
#n차원 단위 행렬 세팅
I = np.identity(n)

#수식 진행
H = I - (2/innerval)*outer_mat