Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Marketing Mix Modeling
- 프로그래머를 위한 선형대수 #선형대수 #LU분해
- 프로그래머를 위한 선형대수 #선형대수 #고유분해 #고윳값 #고유벡터
- Media Mix Modeling
- mmm
- bayesian
- 프로그래머를 위한 선형대수 #선형대수 #고유값 #고유벡터 #고유분해
- 수리통계
- 미적분
- 미적분 #접선의 방정식 #최적화 #뉴턴법 #뉴턴-랩슨법
- 미적분 #평균값 정리 #로피탈의 정리 #접선의 방정식
- lightweightmmm
- Optimization
- 프로그래머를 위한 선형대수 #선형대수 #고유값 #고유벡터 #야코비 회전법 #QR법 #하우스홀더반사 #행렬회전
- 미적분 #사인과 코사인의 도함수
- 프로그래머를 위한 선형대수 #선형대수 #행렬계산
- 시계열분석 #Time-Series Analysis #이상탐지 #Anomaly Detection #Spectral Residual #CNN #SR-CNN
- bayesian inference
Archives
- Today
- Total
문과생 네버랜드의 데이터 창고
2. 역행렬과 행렬식 본문
In [1]:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
In [9]:
# - 성질
print(np.identity(3))
print("행렬식 : ",np.linalg.det(np.identity(3)))
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
행렬식 : 1.0
- 성질1 : 단위행렬의 행렬식은 1이다.
In [16]:
A = np.matrix([[2,3],[4,1]])
B = np.matrix([[4,2],[3,1]])
print(np.linalg.det(np.dot(A,B)))
print(np.linalg.det(A) * np.linalg.det(B)) #행렬곱의 행렬식과, 각 행렬식의 곱은 동치이다. 물론, 알고리즘상 약간의 오차는 존재한다.
19.999999999999996
20.000000000000004
- 성질2 : det(AB) = det(A) * det(B)
In [19]:
A_1 = np.linalg.inv(A)
print(np.linalg.det(A_1))
print(1/np.linalg.det(A)) #역행렬의 행렬식은 해당 행렬의 행렬식의 역수와 같다. 물론, 알고리즘상 약간의 오차는 존재한다.
-0.10000000000000002
-0.09999999999999998
- 성질3 : det(A^-1) = 1/det(A)
In [80]:
print(" * 2열의 값을 10배 뻥튀기하여 1열에 결합")
print("")
A_1 = A[0] + 10*A[1]
A_2 = A[1]
print(np.vstack([A_1,A_2]))
print("")
print("행렬식 :",np.linalg.det(np.vstack([A_1,A_2])))
print("원래 행렬의 행렬식 : ",np.linalg.det(A))
* 2열의 값을 10배 뻥튀기하여 1열에 결합
[[42 13]
[ 4 1]]
행렬식 : -9.999999999999998
원래 행렬의 행렬식 : -10.000000000000002
- 성질 4 : 어떤 행/열벡터를 임의의 값으로 뻥튀기한 후, 다른 열에 더해도 행렬식은 변하지 않는다. 이 성질은 행연산의 근거가 된다.
In [79]:
print(" * 2열을 10배 뻥튀기")
print("")
A_1 = A[0]
A_2 = A[1] * 10
print(np.vstack([A_1,A_2]))
print("")
print("행렬식 : ", np.linalg.det(np.vstack([A_1,A_2])), ",원래 행렬식의 10배이다.")
print("")
print(" * 1,2열 모두 10배 뻥튀기")
print("")
A_1 = A[0] * 10
A_2 = A[1] * 10
print(np.vstack([A_1,A_2]))
print("행렬식 : ", np.linalg.det(np.vstack([A_1,A_2])),",원래 행렬식의 100배이다.")
* 2열을 10배 뻥튀기
[[ 2 3]
[40 10]]
행렬식 : -100.00000000000004 ,원래 행렬식의 10배이다.
* 1,2열 모두 10배 뻥튀기
[[20 30]
[40 10]]
행렬식 : -999.9999999999998 ,원래 행렬식의 100배이다.
- 성질5 : 임의의 갯수의 행/열에 상수배를 하는 경우, 그 임의의 갯수 n만큼 행렬식은 det^(n)으로 늘어난다. 즉, 기하급수적으로 늘어난다.
- 각 열이 독립적으로 행렬식에 영향을 미치는 것을 다중선형성이라고 한다.
In [84]:
print("* 1열과 2열의 순서를 바꾸기")
print("")
A_1 = A[1]
A_2 = A[0]
print(np.vstack([A_1,A_2]))
print("")
print("순서가 바뀐 행렬의 행렬식 :",np.linalg.det(np.vstack([A_1,A_2])))
print("원래 행렬의 행렬식: ",np.linalg.det(A))
print("")
* 1열과 2열의 순서를 바꾸기
[[4 1]
[2 3]]
순서가 바뀐 행렬의 행렬식 : 10.000000000000002
원래 행렬의 행렬식: -10.000000000000002
- 성질6 : 행/열이 교환되는경우, 행렬식의 부호가 바뀐다.
- 이는 '행렬식은 부피 변화율'이란 개념 하에 접근할 때, 부분공간의 기저가 뒤바뀌는(즉, 거꾸로 뒤집어지는) 모양을 상상하면 쉽게 이해할 수 있다.
(2) 행렬식의 계산¶
3) 역행렬¶
(1) 가우스 - 요르단 소거법¶
In [120]:
# - matrix와 상수만으로 이루어진 블록행렬 표기를 활용한다.
A = np.matrix([[2,3,3],[3,4,2],[-2,-2,3]]) #행렬 A
n = np.matrix([9,9,2]) #방정식의 상수 벡터
An = np.hstack([A,n.T])
print(An)
[[ 2 3 3 9]
[ 3 4 2 9]
[-2 -2 3 2]]
변형의 조건은 다음과 같다.¶
- 어느 행에 c배를 한다.
- 위에서 c배한 행으로 다른 행을 더하거나 뺀다.
- 행렬이 단위행렬이 되면 연산을 종료한다.
In [121]:
# phase 1 : 1행을 1/2배 한다.
A_1 = (1/2) * An[0]
A_2 = An[1]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 1.5 1.5 4.5]
[ 3. 4. 2. 9. ]
[-2. -2. 3. 2. ]]
In [122]:
# phase 2 : 1행을 3배하여 2행을 뺀다.
A_1 = An[0]
A_2 = An[1] - 3 * An[0]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 1.5 1.5 4.5]
[ 0. -0.5 -2.5 -4.5]
[-2. -2. 3. 2. ]]
In [123]:
# Phase 3 : 1행을 두배하여 3행에 더해준다.
A_1 = An[0]
A_2 = An[1]
A_3 = An[2] + 2 * An[0]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 1.5 1.5 4.5]
[ 0. -0.5 -2.5 -4.5]
[ 0. 1. 6. 11. ]]
In [124]:
# Phase 4 : 1행에 2행을 3배 하여 더해준다.
A_1 = An[0] + 3 * An[1]
A_2 = An[1]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. -6. -9. ]
[ 0. -0.5 -2.5 -4.5]
[ 0. 1. 6. 11. ]]
In [125]:
# Phase 5 : 2행을 두배하여 3행에 더해준다.
A_1 = An[0]
A_2 = An[1]
A_3 = An[2] + 2 * An[1]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. -6. -9. ]
[ 0. -0.5 -2.5 -4.5]
[ 0. 0. 1. 2. ]]
In [126]:
# Phase 6 : 2행에 -2를 곱한다.
A_1 = An[0]
A_2 = An[1] * (-2)
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. -6. -9.]
[ 0. 1. 5. 9.]
[ 0. 0. 1. 2.]]
In [127]:
# Phase 7 : 3행을 6배하여 1행에 더해준다.
A_1 = An[0] + 6*An[2]
A_2 = An[1]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[1. 0. 0. 3.]
[0. 1. 5. 9.]
[0. 0. 1. 2.]]
In [128]:
# Phase 8 : 3행을 5배하여 2행에서 빼준다.
A_1 = An[0]
A_2 = An[1] - 5*An[2]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. 0. 3.]
[ 0. 1. 0. -1.]
[ 0. 0. 1. 2.]]
행렬A는 3X3 단위행렬이 되었고, 이 때, 상수부는 [3,-1,2]이다. 이는 각각의 미지수 X1,X2,X3의 값과 같다.¶
(2) 가우스-요르단 소거법으로 역행렬 구하기¶
In [129]:
A = np.matrix([[2,3,3],[3,4,2],[-2,-2,3]]) #행렬 A
n = np.identity(3) #방정식의 상수 벡터
An = np.hstack([A,n.T])
print(An)
[[ 2. 3. 3. 1. 0. 0.]
[ 3. 4. 2. 0. 1. 0.]
[-2. -2. 3. 0. 0. 1.]]
변형의 조건은 다음과 같다.¶
- 어느 행에 c배를 한다.
- 위에서 c배한 행으로 다른 행을 더하거나 뺀다.
- 행렬이 단위행렬이 되면 연산을 종료한다.
In [130]:
# phase 1 : 1행을 1/2배 한다.
A_1 = (1/2) * An[0]
A_2 = An[1]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 1.5 1.5 0.5 0. 0. ]
[ 3. 4. 2. 0. 1. 0. ]
[-2. -2. 3. 0. 0. 1. ]]
In [131]:
# phase 2 : 1행을 3배하여 2행을 뺀다.
A_1 = An[0]
A_2 = An[1] - 3 * An[0]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 1.5 1.5 0.5 0. 0. ]
[ 0. -0.5 -2.5 -1.5 1. 0. ]
[-2. -2. 3. 0. 0. 1. ]]
In [132]:
# Phase 3 : 1행을 두배하여 3행에 더해준다.
A_1 = An[0]
A_2 = An[1]
A_3 = An[2] + 2 * An[0]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 1.5 1.5 0.5 0. 0. ]
[ 0. -0.5 -2.5 -1.5 1. 0. ]
[ 0. 1. 6. 1. 0. 1. ]]
In [133]:
# Phase 4 : 1행에 2행을 3배 하여 더해준다.
A_1 = An[0] + 3 * An[1]
A_2 = An[1]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. -6. -4. 3. 0. ]
[ 0. -0.5 -2.5 -1.5 1. 0. ]
[ 0. 1. 6. 1. 0. 1. ]]
In [134]:
# Phase 5 : 2행을 두배하여 3행에 더해준다.
A_1 = An[0]
A_2 = An[1]
A_3 = An[2] + 2 * An[1]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. -6. -4. 3. 0. ]
[ 0. -0.5 -2.5 -1.5 1. 0. ]
[ 0. 0. 1. -2. 2. 1. ]]
In [135]:
# Phase 6 : 2행에 -2를 곱한다.
A_1 = An[0]
A_2 = An[1] * (-2)
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. -6. -4. 3. 0.]
[ 0. 1. 5. 3. -2. 0.]
[ 0. 0. 1. -2. 2. 1.]]
In [136]:
# Phase 7 : 3행을 6배하여 1행에 더해준다.
A_1 = An[0] + 6*An[2]
A_2 = An[1]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. 0. -16. 15. 6.]
[ 0. 1. 5. 3. -2. 0.]
[ 0. 0. 1. -2. 2. 1.]]
In [137]:
# Phase 8 : 3행을 5배하여 2행에서 빼준다.
A_1 = An[0]
A_2 = An[1] - 5*An[2]
A_3 = An[2]
An = np.vstack([A_1,A_2,A_3])
print(An)
[[ 1. 0. 0. -16. 15. 6.]
[ 0. 1. 0. 13. -12. -5.]
[ 0. 0. 1. -2. 2. 1.]]
In [143]:
print("A행렬의 역행렬")
print("")
print(An.T[3:6].T)
A행렬의 역행렬
[[-16. 15. 6.]
[ 13. -12. -5.]
[ -2. 2. 1.]]
'선형대수' 카테고리의 다른 글
6. 고유공간과 고유분해 (0) | 2023.05.03 |
---|---|
5. LU 분해 (0) | 2023.05.03 |
4. 행렬의 연산 (0) | 2023.05.03 |
3. 차원과 부분공간 (0) | 2023.05.03 |
1. 벡터와 행렬 (0) | 2023.05.03 |