Eigen 初始化矩阵需用模板类(如 MatrixXd),尺寸编译期确定,动态尺寸用 Dynamic;须启用 C++11,避免整数存入 MatrixXd 导致精度丢失,逗号初始化后需调用 .finished()。

如何用 Eigen 初始化矩阵并做基础运算
Eigen 不需要编译安装,头文件直连就能用,但必须确保启用 C++11 或更高标准(-std=c++11)。矩阵对象是模板类,类型和尺寸在编译期确定,动态尺寸用 Dynamic 占位。
常见错误:用 MatrixXd 存整数导致隐式转换丢失精度;或忘记调用 .finished() 在逗号初始化器后。
MatrixXd A(3, 3); A —— 逗号初始化必须成行填满,否则行为未定义-
Vector3d v(1, 2, 3);错误:构造函数不接受参数列表,应写Vector3d v; v - 点乘用
v.dot(u),叉乘仅对Vector3d支持,用v.cross(u) - 矩阵乘法是
A * B,不是A.dot(B)(后者只对向量有效)
解线性方程组 Ax = b 的三种常用方式
别直接求逆(A.inverse() * b),既慢又数值不稳定。Eigen 提供多个分解策略,选错会导致运行时断言失败或结果偏差大。
场景判断优先级:先看矩阵是否对称正定 → 再看是否小规模(A。
立即学习“C++免费学习笔记(深入)”;
- 普通稠密矩阵(无特殊结构):用
A.colPivHouseholderQr().solve(b),鲁棒性强,支持秩亏 - 对称正定矩阵:用
A.llt().solve(b),速度最快,但输入必须严格满足条件,否则运行时报LLT decomposition failed - 需要反复解不同
b:预分解一次,如auto dec = A.lu();然后循环调用dec.solve(b_i)
计算特征值与特征向量的注意事项
特征分解不是总能成功。实矩阵的特征值可能是复数,而 SelfAdjointEigenSolver 只适用于实对称/复共轭对称矩阵;用错会静默返回错误结果(如全零特征向量)。
区分两个关键类:SelfAdjointEigenSolver(快、稳定、要求对称)和 ComplexEigenSolver(通用但慢、结果含复数)。
- 对称矩阵:必须先确保
A.isApprox(A.transpose())成立,再用SelfAdjointEigenSolvereig(A); - 非对称矩阵:用
EigenSolver,特征值在eig(A); eig.eigenvalues()中是VectorXcd类型,不能直接取实部 - 提取最大特征向量:别用
eig.eigenvectors().col(0),索引不按模排序;应遍历eig.eigenvalues()找模最大的下标再取列
性能与内存布局的关键细节
Eigen 默认列优先(column-major),和 Fortran、LAPACK 一致,但和 OpenCV、NumPy 默认行优先相反。混用时若不做拷贝或转置,数据会错位。
大矩阵运算易触发缓存失效,.noalias() 和表达式模板虽自动优化,但显式标注可避免临时对象:
- 避免
C = A * B + C;(产生临时矩阵),改用C.noalias() += A * B; - 从 OpenCV
cv::Mat构造 Eigen 矩阵时,若原图是行优先,必须先.t()或用Map指定RowMajor标签 - 释放大矩阵内存:Eigen 不管理堆内存生命周期,
MatrixXd析构时自动free,但若用Map包装外部内存,别让 Eigen 对象活得比原始内存久
#includeusing namespace Eigen; int main() { MatrixXd A = MatrixXd::Random(3,3); // 正确:对称化后再特征分解 A = (A + A.transpose()) * 0.5; SelfAdjointEigenSolver eig(A); std::cout << "Eigenvalues:\n" << eig.eigenvalues() << "\n"; return 0; }
Eigen 的多数问题不出在“会不会写”,而出在“没意识到矩阵性质是否匹配所选求解器”。对称性、正定性、规模、内存布局——这四个点漏掉任何一个,都可能让结果看起来正常却完全错误。











