按列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的值是已知的并且是固定的,如果这有帮助的话。
答
这并不美观,并且依靠使用其模板参数挑选矩阵 - 但它有效。
#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
或更好的编译方式。
答
我想出了最好的解决办法是把行复制到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;
}
感谢,我去了这一点,然后尽快给您 – user1420
你不不需要做这个过于复杂的模板材料;一个简单的'Eigen :: MatrixXd'就可以做到。 – xjcl