대각행렬

대각행렬(diagonal matrix)은 주 대각선에 있는 성분을 제외한 모든 성분이 0인 정사각행렬을 의미한다. 즉, 행렬 \mathbf{A}가 대각행렬이라면, \mathbf{A}의 성분 중 a_{ij}i \neq j인 경우 모두 0이다. 이를 수식으로 나타내면 다음과 같다.

\mathbf{A} = \begin{pmatrix} a_{11} & 0 & 0 & \cdots & 0 \\ 0 & a_{22} & 0 & \cdots & 0 \\ 0 & 0 & a_{33} & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & a_{nn} \end{pmatrix}

위 수식에서 \mathbf{A}n \times n의 대각행렬이다. 대각행렬은 행렬 연산에서 중요한 역할을 하며, 특히 선형대수와 고유값 문제에서 자주 등장한다. 대각행렬의 특성상 행렬의 성분을 계산할 때 매우 간단해지며, 연산의 복잡성이 감소한다.

대각합

대각합(trace)은 정사각행렬의 주 대각선에 있는 원소들의 합을 의미한다. 행렬 \mathbf{A}의 대각합을 \text{tr}(\mathbf{A})로 나타내며, 이는 다음과 같이 정의된다.

\text{tr}(\mathbf{A}) = \sum_{i=1}^{n} a_{ii}

즉, \mathbf{A}의 대각합은 \mathbf{A}의 대각선 원소들의 합과 같다. 대각합은 행렬의 고유값과 밀접한 관계가 있으며, 고유값의 합은 대각합과 같다. 이는 다음과 같은 성질을 따른다.

  1. \text{tr}(\mathbf{A} + \mathbf{B}) = \text{tr}(\mathbf{A}) + \text{tr}(\mathbf{B})
  2. \text{tr}(c\mathbf{A}) = c \cdot \text{tr}(\mathbf{A}) (여기서 c는 상수)
  3. \text{tr}(\mathbf{A}\mathbf{B}) = \text{tr}(\mathbf{B}\mathbf{A}) (교환법칙)

Eigen을 사용한 대각행렬과 대각합 예제

Eigen 라이브러리를 사용하여 대각행렬을 생성하고, 그 대각합을 계산하는 예제를 살펴보자.

#include <Eigen/Dense>
#include <iostream>

int main() {
    // 3x3 대각행렬 생성
    Eigen::Matrix3d A;
    A << 1, 0, 0,
         0, 2, 0,
         0, 0, 3;

    // 대각행렬 출력
    std::cout << "Matrix A:\n" << A << std::endl;

    // 대각합 계산
    double trace_A = A.trace();
    std::cout << "Trace of A: " << trace_A << std::endl;

    return 0;
}

이 예제에서는 3 \times 3 대각행렬 \mathbf{A}를 생성하고, Eigen의 trace() 함수를 사용하여 대각합을 계산한다. 여기서 행렬 \mathbf{A}

\mathbf{A} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 3 \end{pmatrix}

로 정의되었으며, 이 행렬의 대각합은

\text{tr}(\mathbf{A}) = 1 + 2 + 3 = 6

이다.

대각행렬의 곱

두 대각행렬의 곱은 다시 대각행렬이 된다. 두 대각행렬 \mathbf{A}\mathbf{B}가 있을 때, 이들의 곱 \mathbf{C} = \mathbf{A}\mathbf{B} 또한 대각행렬이다. 이 성질은 대각행렬의 대각 성분끼리만 곱하기 때문에 성립한다. 구체적으로, \mathbf{A}\mathbf{B}가 각각 n \times n 대각행렬이라면,

\mathbf{A} = \begin{pmatrix} a_{11} & 0 & \cdots & 0 \\ 0 & a_{22} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & a_{nn} \end{pmatrix}
\mathbf{B} = \begin{pmatrix} b_{11} & 0 & \cdots & 0 \\ 0 & b_{22} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & b_{nn} \end{pmatrix}

이 때, \mathbf{C} = \mathbf{A}\mathbf{B}는 다음과 같이 정의된다.

