2016-09-26 59 views
1

我在Eigen中有一個n×3矩陣。我想通過按升序對第一列中的值進行排序來重新排列第二列和第三列的值。 E.g排序前:按列1值的升序對本徵矩陣列值進行排序

1 4 6 
-2 5 2 
    3 1 0 

根據第1倍的值的升序排序後:

-2 5 2 
    1 4 6 
    3 1 0 

我在如何處理這一損失。我可以將每列讀入一個向量,並使用std :: sort對列1向量進行排序,但是我沒有看到如何在第2列和第3列中保留列1中排序值的相應值.n的值是已知的並且是固定的,如果這有幫助的話。

回答

1

這並不美觀,並且依靠使用其模板參數挑選矩陣 - 但它有效。

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

// Simple little templated comparison functor 
template <typename MatrixT> 
bool compareRows(MatrixT a, MatrixT b) { 
    return a(0,0) < b(0,0); 
} 

// These are the 6 template arguments to every Eigen matrix 
template <typename Scalar, int rows, int cols, int options, int maxRows, int maxCols> 
Eigen::Matrix<Scalar, rows, cols, options, maxRows, maxCols> sortMatrix(
    Eigen::Matrix<Scalar, rows, cols, options, maxRows, maxCols> target 
) { 
    // Manually construct a vector of correctly-typed matrix rows 
    std::vector<Eigen::Matrix<Scalar, 1, cols>> matrixRows; 
    for (unsigned int i = 0; i < target.rows(); i++) 
      matrixRows.push_back(target.row(i)); 
    std::sort(
      matrixRows.begin(), 
      matrixRows.end(), 
      compareRows<Eigen::Matrix<Scalar, 1, cols>> 
    ); 

    Eigen::Matrix<Scalar, rows, cols, options, maxRows, maxCols> sorted; 
    for (unsigned int i = 0; i < matrixRows.size(); i++) 
      sorted.row(i) = matrixRows[i]; 
    return sorted; 
} 

值得慶幸的是,由於模板參數推導,你可以簡單地調用這個搞成這個樣子:

Eigen::Matrix3f myMatrix; 
// Fill in contents here 
Eigen::Matrix3f sorted = sortMatrix(myMatrix); 

,我幾乎可以肯定有一個更優雅的方式來做到這一點,但我不能現在想想它。而且,因爲它使用std::vector,所以需要使用-std=c++11或更好的編譯方式。

+0

感謝,我去了這一點,然後儘快給您 – user1420

+0

你不不需要做這個過於複雜的模板材料;一個簡單的'Eigen :: MatrixXd'就可以做到。 – xjcl

0

我想出了最好的解決辦法是把行復制到std::vector,然後去到排序:

#include <Eigen/Core> 
#include <algorithm> // std::sort 
#include <vector>  // std::vector 

bool compare_head(const Eigen::VectorXd& lhs, const Eigen::VectorXd& rhs) 
{ 
    return lhs(0) < rhs(0); 
} 

Eigen::MatrixXd sorted_rows_by_head(Eigen::MatrixXd A_nx3) 
{ 
    std::vector<Eigen::VectorXd> vec; 
    for (int64_t i = 0; i < A_nx3.rows(); ++i) 
     vec.push_back(A_nx3.row(i)); 

    std::sort(vec.begin(), vec.end(), &compare_head); 

    for (int64_t i = 0; i < A_nx3.rows(); ++i) 
     A_nx3.row(i) = vec[i]; 

    return A_nx3; 
}