Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

정방행렬을 대칭 행렬과 반대칭 행렬의 합으로 분해하는 방법

선형대수학에서 임의의 정방행렬(square matrix)은 항상 하나의 대칭 행렬(symmetric matrix)과 하나의 반대칭 행렬(skew-symmetric matrix)의 합으로 유일하게 분해할 수 있습니다. 이 글에서는 두 행렬의 정의, 분해 공식의 원리, 그리고 C++ 구현 예제까지 차근차근 살펴보겠습니다.

대칭 행렬(Symmetric Matrix)

전치 행렬(transpose)이 원래 행렬 자신과 같은 행렬을 대칭 행렬이라고 합니다.

AT = A

즉, (i, j) 위치의 성분과 (j, i) 위치의 성분이 항상 같다는 의미입니다.

반대칭 행렬(Skew-symmetric Matrix)

전치 행렬이 원래 행렬의 음수와 같은 행렬을 반대칭 행렬이라고 합니다.

AT = −A

이 성질 때문에 반대칭 행렬의 주대각선 성분은 모두 0이 됩니다.

정방행렬의 분해 공식

정방행렬 A에 대해 다음 항등식이 항상 성립합니다.

A = ½ × (A + AT) + ½ × (A − AT)

여기서 AT는 행렬 A의 전치 행렬입니다.

  • ½(A + AT)는 대칭 행렬입니다. 이 식을 전치하면 ½(AT + A)가 되어 원래 식과 동일하기 때문입니다.
  • ½(A − AT)는 반대칭 행렬입니다. 전치하면 ½(AT − A) = −½(A − AT)가 되어 원래 식의 음수가 되기 때문입니다.

두 행렬을 다시 더하면 원래의 A가 되므로, 모든 정방행렬은 대칭 행렬과 반대칭 행렬의 합으로 나타낼 수 있습니다.

C++ 구현 예제

다음 코드는 입력 행렬의 전치 행렬을 먼저 계산한 후, 각 성분별로 (A + AT)/2와 (A − AT)/2를 구해 두 행렬로 분해합니다.

#include <bits/stdc++.h>
using namespace std;
#define N 3
void printMatrix(float mat[N][N]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)
            cout << mat[i][j] << " ";
        cout << endl;
    }
}
int main() {
    float mat[N][N] = { { 2, -2, -4 },
    { -1, 3, 4 },
    { 1, -2, -3 } };
    float tr[N][N];
    for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
    tr[i][j] = mat[j][i];
    float symm[N][N], skewsymm[N][N];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            symm[i][j] = (mat[i][j] + tr[i][j]) / 2;
            skewsymm[i][j] = (mat[i][j] - tr[i][j]) / 2;
        }
    }
    cout << "Symmetric matrix-" << endl;
    printMatrix(symm);
    cout << "Skew Symmetric matrix-" << endl;
    printMatrix(skewsymm);
    return 0;
}

실행 결과

Symmetric matrix -
2 -1.5 -1.5
-1.5 3 1
-1.5 1 -3
Skew Symmetric matrix -
0 -0.5 -2.5
0.5 0 3
2.5 -3 0

결과를 보면 대칭 행렬은 주대각선을 기준으로 좌우 성분이 서로 같고, 반대칭 행렬은 주대각선이 모두 0이며 마주 보는 성분끼리 부호만 반대인 것을 확인할 수 있습니다. 또한 두 행렬을 성분별로 더하면 원래의 입력 행렬이 그대로 복원됩니다.