\mathbf{C} = \mathbf{A} \mathbf{B} = \begin{pmatrix} a_{11} b_{11} & 0 & \cdots & 0 \\ 0 & a_{22} b_{22} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & a_{nn} b_{nn} \end{pmatrix}

즉, 대각 성분끼리만 곱하는 결과를 얻게 된다.

Eigen을 사용한 대각행렬 곱 예제

이제 두 대각행렬의 곱을 Eigen을 사용하여 계산하는 예제를 살펴보자.

#include <Eigen/Dense>
#include <iostream>

int main() {
    // 3x3 대각행렬 A와 B 생성
    Eigen::Matrix3d A;
    A << 1, 0, 0,
         0, 2, 0,
         0, 0, 3;

    Eigen::Matrix3d B;
    B << 4, 0, 0,
         0, 5, 0,
         0, 0, 6;

    // 행렬 곱 C = A * B
    Eigen::Matrix3d C = A * B;

    // 결과 출력
    std::cout << "Matrix C (A * B):\n" << C << std::endl;

    return 0;
}

위 코드에서는 두 개의 3 \times 3 대각행렬 \mathbf{A}\mathbf{B}를 정의하고, 이들의 곱 \mathbf{C}를 계산한다. 행렬 \mathbf{A}

\mathbf{A} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 3 \end{pmatrix}

이고, 행렬 \mathbf{B}

\mathbf{B} = \begin{pmatrix} 4 & 0 & 0 \\ 0 & 5 & 0 \\ 0 & 0 & 6 \end{pmatrix}

따라서 두 행렬의 곱 \mathbf{C}

\mathbf{C} = \mathbf{A} \mathbf{B} = \begin{pmatrix} 1 \cdot 4 & 0 & 0 \\ 0 & 2 \cdot 5 & 0 \\ 0 & 0 & 3 \cdot 6 \end{pmatrix} = \begin{pmatrix} 4 & 0 & 0 \\ 0 & 10 & 0 \\ 0 & 0 & 18 \end{pmatrix}

이 된다.

대각합의 성질

대각합은 행렬의 성질을 간단하게 나타낼 수 있는 유용한 도구이다. 특히, 대각합은 고유값과 밀접한 관계가 있는데, 행렬의 모든 고유값의 합은 그 행렬의 대각합과 같다. 이를 수식으로 표현하면,

\text{tr}(\mathbf{A}) = \sum_{i=1}^{n} \lambda_i

여기서 \lambda_i\mathbf{A}의 고유값이다. 대각행렬의 경우, 그 고유값은 대각선 성분과 같으므로, 대각합이 고유값의 합과 같다는 성질은 특히 유용하다.

Eigen을 사용하여 고유값과 대각합의 관계를 확인하는 예제는 다음과 같다.

#include <Eigen/Dense>
#include <iostream>

int main() {
    // 3x3 대각행렬 A 생성
    Eigen::Matrix3d A;
    A << 1, 0, 0,
         0, 2, 0,
         0, 0, 3;

    // 고유값 계산
    Eigen::EigenSolver<Eigen::Matrix3d> solver(A);
    Eigen::Vector3d eigenvalues = solver.eigenvalues().real();

    // 고유값 출력
    std::cout << "Eigenvalues of A:\n" << eigenvalues << std::endl;

    // 대각합과 고유값의 합 비교
    double trace_A = A.trace();
    double sum_eigenvalues = eigenvalues.sum();

    std::cout << "Trace of A: " << trace_A << std::endl;
    std::cout << "Sum of eigenvalues: " << sum_eigenvalues << std::endl;

    return 0;
}

이 예제에서는 3 \times 3 대각행렬 \mathbf{A}의 고유값을 구하고, 그 고유값의 합과 대각합을 비교한다. \mathbf{A}의 고유값은 1, 2, 3이며, 고유값의 합은 1 + 2 + 3 = 6이다. 또한, \mathbf{A}의 대각합 역시 6으로, 고유값의 합과 대각합이 같다는 것을 확인할 수 있다.

