C++ 如何在使用特征库c+时删除特定行或列+;

C++ 如何在使用特征库c+时删除特定行或列+;,c++,eigen,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

我正在为我的项目使用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使用块运算。是否有一个简单的方法?

< p>我在C++中很新,但是这个代码在5应用程序中工作。 它只适用于全动态矩阵,但可以对其进行调整

如果有人有更好的方法,请告诉我我真的很想学习

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);
}
模板
无效矩阵xxdRemoveCol(特征::矩阵*mat,int colindex)
{
本征::矩阵*auxmat=新的本征::矩阵;
*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);
}
模板
无效矩阵xxdRemoveCols(特征::矩阵*mat,标准::向量*cols)
{
对于(自动iter=cols->rbegin();iter!=cols->rend();iter++)
MatrixDremoveCol(mat,*iter);
}
模板
无效矩阵XXDREMOVEROW(特征::矩阵*矩阵,整数行索引)
{
本征::矩阵*auxmat=新的本征::矩阵;
*auxmat=*mat;
mat->resize(mat->rows()-1,mat->cols());
int BottomRowsSize=auxmat->rows()-rowindex-1;
mat->topRows(行索引)=auxmat->topRows(行索引);
mat->bottomRows(bottomrowsize)=auxmat->bottomRows(bottomrowsize);
}

使用块函数有点干净:

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);
}
void-remove-ow(特征::矩阵xxd&matrix,无符号整数行移动)
{
unsigned int numRows=matrix.rows()-1;
unsigned int numCols=matrix.cols();
如果(行移动
要改进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);
}
void-remove-ow(特征::矩阵xxd&matrix,无符号整数行移动)
{
unsigned int numRows=matrix.rows()-1;
unsigned int numCols=matrix.cols();
如果(行移动
对于某些用途,您可能会发现以下静态版本更好(并且更符合Eigen编译时效率的精神)。在这种情况下,您将创建一个没有行的新矩阵。可以使用
.leftCols().rightCols()为列构造类似的函数。

模板
内联constexpr自动删除(const-Eigen::Matrix&Matrix,const-int&rowNum)
{
返回(Eigen::Matrix(Matrix.rows()-1,Matrix.cols())

我知道这是一个老问题,但似乎Eigen现在支持创建由索引的行和列定义的子矩阵:


它只是不在文档中,似乎…

通过使用Egeng 3.3.0+(2016.08发布),您可以做得更简单、更简短:

vector indicesToKeep=向量{1,2,3};
VectorXi indicesToKeepVector=VectorXi(indicesToKeep.data(),indicesToKeep.size());
MatrixXf matrix=MatrixXf();//您的数据应该在这里!
矩阵=矩阵(特征::占位符::all,indicesToKeepVector);//选择要保留的列(indicesToKeep),放弃其他列
矩阵=矩阵(indicesToKeepVector,Eigen::占位符::all);//选择要保留的行(indicesToKeep),放弃其他行
矩阵=矩阵(本征::seq(5,10),本征::占位符::all);//将行从5保留到10
矩阵=矩阵(特征::占位符::all,特征::seq(5,10));//将列从5保留到10
矩阵=矩阵(本征::seqN(5,5),本征::占位符::all);//将行从5保留到10
矩阵=矩阵(特征::占位符::all,特征::seqN(5,5));//将列从5保留到10
内联特征::矩阵XXD删除矩阵行(常数特征::矩阵XXD原始矩阵,常数int行到删除)
{
//新矩阵少了一行
特征::矩阵XXD新矩阵(原始矩阵.rows()-1,原始矩阵.cols());
//跟踪新矩阵中的行。跳过第_行中的一行以删除。
int row_to_fill=0;
对于(int orig_matrix_row=0;orig_matrix_row我不认为有一种方法不使用块操作。我不熟悉EGIN库,但是从一般的C++观点看来,你的函数中有内存泄漏:你分配了辅助程序但不删除它们。一般来说,在编写C++时,你应该避免<代码>新< /Cord>——除非你真的需要,而且你知道Y是什么。您正在这样做。相反,只需编写
Eigen::Matrix auxmat=mat
(并通过引用而不是指针传递
mat
),这通常应该可以工作,但不能保证Eigen会从左到右(或从上到下)复制块,因此从理论上讲,您可能会遇到别名问题。@chtz:要避免此问题,请使用
.eval()
函数。From Review:您好,请不要仅用源代码回答。请提供一个好的答案
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();
}
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
  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;
  }