std:sortとEigenを使用して、マトリクスの行/列要素に基づいてマトリクスの行/列をソートします.


文書ディレクトリ
  • 1.ベクトルのソート
  • 2.行列要素による行列のソート


  • 1.ベクトルのソート
    Eigenは線形代数ライブラリであり,一般的な行列とベクトルの動作,および多くの数値線形代数などのアルゴリズムを提供する.しかしMatlabのsort関数のようにベクトルや行列を並べ替える関数はない.ここで、標準ライブラリアルゴリズムsortにより、ソート機能を実現することができる.
    標準ライブラリの関数std::sortの使い方は次の2つです.
  • sort(beg,end)
  • sort(beg,end,comp)

  • ここでbegは、最初の要素を指すポインタまたは反復器を表し、endは、最後の要素の次の位置を指す反復器または最後の要素の次の位置を指すポインタを表す.compはbool値を返す式または「呼び出し可能なオブジェクト」、すなわち述語を表す.sort(beg,end)バージョンの場合、デフォルトでは
    #include
    #include
    #include
    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<<"    :
    "
    ; cout<<x<<endl<<endl; cout<<" :
    "
    ; 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.行列要素による行列のソート
    配列の3番目の列要素に基づいて配列の行を昇順にソートする方法を示します.
    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 
    #include 
    #include 
    
    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