Eigen для C++: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в Eigen: что это и зачем нужно

Eigen — это высокопроизводительная библиотека для линейной алгебры на языке C++. Она предоставляет широкий спектр возможностей для работы с векторами, матрицами, разреженными матрицами, а также для решения систем линейных уравнений, вычисления собственных значений и сингулярного разложения. Eigen написан на чистом C++ (шаблоны) и не требует внешних зависимостей, что делает его идеальным выбором для встраиваемых систем, научных вычислений, компьютерной графики, машинного обучения и робототехники.

Зачем нужна Eigen? В отличие от многих других библиотек (например, LAPACK или BLAS), Eigen предлагает интуитивно понятный API, который напоминает работу с матрицами в MATLAB или NumPy. Она поддерживает ленивые вычисления (lazy evaluation) и векторизацию (SSE, AVX, NEON), что обеспечивает производительность, близкую к ручной оптимизации на ассемблере. Eigen также полностью совместима с современными стандартами C++ (C++11 и выше) и активно поддерживается сообществом.

Основные возможности:

  • Работа с плотными и разреженными матрицами произвольных размеров.
  • Операции: сложение, умножение, транспонирование, инвертирование.
  • Решение линейных систем (LU, QR, Cholesky, SVD).
  • Вычисление собственных значений и собственных векторов.
  • Геометрические преобразования (повороты, кватернионы).
  • Поддержка произвольных типов данных (float, double, complex, пользовательские типы).

Установка Eigen

Eigen — это библиотека, состоящая только из заголовочных файлов (header-only). Это означает, что вам не нужно компилировать отдельную библиотеку — достаточно подключить нужные заголовки в вашем проекте. Установка зависит от операционной системы и менеджера пакетов.

Установка через менеджеры пакетов

Linux (Ubuntu/Debian):

sudo apt-get install libeigen3-dev

macOS (Homebrew):

brew install eigen

Windows (vcpkg):

vcpkg install eigen3

Windows (Conan):

conan install eigen/3.4.0@

Установка вручную (для всех ОС)

Скачайте последнюю версию с официального сайта или клонируйте репозиторий:

git clone https://gitlab.com/libeigen/eigen.git

Затем укажите путь к папке Eigen в вашем компиляторе. Например, для g++:

g++ -I /path/to/eigen my_program.cpp -o my_program

Примечание: Если вы используете CMake, добавьте в CMakeLists.txt:

find_package(Eigen3 REQUIRED)
target_link_libraries(my_target Eigen3::Eigen)

Быстрый старт с примером кода

Давайте напишем простую программу, которая создает матрицу и вектор, выполняет умножение и выводит результат.

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

int main() {
    // Создаем матрицу 2x2
    Eigen::Matrix2d A;
    A << 1, 2,
         3, 4;

    // Создаем вектор 2x1
    Eigen::Vector2d b(5, 6);

    // Умножаем матрицу на вектор
    Eigen::Vector2d x = A * b;

    // Выводим результат
    std::cout << "A * b =\n" << x << std::endl;

    return 0;
}

Компиляция и запуск:

g++ -I /path/to/eigen example.cpp -o example
./example

Вывод:

A * b =
17
39

Этот пример демонстрирует, насколько просто работать с Eigen: синтаксис похож на математические операции, а вывод автоматически форматируется.

Основные методы и функции Eigen

Ниже приведены 10 ключевых методов/функций Eigen с подробным описанием, параметрами и примерами.

1. MatrixXd::Zero() — создание нулевой матрицы

Описание: Создает матрицу или вектор, заполненный нулями. Полезно для инициализации.

Параметры: rows (количество строк), cols (количество столбцов). Для векторов используйте VectorXd::Zero(n).

Пример:

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

int main() {
    Eigen::MatrixXd Z = Eigen::MatrixXd::Zero(3, 4);
    std::cout << "Zero matrix 3x4:\n" << Z << std::endl;
    return 0;
}

Вывод:

Zero matrix 3x4:
0 0 0 0
0 0 0 0
0 0 0 0

2. .transpose() — транспонирование матрицы

