2012-11-08 17 views
8

Ich verwende die Eigen-Bibliothek für mein Projekt. Ich suche, wie man eine bestimmte Reihe oder Spalte von der gegebenen Matrix in Eigen entfernt. Ich bin nicht erfolgreich.So entfernen Sie eine bestimmte Zeile oder Spalte während der Verwendung der Eigenbibliothek 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 

anders als durch Iterieren gesamte Matrix oder durch Blockoperationen auf Matrix A verwendet. Gibt es eine Methode, um es einfach zu machen?

+1

Ich glaube nicht, dass es eine andere Methode als die Verwendung der Blockoperationen gibt. – Jakob

Antwort

9

die Blockfunktionen zu verwenden ist etwas sauberer:

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

Dies sollte im Allgemeinen funktionieren, aber es Es ist nicht garantiert, dass Eigen Blöcke von links nach rechts (oder von oben nach unten) kopiert, so dass Sie theoretisch Alias-Probleme bekommen könnten. – chtz

+0

@chtz: Um dieses Problem zu vermeiden, verwenden Sie die Funktion '.eval()'. – davidhigh

1

Ich bin sehr neu in C++, aber dieser Code funktioniert in Mai-Anwendung.

Es funktioniert nur für volle dynamische Matrix aber kann es anpassen.

Wenn jemand einen besseren Weg hat, bitte zeigen Sie mir, ich möchte wirklich lernen.

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

Ich bin nicht vertraut mit Eigen-Bibliothek, aber von allgemeinen C++ Standpunkt sieht aus wie Sie Speicherlecks in Ihren Funktionen haben: Sie ordnen Auxmats aber nicht löschen sie. – cybevnm

+0

Im Allgemeinen sollten Sie "neu" vermeiden, wenn Sie C++ schreiben - es sei denn, Sie müssen wirklich und Sie wissen, was Sie tun. Stattdessen schreibe einfach 'Eigen :: Matrix auxmat = mat '(und pass' mat 'durch Referenz und nicht durch Zeiger) – chtz

0

Um Andrew Antwort, verwenden bottomRows/rightCols zu verbessern.

0

Sie können die folgende statische Version für bestimmte Verwendungen besser finden (und mehr in Übereinstimmung mit dem Geist der Eigenkompilierungszeit-Effizienz). In diesem Fall erstellen Sie eine neue Matrix ohne die Zeile. mit .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(); 
} 

Genießen Eine ähnliche Funktion kann für Spalten konstruiert werden!

Verwandte Themen