目录
1、矩阵的构造和初始化操作
2、矩阵的算术运算
3、矩阵的分解和求解
4、矩阵的变换
5、矩阵的访问和修改
6、矩阵遍历
7、线性方程组求解
8、其他操作
Eigen库是一个高级的C++库,用于线性代数,矩阵和向量运算,数值分析和相关的数学运算。这个库提供了大量的矩阵操作功能。
1、矩阵的构造和初始化操作
Eigen::Matrix3f A; // 创建一个3x3的双精度浮点型矩阵
A << 1, 2, 3,
4, 5, 6,
7, 8, 9;
cout<<"3X3 float: \n"<<A<<endl;
Eigen::MatrixXf m = Eigen::MatrixXf::Identity(3, 3); // 创建一个3x3的单位矩阵
cout<<"3X3 identity: \n"<<m<<endl;
Eigen::MatrixXf mf(3, 3); // 使用构造函数初始化,默认初始化为0
Eigen::MatrixXi mi(3, 3); // 创建一个3x3的整型矩阵,默认初始化为0
cout<<"3X3 mf: \n"<<mf<<endl;
cout<<"3X3 mi: \n"<<mi<<endl;
Eigen::MatrixXf z = Eigen::MatrixXf::Zero(3, 3); // 创建一个3x3的全0矩阵
Eigen::MatrixXi n = Eigen::MatrixXi::Ones(3, 3); // 创建一个3x3的全1矩阵
cout<<"3X3 Zero: \n"<<z<<endl;
cout<<"3X3 Ones: \n"<<n<<endl;
Eigen::MatrixXf r = Eigen::MatrixXf::Random(3, 3); // 创建一个3x3的随机矩阵
cout<<"3X3 random: \n"<<r<<endl;
float data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Eigen::Map<Eigen::MatrixXf> mp(data, 3, 3); // 将data数组映射为一个3x3的矩阵
cout<<"3X3 map mp: \n"<<mp<<endl;
Eigen::MatrixXf m_i(3, 3);
m_i = (Eigen::MatrixXf(3, 3)<<1, 2, 3, 4, 5, 6, 7, 8, 9).finished(); //对于动态大小的矩阵,可以使用逗号初始化器,但需要在初始化时指定大小
cout<<"initializer m_i: \n"<<m_i<<endl;
Eigen::MatrixXf m_c = m_i;
cout<<"copy constructor m_c : \n"<<m_c<<endl;
2、矩阵的算术运算
Eigen::MatrixXf m1 = Eigen::MatrixXf::Identity(3, 3);
Eigen::MatrixXf m2 = Eigen::MatrixXf::Identity(3, 3);
Eigen::Matrix3f sum = m1 + m2; // 矩阵加法
cout<<"sum : \n"<<sum<<endl;
Eigen::MatrixXf diff = m1 + m2; // 矩阵减法
cout<<"diff : \n"<<diff<<endl;
Eigen::MatrixXf scaled = m1 * 2.0f; // 矩阵与标量的乘法
cout<<"scaled : \n"<<scaled<<endl;
Eigen::MatrixXf product = m1 * m2.transpose(); // 矩阵乘法
cout<<"product : \n"<<product<<endl;
// 矩阵加法
Eigen::Matrix3f C = A + A;
// 矩阵乘法
Eigen::Matrix3f D = A * A.transpose();
// 向量加法
Eigen::Vector4f e = b + b;
// 点积(内积)
float dotProduct = b.dot(b);
// 转置
std::cout << "Transpose of A:\n" << A.transpose() << std::endl;
// 访问元素
std::cout << "Element (1, 1) of A: " << A(1, 1) << std::endl;
3、矩阵的分解和求解
Eigen::MatrixXf m1 = Eigen::Matrix3f::Random();
cout << "original matrix:\n" << m1 << endl;
// 对矩阵进行特征值分解
Eigen::EigenSolver<Eigen::Matrix3f> es(m1);
cout << "eigenvalues:\n" << es.eigenvalues() << endl;
cout << "eigenvectors:\n" << es.eigenvectors() << endl;
// 假设我们有一个线性方程组 Ax = b
Eigen::Vector3f b(1, 2, 3);
cout << "vector b:\n" << b << endl;
// 使用列主元QR分解求解线性方程组
Eigen::Vector3f x = m1.colPivHouseholderQr().solve(b);
cout << "Solution x:\n" << x << endl;
4、矩阵的变换
Eigen::MatrixXf m1 = Eigen::Matrix4f::Random();
cout << "original matrix:\n" << m1 << endl;
// 获取矩阵的转置
Eigen::Matrix4f transposed = m1.transpose();
cout << "transposed:\n" << transposed << endl;
// 获取矩阵的对角线元素
Eigen::Vector4f diagonal = m1.diagonal();
cout << "diagonal:\n" << diagonal << endl;
// 获取矩阵的逆(注意:需要先检查矩阵是否可逆)
if(m1.determinant() != 0) // 使用行列式检查是否可逆
{
// 求逆矩阵
Eigen::Matrix4f inv_m = m1.inverse();
cout << "inverse:\n" << inv_m << endl;
// 验证逆矩阵的正确性:m * inv_m 应该接近单位矩阵
Eigen::MatrixXf identity_check = m1 * inv_m;
cout << "identity check:\n" << identity_check << endl;
}
else
{
cerr << "Matrix is singular and cannot be inverted." << endl;
}
5、矩阵的访问和修改
Eigen::MatrixXf m1 = Eigen::Matrix4f::Random();
cout << "original matrix:\n" << m1 << endl;
// 取出前3行和前3列的子矩阵
Eigen::Matrix3f sub_matrix = m1.block(0, 0, 3, 3);
cout << "sub_matrix:\n" << sub_matrix << endl;
// 修改矩阵的元素
m1(1, 2) = 10; // 将第2行第3列的元素设置为10
// 访问矩阵的元素
cout << "Element at (1, 2): " << m1(1, 2) << endl;
// 访问矩阵的第2行
Eigen::Vector4f row = m1.row(1);
cout << "row 2: " << row << std::endl;
// 访问矩阵的第2列
Eigen::Vector4f col = m1.col(1);
cout << "col 2: " << col << std::endl;
Eigen::MatrixXf m2 = Eigen::Matrix3f::Random();
cout << "original matrix:\n" << m2 << endl;
// 创建一个4x4的矩阵,并初始化
Eigen::Matrix4f m4_4= Eigen::Matrix4f::Zero();
// 将3x3矩阵赋值给4x4矩阵的前3行和前3列
m4_4.block(0, 0, 3, 3) = m2;
cout << "4x4 matrix with 3x3 block assigned:\n" << m4_4 << endl;
//块操作
// 提取矩阵的第二列
Eigen::Vector3f column = A.col(1);
// 提取矩阵的前两行
Eigen::Matrix2f topRows = A.topRows(2);
6、矩阵遍历
3.1 使用迭代器遍历和打印
#include <iostream>
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd mat(3, 4);
mat << 1, 2, 3, 4,
5, 6, 7, 8,
9, 0, 1, 2;
// 遍历并打印矩阵的每一行
for (int row = 0; row < mat.rows(); ++row) {
for (Eigen::MatrixXd::RowIterator it = mat.row(row).begin(); it != mat.row(row).end(); ++it) {
std::cout << *it << ' ';
}
std::cout << '\n';
}
Eigen::VectorXd vec(5);
vec << 3, 6, 9, 12, 15;
// 遍历并打印向量的所有元素
for (Eigen::VectorXd::Iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << ' ';
}
std::cout << '\n';
return 0;
}
3.2 直接访问元素并打印
#include <iostream>
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd mat(3, 4);
mat << 1, 2, 3, 4,
5, 6, 7, 8,
9, 0, 1, 2;
// 遍历并打印矩阵的每一行
for (int row = 0; row < mat.rows(); ++row) {
for (int col = 0; col < mat.cols(); ++col) {
std::cout << mat(row, col) << ' ';
}
std::cout << '\n';
}
Eigen::VectorXd vec(5);
vec << 3, 6, 9, 12, 15;
// 遍历并打印向量的所有元素
for (int i = 0; i < vec.size(); ++i) {
std::cout << vec(i) << ' ';
}
std::cout << '\n';
return 0;
}
7、线性方程组求解
// 假设A是已知的系数矩阵,b是已知的右侧向量
Eigen::VectorXd x;
Eigen::MatrixXd A(3, 3);
Eigen::VectorXd b(3);
// ... 初始化A和b ...
// 使用LLT分解求解Ax=b
Eigen::LLT<Eigen::MatrixXd> llt(A);
if (llt.info() == Eigen::Success) {
x = llt.solve(b);
} else {
std::cerr << "LLT decomposition failed!" << std::endl;
}
// 输出解
std::cout << "Solution: " << x << std::endl;
8、其他操作
Eigen::Matrix3f m1; // 创建一个3x3的双精度浮点型矩阵
m1 << 1, 2, 3,
4, 5, 6,
7, 8, 9;
// 计算矩阵的Frobenius范数
float norm = m1.norm();
cout << "norm of the matrix: " << norm << endl;
Eigen::Matrix3f m2; // 创建一个3x3的双精度浮点型矩阵
m2 << 1, 2, 3,
4, 5, 6,
7, 8, 9.0001f;
// 检查两个矩阵是否近似相等(这里使用1e-5作为精度阈值)
bool are_approx = m1.isApprox(m2, 1e-5);
cout << "are m1 and m2 approximately equal? " << (are_approx ? "Yes" : "No") << endl;