跳到主要内容

3.5.2 Eigen RVV 使用

Eigen 是一个高性能的 C++ 模板库,用于线性代数、矩阵和向量运算、数值分析等。它是纯头文件库,无需编译,只需要包含头文件即可使用。我们RVV的Eigen库基于OpenBLAS实现。

主要特性

  • 高性能: 经过高度优化,性能接近 Fortran 和 C 语言实现
  • 易用性: 直观的 API 设计,支持运算符重载
  • 纯头文件: 无需编译,直接包含头文件即可使用
  • 丰富的功能: 支持矩阵运算、线性方程组求解、特征值分解等

基础用法

基本包含和命名空间

#include <Eigen/Dense>
using namespace Eigen;

向量操作

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

int main() {
// 创建向量
Vector3d v1(1, 2, 3); // 3维向量
VectorXd v2(5); // 动态大小向量
v2 << 1, 2, 3, 4, 5; // 初始化

// 向量运算
Vector3d v3 = v1 + Vector3d(1, 1, 1); // 向量加法
double dot_product = v1.dot(v3); // 点积
Vector3d cross_product = v1.cross(v3); // 叉积
double norm = v1.norm(); // 向量模长

std::cout << "v1: " << v1.transpose() << std::endl;
std::cout << "点积: " << dot_product << std::endl;
std::cout << "模长: " << norm << std::endl;

return 0;
}

矩阵操作

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

int main() {
// 创建矩阵
Matrix3d m1; // 3x3 矩阵
m1 << 1, 2, 3,
4, 5, 6,
7, 8, 9;

MatrixXd m2(3, 4); // 动态大小矩阵
m2 = MatrixXd::Random(3, 4); // 随机矩阵

// 特殊矩阵
Matrix3d identity = Matrix3d::Identity(); // 单位矩阵
Matrix3d zeros = Matrix3d::Zero(); // 零矩阵
Matrix3d ones = Matrix3d::Ones(); // 全1矩阵

// 矩阵运算
Matrix3d m3 = m1 + identity; // 矩阵加法
Matrix3d m4 = m1 * m3; // 矩阵乘法
Matrix3d m5 = m1.transpose(); // 转置

std::cout << "矩阵 m1:\n" << m1 << std::endl;
std::cout << "矩阵 m1 的转置:\n" << m5 << std::endl;

return 0;
}

矩阵分解

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

int main() {
Matrix3d A;
A << 4, -2, 1,
-2, 4, -2,
1, -2, 4;

// LU 分解
PartialPivLU<Matrix3d> lu(A);
Matrix3d L = lu.matrixLU().triangularView<Lower>();
Matrix3d U = lu.matrixLU().triangularView<Upper>();

// QR 分解
HouseholderQR<Matrix3d> qr(A);
Matrix3d Q = qr.householderQ();
Matrix3d R = qr.matrixQR().triangularView<Upper>();

// 特征值分解
SelfAdjointEigenSolver<Matrix3d> eigen_solver(A);
Vector3d eigenvalues = eigen_solver.eigenvalues();
Matrix3d eigenvectors = eigen_solver.eigenvectors();

std::cout << "特征值: " << eigenvalues.transpose() << std::endl;
std::cout << "特征向量:\n" << eigenvectors << std::endl;

return 0;
}

线性方程组求解

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

int main() {
// 求解 Ax = b
Matrix3d A;
A << 2, 1, 1,
1, 2, 1,
1, 1, 2;

Vector3d b(1, 2, 3);

// 方法1: 直接求解
Vector3d x1 = A.colPivHouseholderQr().solve(b);

// 方法2: LU 分解求解
Vector3d x2 = A.partialPivLu().solve(b);

// 方法3: Cholesky 分解(适用于对称正定矩阵)
Vector3d x3 = A.llt().solve(b);

std::cout << "解 x: " << x1.transpose() << std::endl;
std::cout << "验证 Ax = " << (A * x1).transpose() << std::endl;

return 0;
}

几何变换

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

int main() {
// 旋转矩阵
AngleAxisd rotation(M_PI/4, Vector3d::UnitZ()); // 绕Z轴旋转45度
Matrix3d R = rotation.toRotationMatrix();

// 平移向量
Vector3d t(1, 2, 3);

// 齐次变换矩阵
Matrix4d T = Matrix4d::Identity();
T.block<3,3>(0,0) = R;
T.block<3,1>(0,3) = t;

// 变换点
Vector3d point(1, 0, 0);
Vector4d point_homo;
point_homo << point, 1;
Vector4d transformed = T * point_homo;

std::cout << "原始点: " << point.transpose() << std::endl;
std::cout << "变换后: " << transformed.head<3>().transpose() << std::endl;

return 0;
}

动态矩阵操作

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

int main() {
// 动态大小矩阵
int rows = 4, cols = 3;
MatrixXd dynamic_matrix(rows, cols);

// 填充矩阵
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
dynamic_matrix(i, j) = i * cols + j + 1;
}
}

// 矩阵切片和块操作
MatrixXd block = dynamic_matrix.block(1, 1, 2, 2); // 从(1,1)开始的2x2块
VectorXd row = dynamic_matrix.row(0); // 第0行
VectorXd col = dynamic_matrix.col(1); // 第1列

std::cout << "动态矩阵:\n" << dynamic_matrix << std::endl;
std::cout << "2x2块:\n" << block << std::endl;
std::cout << "第0行: " << row.transpose() << std::endl;

return 0;
}

编译方法