如何在Eigen中直接获取并存储前x个特征值/特征向量
Eigen 直接获取前x个特征值/特征向量的方法
对称(自伴随)矩阵场景
Eigen对对称矩阵的特征值计算有原生优化,无需完整对角化就能直接提取指定数量的特征值/特征向量:
- 预先分配好存储结果的向量和矩阵,比如要取前x个最大特征值,就创建长度为x的向量和n×x的矩阵(n为原矩阵维度)。
- 使用
SelfAdjointEigenSolver的重载compute方法,传入原矩阵、计算选项,以及要提取的特征值数量。 - 注意
SelfAdjointEigenSolver默认按升序返回特征值,需通过tail(x)取最大的x个,再调整顺序(如果需要降序展示)。
代码示例:
#include <Eigen/Dense> #include <iostream> int main() { const int mat_dim = 5; // 原矩阵维度 const int top_k = 2; // 需要保留的特征值/特征向量数量 // 构造对称矩阵示例 Eigen::MatrixXd sym_mat(mat_dim, mat_dim); sym_mat << 1, 2, 3, 4, 5, 2, 6, 7, 8, 9, 3, 7, 10, 11, 12, 4, 8, 11, 13, 14, 5, 9, 12, 14, 15; // 预先创建存储结果的容器 Eigen::VectorXd top_eigenvalues(top_k); Eigen::MatrixXd top_eigenvectors(mat_dim, top_k); Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver; // 计算top_k个特征值及对应特征向量 solver.compute(sym_mat, Eigen::ComputeEigenvectors, top_k); // 提取最大的top_k个特征值(默认升序,取末尾top_k个后反转成降序) top_eigenvalues = solver.eigenvalues().tail(top_k).reverse(); // 对应提取特征向量并调整顺序 top_eigenvectors = solver.eigenvectors().rightCols(top_k).colwise().reverse(); std::cout << "前" << top_k << "个最大特征值:\n" << top_eigenvalues << "\n"; std::cout << "对应的特征向量矩阵:\n" << top_eigenvectors << "\n"; return 0; }
如果需要提取最小的x个特征值,把tail(x)换成head(x)即可,无需反转顺序。
非对称一般矩阵场景
对于非对称矩阵,Eigen原生的EigenSolver不支持部分对角化,需要借助ArpackSupport模块(需链接Arpack库)来实现:
- 引入
Eigen/ArpackSupport头文件。 - 使用
ArpackEigenSolver,通过第二个参数指定要提取的特征值类型(比如"LM"表示模最大的,"SM"表示模最小的),第三个参数指定数量。 - 直接提取结果到预先创建的容器中。
代码示例:
#include <Eigen/Dense> #include <Eigen/ArpackSupport> #include <iostream> int main() { const int mat_dim = 5; const int top_k = 2; // 构造非对称矩阵示例 Eigen::MatrixXd gen_mat(mat_dim, mat_dim); gen_mat << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25; Eigen::VectorXd top_eigenvalues(top_k); Eigen::MatrixXd top_eigenvectors(mat_dim, top_k); Eigen::ArpackEigenSolver<Eigen::MatrixXd> solver; // 提取模最大的top_k个特征值及特征向量 solver.compute(gen_mat, "LM", top_k); top_eigenvalues = solver.eigenvalues(); top_eigenvectors = solver.eigenvectors(); std::cout << "前" << top_k << "个最大模特征值:\n" << top_eigenvalues << "\n"; std::cout << "对应的特征向量矩阵:\n" << top_eigenvectors << "\n"; return 0; }
可用的特征值类型参数还有:"LR"(实部最大)、"SR"(实部最小)、"LI"(虚部最大)、"SI"(虚部最小)。
内容的提问来源于stack exchange,提问作者manne
相关产品推荐
相关产品推荐

