2017-01-20 5 views
2

Ich habe zwei Sparse-Matrizen in Eigen, und ich möchte sie vertikal in eins verbinden. Als Beispiel wäre das Ziel des Codes sein:Concarenate Sparse-Matrix Eigenen

SparseMatrix<double> matrix1; 
matrix1.resize(10, 10); 
SparseMatrix<double> matrix2; 
matrix2.resize(5, 10); 

SparseMatrix<double> MATRIX_JOIN; 
MATRIX_JOIN.resize(15, 10); 
MATRIX_JOIN << matrix1, matrix2; 

fand ich einige Lösungen auf forum aber ich war zu ihrer Umsetzung nicht in der Lage.

Was ist der richtige Weg, um die Matrizen vertikal zu verbinden?

bearbeiten

Meine Implementierung:

SparseMatrix<double> L; 
SparseMatrix<double> C; 
// ... (Operations with the matrices) 
SparseMatrix<double> EMATRIX; 
EMATRIX.resize(L.rows() + C.rows(), L.cols()); 
EMATRIX.middleRows(0, L.rows()) = L; 
EMATRIX.middleRows(L.rows(), C.rows()) = C; 

ich einen Fehler von Typen bekommen, an den Compiler Acording die rechte Seite ist ein Eigen :: Blocks und die linke Seite ist Eigen :: Dünnbesetzte Matrix

+0

Was bedeutet „Ich war es nicht in der Lage zu implementieren.“ bedeuten? –

+0

@ Code-Apprentice Ich konnte die Lösung, die ich im Forum gefunden habe, nicht implementieren. Es sollte auch eine spärliche und eine dichte Matrix (die Lösung im Forum) beitreten. – Javier

+0

Das Wiederholen der gleichen Wörter erklärt nicht, was die Wörter bedeuten. Bitte zeigen Sie genau, was Sie getan haben und was passiert, wenn Sie den Code, den Sie geschrieben haben, kompilieren und ausführen. –

Antwort

3

Soweit ich weiß, gibt es derzeit keine integrierte Lösung. Sie können mithilfe the internal insertBack function als Ihre Lösung Art und Weise effizienter sein:

SparseMatrix<double> M(L.rows() + C.rows(), L.cols()); 
M.reserve(L.nonZeros() + C.nonZeros()); 
for(Index c=0; c<L.cols(); ++c) 
{ 
    for(SparseMatrix<double>::InnerIterator itL(L, c); itL; ++itL) 
     M.insertBack(itL.row(), c) = itL.value(); 
    for(SparseMatrix<double>::InnerIterator itC(C, c); itC; ++itC) 
     M.insertBack(itC.row(), c) = itC.value(); 
} 
M.finalize(); 
+0

Ist das effizienter als Triplets? – Javier

+0

@Javier sollte es in allen aber sehr seltsamen Fällen sein. Es kann in vielen Fällen nicht viel ausmachen. – chtz

1

ich am Ende dabei wie folgt vor:

MATRIX_JOIN.resize(matrix1.rows() + matrix2.rows(), matrix1.cols() + matrix2.cols()); 
MATRIX_JOIN.setZero(); 

// Fill MATRIX_JOIN with triples from the other matrices 
std::vector<Triplet<double> > tripletList; 
for (int k = 0; k < matrix1.outerSize(); ++k) 
{ 
    for (SparseMatrix<double>::InnerIterator it(matrix1, k); it; ++it) 
    { 
     tripletList.push_back(Triplet<double>(it.row(), it.col(), it.value())); 
    } 
} 
for (int k = 0; k < matrix2.outerSize(); ++k) 
{ 
    for (SparseMatrix<double>::InnerIterator it(matrix2, k); it; ++it) 
    { 
     tripletList.push_back(Triplet<double>(it.row(), it.col(), it.value())); 
    } 
} 
FINALMATRIX.setFromTriplets(tripletList.begin(), tripletList.end()); 

Es kann eine Beschleunigung geben, indem tripleList.reserve(X) aufgerufen wird, wobei X die erwartete Menge an einzufügenden Triplets ist.