[英]How to remove a certain row or column while using Eigen Library c++
我正在为我的项目使用 Eigen 库。 我正在搜索如何从 Eigen 中的给定矩阵中删除某个行或列。 我没有成功。
MatrixXd A = X1 X2 X3 X4
Y1 Y2 Y3 Y4
Z1 Z2 Z3 Z4
A1 A2 A3 A4
MatrixXd Atransform = X1 X2 X4
Y1 Y2 Y4
Z1 Z2 Z4
A1 A2 A4
enter code here
除了遍历整个矩阵或对矩阵 A 使用块操作之外。 有没有一种方法可以简单地做到这一点。
使用块函数会更简洁一些:
void removeRow(Eigen::MatrixXd& matrix, unsigned int rowToRemove)
{
unsigned int numRows = matrix.rows()-1;
unsigned int numCols = matrix.cols();
if( rowToRemove < numRows )
matrix.block(rowToRemove,0,numRows-rowToRemove,numCols) = matrix.block(rowToRemove+1,0,numRows-rowToRemove,numCols);
matrix.conservativeResize(numRows,numCols);
}
void removeColumn(Eigen::MatrixXd& matrix, unsigned int colToRemove)
{
unsigned int numRows = matrix.rows();
unsigned int numCols = matrix.cols()-1;
if( colToRemove < numCols )
matrix.block(0,colToRemove,numRows,numCols-colToRemove) = matrix.block(0,colToRemove+1,numRows,numCols-colToRemove);
matrix.conservativeResize(numRows,numCols);
}
通过使用 Eigen 3.3.0+(2016.08 发布),您可以更轻松、更短地完成此操作:
vector<int> indicesToKeep = vector<int>{ 1, 2, 3 };
VectorXi indicesToKeepVector = VectorXi(indicesToKeep.data(), indicesToKeep.size());
MatrixXf matrix = MatrixXf(); // your data should be here!
matrix = matrix(Eigen::placeholders::all, indicesToKeepVector); // select columns you want to keep(indicesToKeep), discard others
matrix = matrix(indicesToKeepVector, Eigen::placeholders::all); // select rows you want to keep(indicesToKeep), discard others
matrix = matrix(Eigen::seq(5, 10), Eigen::placeholders::all); // keep rows from 5 to 10
matrix = matrix(Eigen::placeholders::all, Eigen::seq(5, 10)); // keep columns from 5 to 10
matrix = matrix(Eigen::seqN(5, 5), Eigen::placeholders::all); // keep rows from 5 to 10
matrix = matrix(Eigen::placeholders::all, Eigen::seqN(5, 5)); // keep columns from 5 to 10
要改进 Andrew 的回答,请使用 bottomRows/rightCols。
void removeRow(Eigen::MatrixXd& matrix, unsigned int rowToRemove)
{
unsigned int numRows = matrix.rows()-1;
unsigned int numCols = matrix.cols();
if( rowToRemove < numRows )
matrix.block(rowToRemove,0,numRows-rowToRemove,numCols) = matrix.bottomRows(numRows-rowToRemove);
matrix.conservativeResize(numRows,numCols);
}
void removeColumn(Eigen::MatrixXd& matrix, unsigned int colToRemove)
{
unsigned int numRows = matrix.rows();
unsigned int numCols = matrix.cols()-1;
if( colToRemove < numCols )
matrix.block(0,colToRemove,numRows,numCols-colToRemove) = matrix.rightCols(numCols-colToRemove);
matrix.conservativeResize(numRows,numCols);
}
您可能会发现以下静态版本更适合某些用途(并且更符合 Eigen 编译时效率的精神)。 在这种情况下,您将创建一个没有行的新矩阵。 可以使用.leftCols() .rightCols()
为列构造类似的函数
template<typename T>
inline constexpr auto removeRow(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& matrix, const int& rowNum)
{
return (Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>(matrix.rows() - 1, matrix.cols())
<< static_cast<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>(matrix.topRows(rowNum - 1)),
static_cast<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>(matrix.bottomRows(matrix.rows() - rowNum))).finished();
}
享受!
我知道这是一个老问题,但似乎现在的本征支持创建索引通过行和列定义的子矩阵: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=329 HTTP://征。 tuxfamily.org/dox-devel/classEigen_1_1DenseBase.html#a0b44220621cd59a75cd0f48cc499518f
它似乎不在文档中......
inline Eigen::MatrixXd removeMatrixRow(const Eigen::MatrixXd original_matrix, const int row_to_remove)
{
// New matrix has one fewer rows
Eigen::MatrixXd new_matrix(original_matrix.rows()-1, original_matrix.cols());
// Track rows in new matrix. Skip one at row_to_remove.
int row_to_fill = 0;
for (int orig_matrix_row = 0; orig_matrix_row < original_matrix.rows(); ++orig_matrix_row)
{
if (orig_matrix_row != row_to_remove)
{
new_matrix.row(row_to_fill) = original_matrix.row(orig_matrix_row);
++row_to_fill;
}
}
return new_matrix;
}
我对 C++ 很陌生,但这段代码适用于可能的应用程序。
它仅适用于完整的动态矩阵,但可以适应它。
如果有人有更好的方法,请告诉我我真的很想学习。
template<typename ScalarType>
void MatrixXdRemoveCol(Eigen::Matrix<ScalarType,-1,-1,0,-1,-1> *mat, int colindex)
{
Eigen::Matrix<ScalarType,-1,-1,0,-1,-1> *auxmat = new Eigen::Matrix<ScalarType,-1,-1,0,-1,-1>;
*auxmat = *mat;
mat->resize(mat->rows(),mat->cols()-1);
int rightColsSize = auxmat->cols()-colindex-1;
mat->leftCols(colindex) = auxmat->leftCols(colindex);
mat->rightCols(rightColsSize) = auxmat->rightCols(rightColsSize);
}
template<typename ScalarType>
void MatrixXdRemoveCols(Eigen::Matrix<ScalarType,-1,-1,0,-1,-1> *mat, std::vector<int>* cols)
{
for(auto iter = cols->rbegin();iter != cols->rend();iter++)
MatrixXdRemoveCol<ScalarType>(mat,*iter);
}
template<typename ScalarType>
void MatrixXdRemoveRow(Eigen::Matrix<ScalarType,-1,-1,0,-1,-1> *mat, int rowindex)
{
Eigen::Matrix<ScalarType,-1,-1,0,-1,-1> *auxmat = new Eigen::Matrix<ScalarType,-1,-1,0,-1,-1>;
*auxmat = *mat;
mat->resize(mat->rows()-1,mat->cols());
int BottomRowsSize = auxmat->rows()-rowindex-1;
mat->topRows(rowindex) = auxmat->topRows(rowindex);
mat->bottomRows(BottomRowsSize) = auxmat->bottomRows(BottomRowsSize);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.