天天看点

使用std:sort和Eigen根据矩阵某一行/列元素对矩阵的行/列排序

文章目录

      • 1.对向量排序
      • 2.根据行列元素对行列排序

1.对向量排序

Eigen 为线性代数库,提供了一般的矩阵和向量的操作,以及诸多数值线性代数等算法。但是没有类似于Matlab的sort函数那样对向量或矩阵进行排序函数。在这里,借助于标准库算法sort,可以实现排序功能。

标准库中函数std::sort的用法有以下两种:

  • sort(beg,end)

  • sort(beg,end,comp)

其中beg表示指向首元素的指针或迭代器,end表示“尾后迭代器”(指向最后一个元素的下一个位置的迭代器)或指向最后一个元素的下一个位置的指针。comp表示一个返回bool值的表达式或者"可调用对象",即谓词。对于sort(beg,end)版本,默认采用<运算符进行比较。对于sort(beg,end,comp),则采用comp中定义的行为规则进行比较。

#include<iostream>
#include<algorithm>
#include<Eigen/Eigen>
using namespace std;
using namespace Eigen;

/**对向量进行排序,从大到小
 * vec: 待排序的向量
 * sorted_vec: 排序的结果
 * ind: 排序结果中各个元素在原始向量的位置
 */
void sort_vec(const VectorXd& vec, VectorXd& sorted_vec,  VectorXi& ind){
  ind=VectorXi::LinSpaced(vec.size(),0,vec.size()-1);//[0 1 2 3 ... N-1]
  auto rule=[vec](int i, int j)->bool{
    return vec(i)>vec(j);
  };//正则表达式,作为sort的谓词
  std::sort(ind.data(),ind.data()+ind.size(),rule);
  //data成员函数返回VectorXd的第一个元素的指针,类似于begin()
  sorted_vec.resize(vec.size());
  for(int i=0;i<vec.size();i++){
    sorted_vec(i)=vec(ind(i));
  }
}
//测试
int main(){
  VectorXd x(5);
  x<<3,4,1,5,6;
  VectorXi ind;
  VectorXd sorted_vec;
  sort_vec(x,sorted_vec,ind);
  cout<<"原始向量:\n";
  cout<<x<<endl<<endl;
  cout<<"排序后:\n";
  cout<<sorted_vec<<endl<<endl;
  cout<<"排序后向量各元素对应的原始向量中的位置"<<endl;
  cout<<ind<<endl;

  return 0;
}

           

编译时加上选项: -std=c++11

输出结果为:

原始向量:
3
4
1
5
6

排序后:
6
5
4
3
1

排序后向量各元素对应的原始向量中的位置
4
3
1
0
2

           

REF:https://blog.csdn.net/X_And_Y/article/details/83383520

2.根据行列元素对行列排序

本文展示了根据数组的第三列元素对数组的行进行升序排序:

void sort_vec(const MatrixXf& mtrx,MatrixXf& sorted_mtrx,VectorXi& ind){  
  ind = VectorXi::LinSpaced(mtrx.rows(),0,mtrx.rows()-1);
  auto rule=[mtrx](int i,int j)->bool
  {
    return mtrx(i,2)>mtrx(j,2);
  };
  sort(ind.data(),ind.data()+ind.size(),rule);
  //data成员函数返回VectorXd的第一个元素的指针,类似于begin()
  sorted_mtrx.resize(mtrx.rows(),mtrx.cols());
  for(int i=0;i<mtrx.rows();i++){
    sorted_mtrx.row(i)=mtrx.row(ind(i));
  }
}
           

测试:

#include <iostream>
#include <algorithm>
#include <Eigen/Core>

using namespace std;
using namespace Eigen;

int main(int argc,char** argv){
	MatrixXf a,a_sort;
    VectorXi ind;
    a.resize(3,3);
    a<<4,5,6,1,2,3,7,8,9;
    sort_vec(a,a_sort,ind);
    cout<<a<<endl;
    cout<<"-------"<<endl;
    cout<<a_sort<<endl;
}
           

输出结果:

4 5 6
1 2 3
7 8 9
-------
7 8 9
4 5 6
1 2 3
           

继续阅读