2012-11-08 71 views
8

Iam使用特徵庫用於我的項目。我正在尋找如何從特徵矩陣中刪除特定的行或列。 Iam不成功。如何在使用特徵庫時刪除特定的行或列C++

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上使用塊操作。有沒有簡單的方法。

+1

我不認爲有一種方法,而不是使用塊操作。 – Jakob

回答

9

使用塊的功能是有點清潔:

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); 
} 
+0

這應該通常工作,但它不能保證Eigen會從左到右(或從上到下)複製塊,因此理論上可以得到混疊問題。 – chtz

+0

@chtz:爲了避免這個問題,使用'.eval()'函數。 – davidhigh

1

我在C++中很新,但是這個代碼在may應用程序中工作。

它只適用於全動態矩陣,但可以適應它。

如果有人有更好的方式請告訴我我真的很想學習。

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); 
} 
+2

我對eigen庫不熟悉,但是從一般C++的觀點看來,您的函數中有內存泄漏:您分配了輔助資源但不刪除它們。 – cybevnm

+0

一般來說,在編寫C++時你應該避免使用'new',除非你真的需要並且你知道你在做什麼。相反,只需編寫Eigen :: Matrix auxmat = mat'(並通過引用傳遞'mat'而不是通過指針) – chtz

0

爲了提高安德魯的回答,請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); 
} 
0

您可能會發現在某些用途(在線多與本徵的編譯時間效率的精神)以下靜態版本更好。在這種情況下,您將創建一個沒有該行的新矩陣。類似的功能可以構建爲列使用.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(); 
} 

享受!