대각행렬의 역행렬

대각행렬 \mathbf{A}의 역행렬(inverse matrix)은 존재할 경우, 대각 성분의 역수로 구성된 또 다른 대각행렬이다. 즉, 대각행렬이 역행렬을 가지기 위해서는 모든 대각 성분이 0이 아니어야 한다. 대각행렬 \mathbf{A}의 역행렬 \mathbf{A}^{-1}은 다음과 같이 정의된다.

\mathbf{A}^{-1} = \begin{pmatrix} \frac{1}{a_{11}} & 0 & \cdots & 0 \\ 0 & \frac{1}{a_{22}} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \frac{1}{a_{nn}} \end{pmatrix}

따라서, 대각행렬의 역행렬은 단순히 각 대각 성분의 역수로 이루어진 대각행렬이다.

Eigen을 사용한 대각행렬 역행렬 예제

대각행렬의 역행렬을 Eigen 라이브러리를 사용하여 계산하는 예제를 살펴보자.

#include <Eigen/Dense>
#include <iostream>

int main() {
    // 3x3 대각행렬 A 생성
    Eigen::Matrix3d A;
    A << 1, 0, 0,
         0, 2, 0,
         0, 0, 3;

    // 역행렬 계산
    Eigen::Matrix3d A_inv = A.inverse();

    // 결과 출력
    std::cout << "Inverse of A:\n" << A_inv << std::endl;

    return 0;
}

이 코드에서는 3 \times 3 대각행렬 \mathbf{A}의 역행렬을 계산한다. 행렬 \mathbf{A}

\mathbf{A} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 3 \end{pmatrix}

로 정의되었으며, 이 행렬의 역행렬 \mathbf{A}^{-1}

\mathbf{A}^{-1} = \begin{pmatrix} \frac{1}{1} & 0 & 0 \\ 0 & \frac{1}{2} & 0 \\ 0 & 0 & \frac{1}{3} \end{pmatrix} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 0.5 & 0 \\ 0 & 0 & 0.3333 \end{pmatrix}

로 계산된다.

대각행렬의 거듭제곱

대각행렬의 또 다른 중요한 성질 중 하나는 거듭제곱 연산이다. 대각행렬 \mathbf{A}k번째 거듭제곱 \mathbf{A}^k는 대각 성분을 k번 거듭 곱한 결과로 계산된다. 수식으로 나타내면 다음과 같다.

\mathbf{A}^k = \begin{pmatrix} a_{11}^k & 0 & \cdots & 0 \\ 0 & a_{22}^k & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & a_{nn}^k \end{pmatrix}

대각행렬의 거듭제곱은 매우 간단하게 계산할 수 있다.

Eigen을 사용한 대각행렬 거듭제곱 예제

이제 Eigen 라이브러리를 사용하여 대각행렬의 거듭제곱을 계산하는 예제를 살펴보자.

#include <Eigen/Dense>
#include <iostream>

int main() {
    // 3x3 대각행렬 A 생성
    Eigen::Matrix3d A;
    A << 2, 0, 0,
         0, 3, 0,
         0, 0, 4;

    // A의 3제곱 계산
    Eigen::Matrix3d A_pow3 = A.array().pow(3);

    // 결과 출력
    std::cout << "A^3:\n" << A_pow3 << std::endl;

    return 0;
}

이 예제에서는 3 \times 3 대각행렬 \mathbf{A}의 세제곱을 계산하고 있다. 행렬 \mathbf{A}

\mathbf{A} = \begin{pmatrix} 2 & 0 & 0 \\ 0 & 3 & 0 \\ 0 & 0 & 4 \end{pmatrix}

이고, 이 행렬의 세제곱 \mathbf{A}^3

\mathbf{A}^3 = \begin{pmatrix} 2^3 & 0 & 0 \\ 0 & 3^3 & 0 \\ 0 & 0 & 4^3 \end{pmatrix} = \begin{pmatrix} 8 & 0 & 0 \\ 0 & 27 & 0 \\ 0 & 0 & 64 \end{pmatrix}

로 계산된다.