天天看點

使用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
           

繼續閱讀