You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eigen特征向量按特征值排序:std::sort测试可用VS2015编译失败

在Eigen中按特征值对特征向量排序(适配VS2015)

我之前也踩过VS2015下Eigen特征向量排序的编译坑,结合你提到的「按特征值排序→记录顺序→重排特征向量」的核心思路,给你一个能在VS2015中正常编译运行的实现方案:

核心思路拆解

你说的逻辑完全正确:

  • 第一步:获取特征值数组和对应的特征向量矩阵
  • 第二步:对特征值进行排序,同时记录每个特征值原来的索引位置
  • 第三步:根据记录的索引,重新排列特征向量矩阵的列(Eigen中每个特征向量对应矩阵的一列)

适配VS2015的完整实现

VS2015对C++11的部分特性支持有细节限制(比如不能直接在std::sort中捕获Eigen容器的引用),所以我们用索引数组排序的方式来规避这个问题:

#include <Eigen/Dense>
#include <algorithm>
#include <vector>

// 按特征值降序排序特征向量(要升序的话,把>改成<即可)
void sortEigenvectorsByEigenvalues(Eigen::MatrixXd& eigenvectors, Eigen::VectorXd& eigenvalues) {
    // 创建索引数组,初始为0,1,2,...,n-1
    std::vector<int> indices(eigenvalues.size());
    for (int i = 0; i < indices.size(); ++i) {
        indices[i] = i;
    }

    // 按特征值大小对索引排序(降序)
    std::sort(indices.begin(), indices.end(),
        [&eigenvalues](int a, int b) {
            return eigenvalues(a) > eigenvalues(b);
        });

    // 根据排序后的索引,重新排列特征向量矩阵和特征值向量
    Eigen::MatrixXd sortedEigenvectors = eigenvectors;
    Eigen::VectorXd sortedEigenvalues = eigenvalues;
    for (int i = 0; i < indices.size(); ++i) {
        sortedEigenvectors.col(i) = eigenvectors.col(indices[i]);
        sortedEigenvalues(i) = eigenvalues(indices[i]);
    }

    // 替换原矩阵和向量
    eigenvectors.swap(sortedEigenvectors);
    eigenvalues.swap(sortedEigenvalues);
}

// 测试代码
int main() {
    // 构造一个对称矩阵用于测试
    Eigen::MatrixXd mat(3, 3);
    mat << 1, 2, 3,
           2, 4, 5,
           3, 5, 6;

    // 对称矩阵用SelfAdjointEigenSolver更高效
    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(mat);
    Eigen::MatrixXd eigenvectors = solver.eigenvectors();
    Eigen::VectorXd eigenvalues = solver.eigenvalues();

    std::cout << "排序前特征值:\n" << eigenvalues << "\n\n";
    std::cout << "排序前特征向量矩阵:\n" << eigenvectors << "\n\n";

    // 调用排序函数
    sortEigenvectorsByEigenvalues(eigenvectors, eigenvalues);

    std::cout << "排序后特征值(降序):\n" << eigenvalues << "\n\n";
    std::cout << "排序后特征向量矩阵:\n" << eigenvectors << "\n";

    return 0;
}

针对VS2015的编译注意事项

  • 确保项目开启C++11支持:右键项目→属性→C/C→语言→C标准,选择ISO C++11 标准 (/std:c++11)
  • 如果是非对称矩阵,不要用SelfAdjointEigenSolver,改用EigenSolver,注意此时特征值可能是复数,需要调整排序逻辑(比如按实部大小排序)

关于你提到的测试代码补充

你写的结构体测试逻辑和我们的索引排序思路完全匹配,只是把结构体换成了特征值的索引和对应值:

#include <algorithm>
struct a { double num1; int num2; };
bool acompare(a lhs, a rhs) {
    return lhs.num1 > rhs.num1; // 按num1降序排序
}

内容的提问来源于stack exchange,提问作者user3533030

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:45:05