Описание: Возвращает транспонированную матрицу. Исходная матрица не изменяется (если не использовать .transposeInPlace()).

Параметры: Нет (метод вызывается на объекте матрицы).

Пример:

Eigen::Matrix2d A;
A << 1, 2,
     3, 4;
Eigen::Matrix2d At = A.transpose();
std::cout << "A transposed:\n" << At << std::endl;

Вывод:

A transposed:
1 3
2 4

3. .inverse() — обратная матрица

Описание: Вычисляет обратную матрицу. Работает только для квадратных матриц. Если матрица вырождена, результат может быть некорректным (проверяйте через .determinant()).

Параметры: Нет.

Пример:

Eigen::Matrix2d A;
A << 1, 2,
     3, 4;
Eigen::Matrix2d A_inv = A.inverse();
std::cout << "Inverse of A:\n" << A_inv << std::endl;

Вывод:

Inverse of A:
-2  1
1.5 -0.5

4. .determinant() — определитель матрицы

Описание: Вычисляет определитель квадратной матрицы. Используется для проверки обратимости (если det != 0).

Параметры: Нет.

Пример:

Eigen::Matrix3d A;
A << 1, 2, 3,
     4, 5, 6,
     7, 8, 10;
double det = A.determinant();
std::cout << "Determinant: " << det << std::endl;

Вывод:

Determinant: -3

5. .eigenvalues() — собственные значения

Описание: Вычисляет собственные значения матрицы. Для этого используется класс EigenSolver (для плотных матриц). Возвращает комплексные числа.

Параметры: Нет (метод вызывается на объекте EigenSolver).

Пример:

Eigen::Matrix2d A;
A << 1, 2,
     2, 1;
Eigen::EigenSolver<Eigen::Matrix2d> solver(A);
std::cout << "Eigenvalues:\n" << solver.eigenvalues() << std::endl;

Вывод:

Eigenvalues:
(3,0)
(-1,0)

6. .col(i) и .row(i) — доступ к строкам и столбцам

Описание: Возвращает ссылку на i-й столбец или строку матрицы. Можно читать и изменять значения.

Параметры: i — индекс (начиная с 0).

Пример:

Eigen::Matrix3d A = Eigen::Matrix3d::Random();
std::cout << "Second column:\n" << A.col(1) << std::endl;
A.row(0) = Eigen::Vector3d::Ones(); // Заменяем первую строку на единицы
std::cout << "Modified matrix:\n" << A << std::endl;

7. .block(i, j, p, q) — извлечение подматрицы

Описание: Извлекает блок матрицы размером p x q, начиная с позиции (i, j). Очень удобно для работы с частями матриц.

Параметры: i (строка начала), j (столбец начала), p (количество строк), q (количество столбцов).

Пример:

Eigen::Matrix4d A = Eigen::Matrix4d::Random();
Eigen::Matrix2d B = A.block(1, 1, 2, 2); // Подматрица 2x2 из центра
std::cout << "Block:\n" << B << std::endl;

8. .norm() — норма вектора или матрицы

Описание: Вычисляет евклидову норму (длину) вектора или норму Фробениуса для матрицы.

Параметры: Нет.

Пример:

Eigen::Vector3d v(3, 4, 0);
double n = v.norm();
std::cout << "Norm of v: " << n << std::endl; // 5

9. .solve() — решение системы линейных уравнений

Описание: Решает систему Ax = b. Используется с разложениями (например, LU, QR, LLT). Возвращает вектор x.

Параметры: b — вектор правой части.

Пример:

Eigen::Matrix2d A;
A << 2, 1,
     1, 3;
Eigen::Vector2d b(5, 6);
Eigen::Vector2d x = A.colPivHouseholderQr().solve(b);
std::cout << "Solution x:\n" << x << std::endl;

10. .SVD() — сингулярное разложение

Описание: Выполняет сингулярное разложение матрицы (A = U * S * V^T). Используется для решения плохо обусловленных систем и сжатия данных.

Параметры: Нет (используется класс JacobiSVD).

Пример:

Eigen::Matrix3d A;
A << 1, 0, 0,
     0, 2                    

Рекомендаций