Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eigen - Sort matrix diagonal

Tags:

c++

sorting

eigen

What I have is diagonal matrix of type Eigen::MatrixXi. I need elements on the diagonal to be sorted in ascending order. For example like this:

2 0 0      1 0 0
0 7 0  >>> 0 2 0
0 0 1      0 0 7

I thought I would simply do:

std::sort(matrix.diagonal().begin(), matrix.diagonal().end());

But apparently Eigen::Diagonal does not have begin nor end function. So the question is, is there any way of sorting elements on diagonal using internal std::sort or anything similarly elegant?

I went through official documentation but did not find anything useful.

like image 671
Jendas Avatar asked Aug 16 '14 16:08

Jendas


1 Answers

There is no native support for sorting matrices as of today. There are two long-pending feature requests relevant to this functionality:

  • Bug 231 - STL compatible iterators
  • Bug 299 - Sort function for matrices and vectors returning indices as well

As suggested by @NicolasM in the comments, currently, the most elegant solution is to provide custom iterators yourself, e.g.:

namespace Eigen {
  template<typename Scalar>
  class iterator {
    Scalar* ptr;
    int stride;
  public: 
    iterator(Scalar* ptr_, int stride_) : ptr(ptr_), stride(stride_) {}
    Scalar& operator*() const { return *ptr;}
    iterator& operator++() { ptr += stride; return *this;}
    bool operator<(const iterator& other) { return ptr < other.ptr; }
    // implement further operations, required for random access iterators ...
  }

  template<class Derived>
  iterator begin(MatrixBase<Derived>&& mat)
  { return iterator(mat.data(), mat.innerStride()); }
  template<class Derivde>
  iterator end(MatrixBase<Derived>&& mat)
  { return iterator(mat.data() + mat.size()*mat.innerStride(), mat.innerStride()); }

} // namespace Eigen
like image 145
chtz Avatar answered Sep 23 '22 08:09

chtz