[Python] Matrix (행렬, 선형대수학)
※ Matrix (행렬)
■ 행렬의 덧셈
# 직접 정의하기
def add(A, B):
n = len(A)
p = len(A[0])
result = []
for i in range(0, n):
row = []
for j in range(0, p):
val = A[i][j] + B[i][j]
row.append(val)
result.append(row)
return result
A = [[1, 2], [3, 4], [5, 6]]
B = [[7, 8], [9, 10], [11, 12]]
print(add(A, B))
[[8, 10], [12, 14], [16, 18]]
# numpy 사용
import numpy as np
A = np.array([[1, 2], [3, 4], [5, 6]])
B = np.array([[7, 8], [9, 10], [11, 12]])
print(A+B)
[[ 8 10]
[12 14]
[16 18]]
■ 행렬의 뺄셈
# 직접 정의하기
def subtract(A, B):
n = len(A)
p = len(A[0])
result = []
for i in range(0, n):
row = []
for j in range(0, p):
val = A[i][j] - B[i][j]
row.append(val)
result.append(row)
return result
A = [[1, 2], [8, 1], [3, 9]]
B = [[7, 2], [9, 4], [11, 12]]
print(subtract(A, B))
[[-6, 0], [-1, -3], [-8, -3]]
# numpy 사용
import numpy as np
A = np.array([[1, 2], [8, 1], [3, 9]])
B = np.array([[7, 2], [9, 4], [11, 12]])
print(A-B)
[[-6 0]
[-1 -3]
[-8 -3]]
■ 행렬의 스칼라 곱
# 직접 정의하기
def scalr_mat_mul(x, A):
n = len(A)
p = len(A[0])
result = []
for i in range(0, n):
row = []
for j in range(0, p):
val = x * A[i][j]
row.append(val)
result.append(row)
return result
x = 7
A = [[1, 2], [8, 1], [3, 9]]
print(scalr_mat_mul(x, A))
[[7, 14], [56, 7], [21, 63]]
# numpy 사용
import numpy as np
x = 7
A = np.array([[1, 2], [8, 1], [3, 9]])
print(x*A)
[[ 7 14]
[56 7]
[21 63]]
■ 행렬의 원소곱
# 직접 정의하기
def ele_product(A, B):
n = len(A)
p = len(A[0])
result = []
for i in range(0, n):
row = []
for j in range(0, p):
val = A[i][j] * B[i][j]
row.append(val)
result.append(row)
return result
A = [[1, 2], [8, 1], [3, 9]]
B = [[7, 2], [9, 4], [11, 12]]
print(ele_product(A, B))
[[7, 4], [72, 4], [33, 108]]
# numpy 사용
import numpy as np
A = np.array([[1, 2], [8, 1], [3, 9]])
B = np.array([[7, 2], [9, 4], [11, 12]])
print(np.multiply(A, B))
[[ 7 4]
[ 72 4]
[ 33 108]]
■ 행렬의 곱
# 직접 정의하기
def matmul(A, B):
n = len(A)
p1 = len(A[0])
p2 = len(B[0])
result = []
for i in range(0, n):
row = []
for j in range(0, p2):
value = 0
for k in range(0, p1):
value = value + A[i][k] * B[k][j]
row.append(value)
result.append(row)
return result
A = [[1, 2], [8, 1], [3, 9]]
B = [[7, 3, 5], [9, 2, 4]]
print(matmul(A, B))
[[25, 7, 13], [65, 26, 44], [102, 27, 51]]
# numpy 사용
import numpy as np
A = np.array([[1, 2], [8, 1], [3, 9]])
B = np.array([[7, 3, 5], [9, 2, 4]])
print(np.matmul(A, B))
[[ 25 7 13]
[ 65 26 44]
[102 27 51]]
■ 전치 행렬
# 직접 정의하기
def transpose(A):
n = len(A)
p = len(A[0])
At = []
for i in range(0, p):
row = []
for j in range(0, n):
value = A[j][i]
row.append(value)
At.append(row)
return At
A = [[1, 5], [3, 4], [6, 2]]
print(transpose(A))
[[1, 3, 6], [5, 4, 2]]
# numpy 사용
import numpy as np
A = [[1, 5], [3, 4], [6, 2]]
At = np.transpose(A)
print(At)
[[1 3 6]
[5 4 2]]
■ 대각 행렬
□ 대각 원소 추출하기
# 직접 정의하기
def diag(A):
n = len(A)
D = []
for i in range(0, n):
value = A[i][i]
D.append(value)
return D
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(diag(A))
[1, 5, 9]
# numpy 사용
import numpy as np
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
D = np.diag(A)
print(D)
[1 5 9]
□ 대각 원소를 대각 행렬로 변환하기
# 직접 정의하기
def ele2diag(v):
n = len(v)
diag_A = []
for i in range(0, n):
row = []
for j in range(0, n):
if i == j:
value = v[i]
row.append(value)
else:
row.append(0)
diag_A.append(row)
return diag_A
v = [1,2,3]
print(ele2diag(v))
[[1, 0, 0], [0, 2, 0], [0, 0, 3]]
# numpy 사용
import numpy as np
v = [1,2,3]
print(np.diag(v))
[[1 0 0]
[0 2 0]
[0 0 3]]
■ 단위 행렬
# 직접 정의하기
def identity(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
n = 3
print(identity(n))
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
# numpy 사용
import numpy as np
n = 3
print(np.eye(n)) # np.identity(n)
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
■ 영 행렬
# 직접 정의하기
def zero(n, p):
Z = []
for i in range(0, n):
row = []
for j in range(0, p):
row.append(0)
Z.append(row)
return Z
n = 3
p = 2
print(zero(n, p))
[[0, 0], [0, 0], [0, 0]]
# numpy 사용
import numpy as np
n = 3
p = 2
print(np.zeros((n, p)))
[[0. 0.]
[0. 0.]
[0. 0.]]
■ 삼각 행렬
□ Upper Triangular Matrix
# 직접 정의하기
def u_tri(A):
n = len(A)
utri_mat = []
for i in range(0, n):
row = []
for j in range(0, n):
if i>j:
row.append(0)
else:
row.append(A[i][j])
utri_mat.append(row)
return utri_mat
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
u_tri(A)
[[1, 2, 3], [0, 5, 6], [0, 0, 9]]
# numpy 사용
import numpy as np
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(np.triu(A))
[[1 2 3]
[0 5 6]
[0 0 9]]
□ Lower Triangular Matrix
# 직접 정의하기
def l_tri(A):
n = len(A)
ltri_mat = []
for i in range(0, n):
row = []
for j in range(0, n):
if i<j:
row.append(0)
else:
row.append(A[i][j])
ltri_mat.append(row)
return ltri_mat
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(l_tri(A))
[[1, 0, 0], [4, 5, 0], [7, 8, 9]]
# numpy 사용
import numpy as np
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(np.tril(A))
[[1 0 0]
[4 5 0]
[7 8 9]]
■ 토플리츠 행렬
# 직접 정의하기
def toeplitz(u, v):
n1 = len(u)
n2 = len(v)
toeplitz_mat = []
for i in range(0, n1):
row = []
for j in range(0, n2):
if i >= j:
row.append(u[i-j])
else:
row.append(v[j-i])
toeplitz_mat.append(row)
return toeplitz_mat
u = [1, 2, 3, 4]
v = [11, 12, 13, 14, 15]
print(toeplitz(u, v))
[[1, 12, 13, 14, 15], [2, 1, 12, 13, 14], [3, 2, 1, 12, 13], [4, 3, 2, 1, 12]]
# scipy 사용
from scipy.linalg import toeplitz
A = toeplitz([1, 2, 3, 4], [11, 12, 13, 14, 15])
print(A)
[[ 1 12 13 14 15]
[ 2 1 12 13 14]
[ 3 2 1 12 13]
[ 4 3 2 1 12]]
■ Bidiagonal Matrix (이중 대각 행렬)
□ Upper Bidiagonal Matrix
# 직접 정의하기
def u_bidiagonal_mat(A):
n = len(A)
u_bidiag_mat = []
for i in range(0, n):
row = []
for j in range(0, n):
if (i>j) or (j-i>1):
row.append(0)
else:
row.append(A[i][j])
u_bidiag_mat.append(row)
return u_bidiag_mat
A = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
print(u_bidiagonal_mat(A))
[[1, 2, 0, 0], [0, 6, 7, 0], [0, 0, 11, 12], [0, 0, 0, 16]]
# numpy 활용
A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
diag_ele = np.diag(A)
upper_diag_ele = np.diag(A, k = 1)
upper_bidiagonal_mat = np.diag(diag_ele) + np.diag(upper_diag_ele, k = 1)
print(upper_bidiagonal_mat)
[[ 1 2 0 0]
[ 0 6 7 0]
[ 0 0 11 12]
[ 0 0 0 16]]
□ Lower Bidiagonal Matrix
# Lower Bidiagonal Matrix
# 직접 정의하기
def l_bidiagonal_mat(A):
n = len(A)
l_bidiag_mat = []
for i in range(0, n):
row = []
for j in range(0, n):
if (i<j) or (i-j>1):
row.append(0)
else:
row.append(A[i][j])
l_bidiag_mat.append(row)
return l_bidiag_mat
A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
print(l_bidiagonal_mat(A))
[[1, 0, 0, 0], [5, 6, 0, 0], [0, 10, 11, 0], [0, 0, 15, 16]]
# numpy 활용
A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
diag_ele = np.diag(A)
lower_diag_ele = np.diag(A, k = -1)
lower_bidiagonal_mat = np.diag(diag_ele) + np.diag(lower_diag_ele, k = -1)
print(lower_bidiagonal_mat)
[[ 1 0 0 0]
[ 5 6 0 0]
[ 0 10 11 0]
[ 0 0 15 16]]
■ Householder Transformation
# numpy 활용
import numpy as np
v = np.array([1, 2, 3, 4])
n = len(v)
outer_mat = np.outer(v, v)
inner_mat = np.inner(v, v)
I = np.eye(n)
H = I - 2 * outer_mat / inner_mat
print(H)
[[ 0.93 -0.13 -0.20 -0.26]
[-0.13 0.73 -0.40 -0.53]
[-0.20 -0.40 0.40 -0.80]
[-0.26 -0.53 -0.80 -0.06]]
■ Determinant (행렬식)
# numpy 활용
import numpy as np
> A = np.array = [[3, 2, 0], [-1, -3, 6], [2, 3, -5]]
> detA = np.linalg.det(A)
> print(detA) # 5.000000000000001
■ Inverse Matrix (역행렬)
# numpy 활용
> import numpy as np
> A = np.array = [[3, 2, 0], [-1, -3, 6], [2, 3, -5]]
> invA = np.linalg.inv(A)
> print(invA)
[[-0.6 2. 2.4]
[ 1.4 -3. -3.6]
[ 0.6 -1. -1.4]]
================================================
self-connecting edges
> A = np.array([[0,1,1,1],
[1,0,0,5],
[1,0,0,1],
[1,0,1,0]])
> A + np.eye(4)
array([[1., 1., 1., 1.],
[1., 1., 0., 5.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])
degree matrix
> D = np.array(A.sum(axis=1)).flatten()
> D = np.diag(D)
> D
array([[3, 0, 0, 0],
[0, 6, 0, 0],
[0, 0, 2, 0],
[0, 0, 0, 2]])
댓글남기기