들어가며
행렬(Matrix)은 컴퓨터 공학과 프로그래밍에서 중요한 개념 중 하나입니다.
특히, 그래픽 처리, 데이터 분석, 머신러닝, 게임 개발 등 다양한 분야에서 사용되며, 코딩 테스트에서도 종종 출제됩니다.
2차원 배열로 표현할 수 있어, 행과 열을 순회하는 코드를 연습하기에도 좋습니다.
이 문서는 행렬의 기본 개념과 주요 연산에 대해 설명합니다. 처음 접하는 분들도 쉽게 이해할 수 있도록 최대한 직관적으로 설명하겠습니다.
기본 용어
행렬(matrix)은 숫자 또는 문자를 직사각형 형태로 배열한 것입니다.
가로줄을 행(row) , 세로줄을 열(column) 이라고 합니다.
예시:
[ 1 3 2 5 1 7 ] \begin{bmatrix}
1 & 3 & 2 \\
5 & 1 & 7
\end{bmatrix} [ 1 5 3 1 2 7 ]
위 행렬은 2 × 3 2 \times 3 2 × 3 행렬이라고 하며, 7 7 7 은 ( 2 , 3 ) (2,3) ( 2 , 3 ) 성분입니다.
행렬 표기
행렬은 일반적으로 다음과 같이 나타냅니다.
A = [ a 11 a 12 a 13 a 21 a 22 a 23 ] A = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \end{bmatrix} A = [ a 11 a 21 a 12 a 22 a 13 a 23 ]
각 성분은 a i j a_{ij} a ij 형태로 표기합니다.
[ 3 5 − 1 7 ] \begin{bmatrix} 3 & 5 \\ -1 & 7 \end{bmatrix} [ 3 − 1 5 7 ]
위 행렬은 2 × 2 2 \times 2 2 × 2 행렬 또는 2차 정사각 행렬(square matrix) 입니다.
행렬의 종류
전치 행렬 (Transpose Matrix)
전치 행렬(transpose matrix)은 원래 행렬의 행과 열을 바꾼 행렬입니다. 보통 A ⊤ A^{\top} A ⊤ 또는 A T A^T A T 로 표기합니다.
예시:
A = [ 1 2 4 5 3 7 ] ⇒ A T = [ 1 5 2 3 4 7 ] A = \begin{bmatrix} 1 & 2 & 4 \\ 5 & 3 & 7 \end{bmatrix} \Rightarrow A^T = \begin{bmatrix} 1 & 5 \\ 2 & 3 \\ 4 & 7 \end{bmatrix} A = [ 1 5 2 3 4 7 ] ⇒ A T = 1 2 4 5 3 7
전치 행렬은 열벡터를 행벡터로 표현하거나, 행과 열의 배치를 연산에 맞게 바꿀 때 사용합니다.
대칭 행렬 (Symmetric Matrix)
대칭 행렬은 전치 행렬과 자기 자신이 같을 때 성립합니다: A = A ⊤ A = A^{\top} A = A ⊤
A = [ 1 3 3 a ] ⇒ A T = [ 1 3 3 a ] A = \begin{bmatrix} 1 & 3 \\ 3 & a \end{bmatrix} \Rightarrow A^T = \begin{bmatrix} 1 & 3 \\ 3 & a \end{bmatrix} A = [ 1 3 3 a ] ⇒ A T = [ 1 3 3 a ]
대칭 행렬은 그래프 이론이나 공학에서 자주 사용되며, 물리학에서도 응력(stress)과 관련된 행렬로 활용됩니다.
대각 행렬 (Diagonal Matrix)
정사각 행렬 중 대각 성분이 아닌 모든 성분이 0 0 0 인 행렬을 대각 행렬(diagonal matrix) 이라고 합니다.
[ 1 0 0 0 0 0 0 0 3 ] \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 0 & 3 \end{bmatrix} 1 0 0 0 0 0 0 0 3
대각 성분은 0 0 0 이어도 상관없습니다.
대각 행렬은 항상 대칭 행렬입니다.
연산이 단순하여 컴퓨터 연산 속도를 빠르게 하기 위한 최적화된 구조로 사용됩니다.
단위 행렬 (Identity Matrix)
대각 성분만 1 1 1 이고 나머지는 0 0 0 인 행렬을 단위 행렬(identity matrix) 이라고 합니다. 단위 행렬 I I I 는 행렬 곱셈에서 곱셈 항등원의 역할을 합니다.
I = [ 1 0 0 1 ] , I = [ 1 0 0 0 1 0 0 0 1 ] I = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}, \quad I = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix} I = [ 1 0 0 1 ] , I = 1 0 0 0 1 0 0 0 1
단위 행렬은 행렬 곱셈에서 다음과 같은 항등원 역할을 합니다.
A ⋅ I n = I m ⋅ A = A ( A 는 m × n 행렬 ) A \cdot I_n = I_m \cdot A = A \quad (A \text{는 } m \times n \text{ 행렬}) A ⋅ I n = I m ⋅ A = A ( A 는 m × n 행렬 )
이는 일반적인 수에서 1 1 1 이 곱셈의 항등원 역할을 하는 것과 같은 개념입니다.
영행렬 (Zero Matrix)
모든 성분이 0 0 0 인 행렬을 영행렬(zero matrix) 이라고 합니다.
[ 0 0 0 0 ] , [ 0 0 0 0 0 0 0 0 0 ] \begin{bmatrix} 0 & 0 \\ 0 & 0 \end{bmatrix}, \quad \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix} [ 0 0 0 0 ] , 0 0 0 0 0 0 0 0 0
영행렬은 덧셈에서 항등원의 역할을 하며, 신호 처리나 선형 시스템에서 중요한 역할을 합니다.
행렬의 연산
행렬의 비교: A = B A = B A = B
두 행렬의 크기가 같고 같은 위치의 성분이 모두 같을 때 A = B A = B A = B 입니다.
[ 1 x 2 3 ] = [ 1 2 2 y ] \begin{bmatrix} 1 & x \\ 2 & 3 \end{bmatrix} = \begin{bmatrix} 1 & 2 \\ 2 & y \end{bmatrix} [ 1 2 x 3 ] = [ 1 2 2 y ]
이때, x = 2 , y = 3 x = 2, y = 3 x = 2 , y = 3 입니다.
행렬의 실수배 (Scalar Multiplication)
행렬의 모든 성분에 특정한 숫자(스칼라)를 곱하는 연산입니다. 아래 실수배와 덧셈·뺄셈 예제에서는 다음 두 행렬을 사용합니다.
A = [ 2 1 5 3 ] , B = [ − 1 4 1 2 ] A = \begin{bmatrix} 2 & 1 \\ 5 & 3 \end{bmatrix}, \quad B = \begin{bmatrix} -1 & 4 \\ 1 & 2 \end{bmatrix} A = [ 2 5 1 3 ] , B = [ − 1 1 4 2 ]
3 A = [ 6 3 15 9 ] 3A = \begin{bmatrix} 6 & 3 \\ 15 & 9 \end{bmatrix} 3 A = [ 6 15 3 9 ]
행렬의 덧셈 (Addition)과 뺄셈 (Subtraction)
같은 크기의 행렬끼리만 가능합니다.
A + B = [ 1 5 6 5 ] A + B = \begin{bmatrix} 1 & 5 \\ 6 & 5 \end{bmatrix} A + B = [ 1 6 5 5 ]
A − B = [ 3 − 3 4 1 ] A - B = \begin{bmatrix} 3 & -3 \\ 4 & 1 \end{bmatrix} A − B = [ 3 4 − 3 1 ]
행렬의 곱셈 (Matrix Multiplication)
행렬 곱셈은 일반적인 덧셈이나 뺄셈과 다릅니다. 같은 위치에 있는 성분끼리 연산하는 것이 아니라, 왼쪽 행렬의 행과 오른쪽 행렬의 열을 대응시켜 계산 합니다.
예제 1: 2 × 2 2 \times 2 2 × 2 행렬 곱셈
[ 1 2 3 4 ] × [ 5 6 7 8 ] \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} \times \begin{bmatrix} 5 & 6 \\ 7 & 8 \end{bmatrix} [ 1 3 2 4 ] × [ 5 7 6 8 ]
각 행과 열의 성분을 곱하고 합하여 새로운 행렬을 만듭니다.
= [ ( 1 ⋅ 5 + 2 ⋅ 7 ) ( 1 ⋅ 6 + 2 ⋅ 8 ) ( 3 ⋅ 5 + 4 ⋅ 7 ) ( 3 ⋅ 6 + 4 ⋅ 8 ) ] = \begin{bmatrix} (1 \cdot 5 + 2 \cdot 7) & (1 \cdot 6 + 2 \cdot 8) \\ (3 \cdot 5 + 4 \cdot 7) & (3 \cdot 6 + 4 \cdot 8) \end{bmatrix} = [ ( 1 ⋅ 5 + 2 ⋅ 7 ) ( 3 ⋅ 5 + 4 ⋅ 7 ) ( 1 ⋅ 6 + 2 ⋅ 8 ) ( 3 ⋅ 6 + 4 ⋅ 8 ) ]
= [ 19 22 43 50 ] = \begin{bmatrix} 19 & 22 \\ 43 & 50 \end{bmatrix} = [ 19 43 22 50 ]
위 연산에서 결과 행렬의 각 성분은 왼쪽 행렬의 행과 오른쪽 행렬의 열을 곱한 값들의 합 입니다.
예제 2: 2 × 2 2 \times 2 2 × 2 행렬과 2 × 1 2 \times 1 2 × 1 행렬의 곱셈
[ 1 2 3 4 ] × [ 5 6 ] \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} \times \begin{bmatrix} 5 \\ 6 \end{bmatrix} [ 1 3 2 4 ] × [ 5 6 ]
이 경우, 결과 행렬의 크기는 ( 2 × 1 ) (2 \times 1) ( 2 × 1 ) 이 됩니다.
= [ ( 1 ⋅ 5 + 2 ⋅ 6 ) ( 3 ⋅ 5 + 4 ⋅ 6 ) ] = \begin{bmatrix} (1 \cdot 5 + 2 \cdot 6) \\ (3 \cdot 5 + 4 \cdot 6) \end{bmatrix} = [ ( 1 ⋅ 5 + 2 ⋅ 6 ) ( 3 ⋅ 5 + 4 ⋅ 6 ) ]
= [ 17 39 ] = \begin{bmatrix} 17 \\ 39 \end{bmatrix} = [ 17 39 ]
예제 3: 2 × 3 2 \times 3 2 × 3 행렬과 3 × 2 3 \times 2 3 × 2 행렬의 곱셈
[ 4 − 2 1 0 2 3 ] × [ 0 − 3 − 2 1 1 4 ] \begin{bmatrix}
4&-2&1\\
0&2&3\\
\end{bmatrix}
\times
\begin{bmatrix}
0&-3\\
-2&1\\
1&4\\
\end{bmatrix} [ 4 0 − 2 2 1 3 ] × 0 − 2 1 − 3 1 4
= [ ( 4 ⋅ 0 + ( − 2 ) ⋅ ( − 2 ) + 1 ⋅ 1 ) ( 4 ⋅ ( − 3 ) + ( − 2 ) ⋅ 1 + 1 ⋅ 4 ) ( 0 ⋅ 0 + 2 ⋅ ( − 2 ) + 3 ⋅ 1 ) ( 0 ⋅ ( − 3 ) + 2 ⋅ 1 + 3 ⋅ 4 ) ] = \begin{bmatrix}
(4 \cdot 0+(-2) \cdot (-2)+1 \cdot 1) & (4 \cdot (-3)+(-2) \cdot 1+1 \cdot 4) \\
(0 \cdot 0+2 \cdot (-2)+3 \cdot 1) & (0 \cdot (-3)+2 \cdot 1+3 \cdot 4) \\
\end{bmatrix} = [ ( 4 ⋅ 0 + ( − 2 ) ⋅ ( − 2 ) + 1 ⋅ 1 ) ( 0 ⋅ 0 + 2 ⋅ ( − 2 ) + 3 ⋅ 1 ) ( 4 ⋅ ( − 3 ) + ( − 2 ) ⋅ 1 + 1 ⋅ 4 ) ( 0 ⋅ ( − 3 ) + 2 ⋅ 1 + 3 ⋅ 4 ) ]
= [ 5 − 10 − 1 14 ] = \begin{bmatrix}
5&-10\\
-1&14\\
\end{bmatrix} = [ 5 − 1 − 10 14 ]
설명:
첫 번째 행 과 첫 번째 열 을 곱한 값이 첫 번째 행 , 첫 번째 열 의 성분이 됩니다.
C 11 = A 11 ⋅ B 11 + A 12 ⋅ B 21 + A 13 ⋅ B 31 C_{11} = A_{11} \cdot B_{11} + A_{12} \cdot B_{21} + A_{13} \cdot B_{31} C 11 = A 11 ⋅ B 11 + A 12 ⋅ B 21 + A 13 ⋅ B 31
첫 번째 행 과 두 번째 열 을 곱한 값이 첫 번째 행 , 두 번째 열 의 성분이 됩니다.
C 12 = A 11 ⋅ B 12 + A 12 ⋅ B 22 + A 13 ⋅ B 32 C_{12} = A_{11} \cdot B_{12} + A_{12} \cdot B_{22} + A_{13} \cdot B_{32} C 12 = A 11 ⋅ B 12 + A 12 ⋅ B 22 + A 13 ⋅ B 32
두 번째 행 과 첫 번째 열 을 곱한 값이 두 번째 행 , 첫 번째 열 의 성분이 됩니다.
C 21 = A 21 ⋅ B 11 + A 22 ⋅ B 21 + A 23 ⋅ B 31 C_{21} = A_{21} \cdot B_{11} + A_{22} \cdot B_{21} + A_{23} \cdot B_{31} C 21 = A 21 ⋅ B 11 + A 22 ⋅ B 21 + A 23 ⋅ B 31
두 번째 행 과 두 번째 열 을 곱한 값이 두 번째 행 , 두 번째 열 의 성분이 됩니다.
C 22 = A 21 ⋅ B 12 + A 22 ⋅ B 22 + A 23 ⋅ B 32 C_{22} = A_{21} \cdot B_{12} + A_{22} \cdot B_{22} + A_{23} \cdot B_{32} C 22 = A 21 ⋅ B 12 + A 22 ⋅ B 22 + A 23 ⋅ B 32
이처럼 각 행과 열을 대응하여 곱하고 더하는 방식 으로 행렬의 곱셈을 수행합니다.
행렬 곱셈의 일반적인 규칙
행렬 곱셈이 성립하려면 왼쪽 행렬의 열 개수와 오른쪽 행렬의 행 개수가 같아야 합니다.
결과 행렬의 크기는 왼쪽 행렬의 행 개수 × 오른쪽 행렬의 열 개수 가 됩니다.
즉, 다음과 같은 수식을 만족해야 합니다.
A ( m × n ) × B ( n × r ) = C ( m × r ) A (m \times n) \times B (n \times r) = C (m \times r) A ( m × n ) × B ( n × r ) = C ( m × r )
위 개념을 잘 이해하면, 프로그래밍에서 행렬 연산을 다룰 때 매우 유용 하게 활용할 수 있습니다.
코딩테스트: 행렬의 곱셈
행렬의 곱셈은 코딩 테스트에서 자주 출제되는 문제 유형 중 하나입니다. 특히 2차원 배열을 다루는 능력, 중첩 반복문을 활용한 연산 최적화, 그리고 행렬 곱셈의 기본 개념을 평가하는 데 사용됩니다.
문제
2차원 행렬 A A A 와 B B B 를 입력받아 행렬 A A A 에 행렬 B B B 를 곱한 결과를 반환하는 solution() 함수를 완성하세요.
제약조건
행렬 A A A , B B B 의 행과 열의 길이는 2 이상 100 이하입니다.
행렬 A A A , B B B 의 데이터는 -10 이상 20 이하인 정수입니다.
문제 풀이 (JavaScript)
function solution ( A , B ) { const m = A . length ; const n = A [ 0 ] . length ; const p = B [ 0 ] . length ; if ( n !== B . length ) throw new Error ( "행렬의 곱이 성립되지 않음" ) ; const C = Array . from ( { length : m } , ( ) => new Array ( p ) . fill ( 0 ) ) ; for ( let i = 0 ; i < m ; i ++ ) { for ( let j = 0 ; j < p ; j ++ ) { for ( let k = 0 ; k < n ; k ++ ) { C [ i ] [ j ] += A [ i ] [ k ] * B [ k ] [ j ] ; } } } return C ; }
코드 설명
m , n , p m, n, p m , n , p 는 각각 A A A 의 행 개수, A A A 의 열 개수 (B B B 의 행 개수), B B B 의 열 개수를 나타냄.
n !== B.length 조건을 검사하여 행렬 곱셈이 가능한지 확인.
C C C 는 결과 행렬이며, m × p m \times p m × p 크기의 배열을 0 0 0 으로 초기화.
3중 for문을 이용하여 행렬 곱셈 수행:
i는 A A A 의 행 인덱스.
j는 B B B 의 열 인덱스.
k는 A A A 의 열과 B B B 의 행을 연결하는 인덱스.
C[i][j] += A[i][k] * B[k][j]를 통해 행렬 원소를 누적하여 계산.
최종적으로 C C C 를 반환.