按升序排序特征向量Xf

时间:2014-02-17 17:17:56

标签: c++ eigen

我正在尝试按升序排序Eigen VectorXf x

按降序对其进行排序:

std::sort(x.data(),x.data()+x.size());

这不起作用:

bool myfunction (int i,int j) { return (i<j); }
std::sort(x.data(),x.data()+x.size(),myfunction);

任何想法?

3 个答案:

答案 0 :(得分:7)

前言
由于最初的问题被证明是一个误解,并且其中的代码已经是正确的答案,我决定写一些关于一般使用std::sort的帖子。

std::sort按照元素的弱排序定义的升序排序。默认情况下,它使用在元素上定义的<运算符,但它也可以使用函数对象或函子来提供比较。这个仿函数需要使用bool operator()(const T& lhs, const T& rhs) const的签名正确重载函数。以下是一个例子:

struct FooSorter {
    bool operator (const Foo& lhs, const Foo& rhs) const {
        return lhs.ham_index < rhs.ham_index;
    }
};
/* ... */
std::sort(begin(vec), end(vec), FooSorter());

根据FooSorter operator()中定义的标准,这将对vec表示的整个范围进行排序。

因为为简单事物编写自定义仿函数(按降序排序,按升序排序)会很快变得痛苦,STL提供了许多模板仿函数,可以在functional标题中使用。与分类相关的一个是:

  • std::equal_to实施x == y

  • std::not_equal_to实施x!= y

  • std::greater实施x&gt; y

  • std::less实施x&lt; y

  • std::greater_equal实施x&gt; = y

  • std::less_equal实施x&lt; = y

所有这些都是模板化的,可以用于实现所需操作符的任何类型。使用这些很容易:

std::sort(begin(vec), end(vec), std::greater<int>());

这将按矢量降序排列范围。

但是,由于STL算法的一个最大问题是定义仿函数的痛苦,C ++ 11带来了一个新技巧:lambda functions。这允许您声明函数对象等效内联。示例如下:

std::sort(begin(vec), end(vec), [](int lhs, int rhs){return rhs > lhs});

这也会按照降序对vector表示的范围进行排序,但我们不必显式声明一个仿函数(或者使用已经声明的仿函数)。 (当实现更复杂的比较或不同STL算法的仿函数时,这会变得更好。)

答案 1 :(得分:1)

如果有人在寻找答案,请点击这里。这样,您就可以获得特征值和相应的特征向量。在这里, covariance_matrix 是要求解特征值和特征向量的矩阵。

    std::vector<std::tuple<float, Eigen::VectorXf>> eigen_vectors_and_values; 

    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigensolver(covariance_matrix);
    if (eigensolver.info() != Eigen::Success) {
        return;
    }
    Eigen::VectorXf eigen_values = eigensolver.eigenvalues();
    Eigen::MatrixXf eigen_vectors = eigensolver.eigenvectors();
    for(int i=0; i<eigen_values.size(); i++){
        std::tuple<float, Eigen::VectorXf> vec_and_val(eigen_values[i], eigen_vectors.row(i));
        eigen_vectors_and_values.push_back(vec_and_val);
    }
    std::sort(eigen_vectors_and_values.begin(), eigen_vectors_and_values.end(), 
        [&](const std::tuple<float, Eigen::VectorXf>& a, const std::tuple<float, Eigen::VectorXf>& b) -> bool{ 
            return std::get<0>(a) < std::get<0>(b); 
    });

注意:选择要使用的本征求解器时要小心。您可以在这里找到要使用的哪个:https://eigen.tuxfamily.org/dox/group__Eigenvalues__Module.html

答案 2 :(得分:0)

感谢此完整的答案对特征值和特征向量进行排序。返回row()是否正确

std::tuple<float, Eigen::VectorXf> vec_and_val(eigen_values[i], eigen_vectors.row(i));

根据documentation of Eigen中的说明,它应该是col()