sort eigen vectorXf in ascending order

user189035 picture user189035 · Feb 17, 2014 · Viewed 11.8k times · Source

I'm trying to sort an Eigen VectorXf x in ascending order.

This sorts it in descending order:

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

and this doesn't work:

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

any ideas?

Answer

Xarn picture Xarn · Feb 17, 2014

Preface
Since the original question turned out to be a misunderstanding, and the code in it is already the proper answer, I decided to write up and post a bit about using std::sort in general.

std::sort sorts range in ascending order defined by weak ordering of the elements. By default it uses < operator defined on elements, but it can also take a function object or functor to provide the comparison. This functor needs to have properly overloaded function with signature of 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 criteria defined in FooSorter's operator().

Because writing custom functors for the simple things (sort in descending order, sort in ascending order) would quickly grow painful, STL provides many templated functors ready to use in functional header. The one relevant for sorting are:

  • std::equal_to implementing x == y

  • std::not_equal_to implementing x != y

  • std::greater implementing x > y

  • std::less implementing x < y

  • std::greater_equal implementing x >= y

  • std::less_equal implementing x <= y

All of these are templated and can be used for any type, that implements needed operators. Using these is easy:

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

This would sort the range represented by vector in descending order.

But, since one of the biggest problems of STL algorithms was the pain of defining functors, C++11 brings a new trick: lambda functions. This lets you declare function object equivalent inline. Example follows:

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

This would also sort the range represented by vector in descending order, but we didn't have to explicitly declare a functor (or use already declared one). (This gets much better when implementing much more complex comparisons, or functors for different STL algorithms.)