Eigen 라이브러리에서 가장 중요한 클래스 중 하나는 벡터와 행렬을 다루는 클래스이다. 이들은 다양한 수학적 연산을 효율적으로 처리할 수 있도록 설계되어 있으며, 특히 선형대수학적 문제를 해결하는 데 매우 유용하다. 본 장에서는 Vector 클래스와 Matrix 클래스의 구조, 기능, 사용 방법을 다룬다.
Vector 클래스
Eigen에서 벡터는 1차원 배열로 표현되며, 선형대수에서 다루는 벡터와 동일한 의미를 갖는다. 벡터는 방향과 크기를 가지며, 2차원, 3차원, 혹은 그 이상의 차원에서도 정의될 수 있다. Eigen의 벡터 클래스는 Eigen::VectorXd
와 같은 형식으로 사용되며, 이는 차원이 동적으로 할당된 벡터를 의미한다. 차원이 정해진 벡터는 Eigen::Vector3d
와 같은 형식으로 정의된다.
예를 들어, 3차원 벡터는 다음과 같이 정의할 수 있다.
Eigen::Vector3d v;
v << 1, 2, 3;
이러한 벡터는 수학적으로 다음과 같이 표현된다.
이러한 벡터의 기본 연산에는 덧셈, 뺄셈, 스칼라 곱, 내적 등이 포함된다. 벡터 간의 덧셈은 다음과 같이 정의된다.
행렬 클래스
Eigen의 행렬 클래스는 2차원 배열로, 행과 열로 구성되어 있다. 행렬은 다양한 형태로 정의될 수 있으며, 차원이 동적으로 할당되거나, 고정된 형태로 정의될 수 있다. 기본적인 행렬 클래스는 Eigen::MatrixXd
로, 이는 동적으로 할당된 크기의 행렬을 의미한다. 정해진 크기의 행렬은 Eigen::Matrix3d
와 같은 형식으로 정의된다.
예를 들어, 3x3 행렬은 다음과 같이 정의된다.
Eigen::Matrix3d m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
수학적으로, 이는 다음과 같은 행렬로 표현된다.
행렬의 기본 연산으로는 덧셈, 뺄셈, 스칼라 곱, 행렬 곱셈 등이 있다. 두 행렬의 곱셈은 다음과 같이 정의된다.
Eigen의 행렬 클래스는 다양한 크기의 행렬을 매우 효율적으로 처리하며, 이를 통해 대규모 수학적 계산을 빠르게 수행할 수 있다.
Vector 클래스와 행렬 클래스의 크기 동적 할당
Eigen 라이브러리에서 Vector와 Matrix 클래스는 동적 크기 할당이 가능한다. 즉, 프로그램 실행 중에 벡터나 행렬의 크기를 설정할 수 있으며, 이를 통해 더욱 유연한 구조로 사용할 수 있다.
동적 크기의 벡터
동적 크기의 벡터는 Eigen::VectorXd
로 정의되며, 크기를 실행 중에 할당할 수 있다. 예를 들어, 크기가 5인 벡터를 다음과 같이 정의할 수 있다.
Eigen::VectorXd v(5);
v << 1, 2, 3, 4, 5;
이 경우, 벡터의 수학적 표현은 다음과 같다.
또한, 벡터의 크기는 실행 중에 다시 변경할 수 있다. 예를 들어, 벡터의 크기를 10으로 늘리고 값을 초기화하는 코드는 다음과 같다.
v.resize(10);
v.setZero(); // 모든 원소를 0으로 초기화
이처럼 resize()
함수와 초기화 함수인 setZero()
, setOnes()
등을 통해 크기와 내용을 동적으로 조정할 수 있다.
동적 크기의 행렬
동적 크기의 행렬은 Eigen::MatrixXd
로 정의되며, 마찬가지로 실행 중에 크기를 설정할 수 있다. 예를 들어, 3x4 행렬을 정의하는 코드는 다음과 같다.
Eigen::MatrixXd m(3, 4);
m << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12;
이 행렬은 다음과 같이 표현된다.
동적 크기의 행렬 역시 실행 중에 크기를 변경할 수 있다. 예를 들어, 이 행렬의 크기를 5x5로 조정하려면 다음과 같이 코딩할 수 있다.
m.resize(5, 5);
m.setIdentity(); // 단위 행렬로 설정
위 코드에서는 resize()
함수를 사용하여 행렬의 크기를 조정하고, setIdentity()
함수로 단위 행렬을 생성하였다. 이렇게 Eigen의 행렬 클래스는 크기를 동적으로 조정하면서 다양한 수학적 연산을 효율적으로 수행할 수 있다.
벡터와 행렬의 변환
벡터와 행렬 사이에는 여러 가지 변환이 가능한다. 예를 들어, Eigen에서는 벡터를 행렬로 변환하거나 그 반대의 작업을 쉽게 수행할 수 있다.
벡터를 행렬로 변환
Eigen의 벡터는 단순히 열 벡터로 간주될 수 있으며, 이를 행렬로 변환하는 것은 자연스럽습니다. 예를 들어, Eigen::Vector3d
타입의 벡터를 3x1 행렬로 변환하려면 별도의 변환 작업이 필요 없다. 벡터는 기본적으로 행렬의 한 형태로 취급되기 때문이다.
Eigen::Vector3d v(1, 2, 3);
Eigen::MatrixXd m = v;
이 경우, 행렬 m
은 다음과 같이 생성된다.
행렬에서 벡터 추출
행렬에서 특정 열 또는 행을 추출하여 벡터로 변환할 수도 있다. 예를 들어, 3x3 행렬의 첫 번째 열을 벡터로 추출하는 코드는 다음과 같다.
Eigen::Matrix3d m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Eigen::Vector3d v = m.col(0);
위 코드에서는 행렬 m
의 첫 번째 열을 v
에 할당했으며, v
는 다음과 같이 나타난다.
이와 같이 벡터와 행렬의 변환은 매우 직관적이며, 이를 통해 다양한 형태의 수학적 계산을 유연하게 처리할 수 있다.
벡터와 행렬의 기본 연산
Eigen 라이브러리에서 벡터와 행렬의 기본 연산은 수학적 정의와 일치하며, 매우 직관적으로 사용할 수 있다. 이러한 연산에는 벡터 간 또는 행렬 간의 덧셈, 뺄셈, 스칼라 곱셈, 내적, 외적 등이 포함된다.
벡터 덧셈과 뺄셈
벡터의 덧셈과 뺄셈은 동일한 크기의 벡터끼리만 수행할 수 있다. 각 원소는 해당하는 위치의 원소끼리 더하거나 빼는 방식으로 연산된다. 예를 들어, 두 3차원 벡터 \mathbf{v_1}과 \mathbf{v_2}의 덧셈은 다음과 같다.
이 연산은 코드로는 다음과 같이 표현된다.
Eigen::Vector3d v1(1, 2, 3);
Eigen::Vector3d v2(4, 5, 6);
Eigen::Vector3d v_sum = v1 + v2;
벡터 뺄셈의 경우도 유사하게 다음과 같이 정의된다.
벡터의 스칼라 곱
벡터와 스칼라의 곱은 벡터의 각 원소에 스칼라 값을 곱하는 방식으로 이루어진다. 예를 들어, 벡터 \mathbf{v} = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix}에 스칼라 2를 곱하면 다음과 같은 벡터가 된다.
코드로는 다음과 같이 작성된다.
Eigen::Vector3d v(1, 2, 3);
Eigen::Vector3d v_scaled = 2 * v;
벡터 내적 (Dot Product)
내적은 두 벡터의 대응하는 원소를 곱한 뒤 합산하는 연산이다. 예를 들어, 두 3차원 벡터 \mathbf{v_1}과 \mathbf{v_2}의 내적은 다음과 같이 계산된다.
이는 코드로 다음과 같이 표현된다.
Eigen::Vector3d v1(1, 2, 3);
Eigen::Vector3d v2(4, 5, 6);
double dot_product = v1.dot(v2);
내적의 결과는 스칼라 값이 되며, 이는 두 벡터 사이의 방향성을 측정하는 데 사용될 수 있다.
벡터 외적 (Cross Product)
외적은 3차원 벡터에서만 정의되며, 두 벡터의 외적은 새로운 3차원 벡터를 생성한다. 외적은 두 벡터가 이루는 평면에 수직인 벡터를 구하는 연산으로, 다음과 같이 정의된다.
예를 들어, 두 벡터 \mathbf{v_1} = \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix}과 \mathbf{v_2} = \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix}의 외적은 다음과 같다.
코드로는 다음과 같이 구현된다.
Eigen::Vector3d v1(1, 0, 0);
Eigen::Vector3d v2(0, 1, 0);
Eigen::Vector3d cross_product = v1.cross(v2);
행렬 덧셈과 뺄셈
행렬의 덧셈과 뺄셈은 벡터와 유사하게 같은 차원의 행렬끼리만 가능한다. 두 행렬 \mathbf{A}와 \mathbf{B}가 있을 때, 이들의 덧셈은 다음과 같이 정의된다.
예를 들어, 두 행렬을 더하는 코드는 다음과 같다.
Eigen::Matrix2d A, B;
A << 1, 2, 3, 4;
B << 5, 6, 7, 8;
Eigen::Matrix2d C = A + B;
행렬의 스칼라 곱
행렬의 스칼라 곱은 행렬의 각 원소에 스칼라 값을 곱하는 연산이다. 예를 들어, 2x2 행렬 \mathbf{A}와 스칼라 값 k에 대한 곱셈은 다음과 같이 정의된다.
예를 들어, 스칼라 3과 행렬 \mathbf{A} = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix}의 곱은 다음과 같다.
이를 코드로 구현하면 다음과 같다.
Eigen::Matrix2d A;
A << 1, 2, 3, 4;
Eigen::Matrix2d B = 3 * A;
행렬 곱셈
행렬 곱셈은 두 행렬의 곱을 계산하는 매우 중요한 연산이다. 두 행렬 \mathbf{A}와 \mathbf{B}가 곱해질 수 있으려면, \mathbf{A}의 열 수와 \mathbf{B}의 행 수가 동일해야 한다. 두 행렬의 곱은 다음과 같이 계산된다.
예를 들어, \mathbf{A}가 2x3 행렬이고 \mathbf{B}가 3x2 행렬일 때, 이들의 곱은 다음과 같다.
이를 코드로 구현하면 다음과 같다.
Eigen::MatrixXd A(2, 3);
Eigen::MatrixXd B(3, 2);
A << 1, 2, 3, 4, 5, 6;
B << 7, 8, 9, 10, 11, 12;
Eigen::MatrixXd C = A * B;
전치 행렬 (Transpose)
전치 행렬은 주어진 행렬의 행과 열을 뒤바꾸는 연산이다. 예를 들어, 2 \times 3 행렬 \mathbf{A}의 전치 행렬 \mathbf{A}^T는 다음과 같이 정의된다.
코드로는 transpose()
함수를 사용하여 전치 행렬을 구할 수 있다.
Eigen::MatrixXd A(2, 3);
A << 1, 2, 3, 4, 5, 6;
Eigen::MatrixXd A_T = A.transpose();
역행렬 (Inverse)
정방 행렬 (행과 열의 수가 같은 행렬) \mathbf{A}의 역행렬 \mathbf{A}^{-1}은 \mathbf{A} \cdot \mathbf{A}^{-1} = \mathbf{I}가 성립할 때, \mathbf{A}에 대해 정의된다. 여기서 \mathbf{I}는 단위 행렬이다.
예를 들어, 2 \times 2 행렬 \mathbf{A}가 있을 때, 그 역행렬은 다음과 같이 계산된다.
코드로는 inverse()
함수를 사용하여 역행렬을 구할 수 있다.
Eigen::Matrix2d A;
A << 1, 2, 3, 4;
Eigen::Matrix2d A_inv = A.inverse();
행렬식 (Determinant)
행렬식은 정방 행렬에 대해 정의되며, 주어진 행렬이 역행렬을 가질 수 있는지 여부를 결정하는 데 사용된다. 예를 들어, 2 \times 2 행렬 \mathbf{A}의 행렬식은 다음과 같이 계산된다.
코드로는 determinant()
함수를 사용하여 행렬식을 구할 수 있다.
Eigen::Matrix2d A;
A << 1, 2, 3, 4;
double det = A.determinant();
단위 행렬과 영 행렬
단위 행렬은 주대각선에 1이 있고, 나머지 원소가 모두 0인 정방 행렬이다. 3 \times 3 단위 행렬 \mathbf{I}는 다음과 같다.
Eigen에서는 setIdentity()
함수를 사용하여 단위 행렬을 만들 수 있다.
Eigen::Matrix3d I;
I.setIdentity();
영 행렬은 모든 원소가 0인 행렬이다. 2 \times 2 영 행렬 \mathbf{O}는 다음과 같이 나타낸다.
코드로는 setZero()
함수를 사용하여 영 행렬을 만들 수 있다.
Eigen::Matrix2d O;
O.setZero();
블록 연산 (Block Operations)
Eigen 라이브러리에서는 행렬의 일부를 추출하거나 특정 영역에 대해 연산을 수행할 수 있는 블록 연산을 제공한다. 이를 통해 행렬의 부분적인 조작이 가능한다. 블록 연산은 행렬의 부분 집합을 참조하거나 변경할 때 유용하게 사용된다.
블록 추출
블록 연산을 사용하여 행렬의 일부를 추출할 수 있다. 블록은 block(i, j, p, q)
함수를 사용하여 추출할 수 있으며, 이 함수는 행렬의 i번째 행, j번째 열부터 시작하여 p \times q 크기의 블록을 반환한다.
예를 들어, 4x4 행렬 \mathbf{A}에서 2x2 블록을 추출하는 코드는 다음과 같다.
Eigen::Matrix4d A;
A << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
Eigen::Matrix2d block = A.block(1, 1, 2, 2);
위 코드에서 A.block(1, 1, 2, 2)
는 행렬 \mathbf{A}의 두 번째 행, 두 번째 열에서 시작하여 2x2 크기의 블록을 추출한다. 추출된 블록은 다음과 같다.
블록 삽입
블록 연산은 행렬의 일부분을 변경하는 데도 사용될 수 있다. 특정 위치에 새로운 값을 삽입하는 방식으로 행렬의 일부를 변경할 수 있다. 예를 들어, 2x2 행렬 \mathbf{B}를 4x4 행렬 \mathbf{A}의 한 부분에 삽입하는 코드는 다음과 같다.
Eigen::Matrix4d A;
A.setZero(); // 4x4 영 행렬로 초기화
Eigen::Matrix2d B;
B << 1, 2, 3, 4;
A.block(1, 1, 2, 2) = B;
이 코드는 \mathbf{A}의 두 번째 행, 두 번째 열에서 시작하는 위치에 \mathbf{B}를 삽입한다. 삽입 후의 \mathbf{A}는 다음과 같다.
행과 열 추출
Eigen 라이브러리에서는 행렬의 특정 행이나 열을 추출할 수 있다. 예를 들어, 3x3 행렬 \mathbf{A}의 첫 번째 열을 추출하는 코드는 다음과 같다.
Eigen::Matrix3d A;
A << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Eigen::Vector3d col = A.col(0);
추출된 첫 번째 열은 다음과 같이 나타난다.
마찬가지로, 특정 행을 추출하려면 row()
함수를 사용할 수 있다. 예를 들어, 두 번째 행을 추출하는 코드는 다음과 같다.
Eigen::Vector3d row = A.row(1);
추출된 두 번째 행은 다음과 같다.
배열과 행렬의 연산 차이
Eigen 라이브러리에서 행렬 클래스는 수학적 행렬 연산을 수행할 때 사용된다. 그러나 때로는 원소별 연산이 필요한 경우가 있다. 이때 Array
클래스를 사용하면 원소별 연산을 쉽게 수행할 수 있다.
원소별 연산
행렬 연산과 배열 연산의 주요 차이점은 배열 연산에서는 원소별로 연산이 수행된다는 점이다. 예를 들어, 두 2x2 행렬 \mathbf{A}와 \mathbf{B}의 원소별 곱셈은 다음과 같이 수행된다.
행렬 곱셈이 아닌 원소별 곱셈은 다음과 같이 계산된다.
이를 코드로 표현하면 다음과 같다.
Eigen::Matrix2d A, B;
A << 1, 2, 3, 4;
B << 5, 6, 7, 8;
Eigen::Matrix2d result = A.array() * B.array();
여기서 .array()
를 사용하여 행렬을 배열로 변환하고, 원소별 연산을 수행한다. 이 방식은 덧셈, 뺄셈, 곱셈, 나눗셈 등 다양한 원소별 연산에 적용할 수 있다.
효율적인 메모리 관리
Eigen 라이브러리는 메모리 관리 측면에서도 매우 효율적으로 설계되었다. 특히, 행렬 크기가 커질수록 메모리 할당과 관련된 최적화가 중요한데, Eigen은 이를 잘 지원한다. Eigen의 다양한 메모리 관리 기법을 통해 고성능 계산을 지원한다.
참조에 의한 전달 (Pass by Reference)
행렬을 함수에 전달할 때 복사가 발생하면 성능에 큰 영향을 미칠 수 있다. 따라서 큰 행렬을 함수에 전달할 때는 참조로 전달하는 것이 좋다. 예를 들어, 다음과 같이 참조를 통해 행렬을 전달할 수 있다.
void processMatrix(const Eigen::MatrixXd& mat) {
// 행렬을 처리하는 코드
}
여기서 const Eigen::MatrixXd&
는 복사가 아닌 참조를 사용하여 성능을 최적화하는 방식이다.
메모리 보존 (Lazy Evaluation)
Eigen은 지연 평가(lazy evaluation)를 통해 불필요한 계산을 줄이는 메커니즘을 가지고 있다. 이로 인해 다중 연산을 수행할 때 중간 결과를 저장하지 않고, 최종 결과만 계산하는 방식으로 메모리 사용을 줄일 수 있다.
예를 들어, 다음과 같은 코드에서:
Eigen::Vector3d v1, v2, v3;
Eigen::Vector3d result = v1 + v2 + v3;
Eigen은 내부적으로 v1 + v2의 중간 결과를 저장하지 않고, 한 번의 계산으로 최종 결과를 구하도록 최적화한다.
메모리 매핑 (Memory Mapping)
Eigen에서는 외부 데이터 배열을 행렬이나 벡터로 직접 매핑하여 사용하는 기능을 제공한다. 이는 메모리를 복사하지 않고 외부 데이터에 직접 접근할 수 있어 메모리 사용량과 계산 성능을 최적화하는 데 매우 유용하다.
외부 데이터 매핑
Eigen에서 제공하는 Map
클래스를 사용하면 외부에 정의된 배열을 직접 Eigen 객체로 매핑할 수 있다. 이를 통해 복사 없이 원본 데이터에 접근하여 연산을 수행할 수 있다.
예를 들어, C++에서 이미 존재하는 배열을 Eigen의 행렬로 매핑하는 방법은 다음과 같다.
double data[6] = {1, 2, 3, 4, 5, 6};
Eigen::Map<Eigen::Matrix<double, 2, 3>> mat(data);
이 코드는 배열 data
를 2x3
행렬로 매핑한다. 여기서 중요한 점은, mat
은 배열 data
를 복사하지 않고 그 데이터를 참조한다는 것이다. 수학적으로, 이 행렬은 다음과 같이 나타난다.
이처럼 Map
을 통해 배열을 직접 참조하면 불필요한 메모리 할당을 피할 수 있으며, 이는 대규모 데이터를 처리할 때 매우 유용하다.
행렬을 부분적으로 매핑
또한 Map
클래스를 사용하면 행렬의 일부분만을 참조할 수도 있다. 예를 들어, 4x4 행렬에서 특정 2x2 블록만을 매핑하는 것은 다음과 같다.
Eigen::Matrix4d A;
A << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
Eigen::Map<Eigen::Matrix2d> block(A.data() + 5);
여기서 A.data() + 5
는 4x4 행렬 \mathbf{A}의 특정 위치를 참조한다. 매핑된 2x2 블록은 다음과 같다.
메모리 정렬과 벡터화
Eigen은 성능 최적화를 위해 메모리 정렬(memory alignment)과 벡터화(vectorization)를 적극적으로 활용한다. 이를 통해 현대 CPU의 SIMD(single instruction, multiple data) 명령어 세트를 사용하여 병렬 연산을 수행할 수 있다.
Eigen은 기본적으로 메모리를 16바이트 단위로 정렬하여, 벡터 연산을 최적화한다. 이는 대규모 연산을 수행할 때 CPU 캐시와 메모리 접근 속도를 최적화하는 데 기여한다.
메모리 정렬을 수동으로 조정하려면 Eigen의 aligned_allocator
를 사용할 수 있다. 예를 들어, 다음과 같이 정렬된 벡터를 정의할 수 있다.
std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d>> vecs;
이 방식은 대규모 벡터나 행렬을 사용할 때 특히 성능 향상을 제공한다.
Eigen의 고급 기능
Eigen은 기본적인 선형대수 연산 외에도 다양한 고급 기능을 제공한다. 이러한 기능에는 행렬 분해, 특이값 분해(SVD), 고유값 분해(Eigenvalue Decomposition) 등이 포함된다. 이 섹션에서는 이러한 고급 기능에 대해 간략히 살펴본다.
LU 분해
LU 분해는 정방 행렬을 하삼각 행렬(Lower triangular matrix)과 상삼각 행렬(Upper triangular matrix)의 곱으로 분해하는 방법이다. LU 분해는 선형 방정식 시스템을 푸는 데 사용된다.
행렬 \mathbf{A}에 대한 LU 분해는 다음과 같이 나타낼 수 있다.
여기서 \mathbf{L}은 하삼각 행렬, \mathbf{U}는 상삼각 행렬이다.
Eigen에서 LU 분해는 FullPivLU
클래스를 사용하여 수행할 수 있다.
Eigen::Matrix3d A;
A << 1, 2, 3, 4, 5, 6, 7, 8, 9;
Eigen::FullPivLU<Eigen::Matrix3d> lu(A);
Eigen::Matrix3d L = lu.matrixL();
Eigen::Matrix3d U = lu.matrixU();
QR 분해
QR 분해는 행렬을 직교 행렬 \mathbf{Q}와 상삼각 행렬 \mathbf{R}의 곱으로 분해하는 방법이다. QR 분해는 행렬의 고유값을 구하거나 최소제곱 문제를 해결하는 데 유용하게 사용된다.
Eigen에서 QR 분해는 HouseholderQR
클래스를 사용하여 수행할 수 있다.
Eigen::MatrixXd A(3, 3);
A << 12, -51, 4,
6, 167, -68,
-4, 24, -41;
Eigen::HouseholderQR<Eigen::MatrixXd> qr(A);
Eigen::MatrixXd Q = qr.householderQ();
Eigen::MatrixXd R = qr.matrixQR().triangularView<Eigen::Upper>();
특이값 분해 (SVD)
특이값 분해(SVD, Singular Value Decomposition)는 임의의 행렬을 세 개의 행렬로 분해하는 강력한 기법이다. 행렬 \mathbf{A}는 다음과 같이 분해된다.
여기서 \mathbf{U}와 \mathbf{V}는 직교 행렬, \mathbf{\Sigma}는 대각 행렬이다. SVD는 행렬의 순위(rank)를 구하거나 차원 축소(dimensionality reduction) 문제에 매우 유용하게 사용된다.
Eigen에서 SVD는 JacobiSVD
클래스를 사용하여 수행할 수 있다.
Eigen::MatrixXd A(3, 2);
A << 1, 0, 0, 1, 0, 0;
Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeThinU | Eigen::ComputeThinV);
Eigen::MatrixXd U = svd.matrixU();
Eigen::MatrixXd V = svd.matrixV();
Eigen::VectorXd S = svd.singularValues();
고유값 분해 (Eigenvalue Decomposition)
고유값 분해는 행렬을 고유값(eigenvalue)과 고유벡터(eigenvector)로 분해하는 방법이다. 정방 행렬 \mathbf{A}에 대해, 고유값 \lambda와 고유벡터 \mathbf{v}는 다음 관계를 만족한다.
Eigen에서 고유값 분해는 EigenSolver
클래스를 사용하여 수행할 수 있다.
Eigen::Matrix3d A;
A << 1, 2, 3, 4, 5, 6, 7, 8, 9;
Eigen::EigenSolver<Eigen::Matrix3d> es(A);
Eigen::Vector3d eigenvalues = es.eigenvalues().real();
Eigen::Matrix3d eigenvectors = es.eigenvectors().real();
고유값 분해는 행렬의 성질을 이해하거나 시스템의 안정성을 분석하는 데 유용하다.