Sort eigenvector Xf in ascending order

I am trying to sort Eigen VectorXf x in ascending order.

This sorts it in descending order:

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

and this does not work:

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

any ideas?

+9
source share
3 answers

Foreword
Since the original question turned out to be a misunderstanding, and the code in it is already the correct answer, I decided to write and publish a little about using std::sort in general.

std::sort sorts the range in ascending order, determined by the weak ordering of the elements. By default, it uses the < operator defined on elements, but it can also take a function object or functor to provide a comparison. This functor must have a properly overloaded function with the signature bool operator()(const T& lhs, const T& rhs) const . An example of this follows:

 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()); 

This would sort the full range represented by vec according to the criteria defined in the FooSorter operator() .

Since writing user-defined functions for simple things (sorting in decreasing order, sorting in increasing order) will quickly become painful, STL provides many template functors ready for use in functional . The following values โ€‹โ€‹are important for sorting:

  • std::equal_to implementation x == y

  • std::not_equal_to implementation x! = y

  • std::greater implementation x> y

  • std::less implementation x <y

  • std::greater_equal implementation x> = y

  • std::less_equal implementation x <= y

They are all templates and can be used for any type that implements the necessary operators. Using them is easy:

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

This sorts the range represented by the vector in descending order.

But, since one of the biggest problems with STL algorithms was the pain of defining functors, C ++ 11 brings a new trick: lambda functions . This allows you to declare a functional object equivalent to a built-in one. Example:

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

It also sorts the range represented by the vector in descending order, but we donโ€™t need to explicitly declare a functor (or use an already declared functor). (This gets much better when implementing much more complex comparisons or functors for different STL algorithms.)

+7
source

If someone is looking for an answer, here is how I did it. Thus, you can get eigenvalues โ€‹โ€‹and corresponding eigenvectors. Here covariance_matrix is a matrix in which eigenvalues โ€‹โ€‹and eigenvectors must be solved.

  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); }); 

Note: be careful when choosing which eigensolver will be used. You can find here which one to use: https://eigen.tuxfamily.org/dox/group__Eigenvalues__Module.html

+1
source

Thanks for this complete answer for sorting both eigenvalues โ€‹โ€‹and eigenvectors. Is it true to return row () in

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

From what is indicated in the Eigen documentation , there should be col ()

0
source

All Articles