特征-排序矩阵对角线

Eigen - Sort matrix diagonal

本文关键字:对角线 排序 特征      更新时间:2023-10-16

我得到的是类型为Eigen::MatrixXi的对角矩阵。我需要对角线上的元素按升序排序。例如:

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

我想我会简单地做:

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

但显然Eigen::Diagonal没有开始和结束功能。问题是,有没有一种方法可以对对角线上的元素进行排序使用内部std::sort或其他类似的优雅方法?

我看了一遍官方文件,但没有发现任何有用的。

目前还没有对矩阵排序的本机支持。有两个与此功能相关的长时间未处理的特性请求:

    Bug 231 - STL兼容迭代器
  • Bug 299 -矩阵和向量的排序函数也返回索引

正如@NicolasM在评论中建议的那样,目前最优雅的解决方案是自己提供自定义迭代器,例如:

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

我想说的是这样的。

void insertion_sort(int arr[3][3], int length) {
int i, j, tmp;
for (i = 1; i < length; i++) {
    j = i;
    while (j > 0 && arr[j - 1][j- 1] > arr[j][j]) {
        tmp = arr[j][j];
        arr[j][j] = arr[j - 1][j - 1];
        arr[j - 1][j - 1] = tmp;
        j--;
    }       
}
}
int main() {    
int a[3][3] = { { 2, 0, 0 }, { 0, 7, 0 }, { 0, 0, 1 } };
insertion_sort(a, 3);
for (int i = 0; i < 3; ++i)
{
    for (int j = 0; j < 3; ++j)
        cout << a[i][j] << " ";
    cout << endl;
}

我使用插入排序是因为它很容易实现。