Search code examples
c++eigen

Eigen SparseMatrix upper triangular to full matrix


I have an upper triangular SparseMatrix<double>. What would be the most efficient way to convert it to a full sparse matrix?

I have this implemented currently as mat.transpose() + mat - diagonal(mat).

I thought I could use something like

mat.selfadjointView<Eigen::Lower>() = mat.selfadjointView<Eigen::Upper>();

For reasons I don't fully understand, this clears the matrix.


Solution

  • According to the documentation for Eigen::MatrixBase::selfadjointview, the function already creates a symmetric view from the upper or lower triangular part.

    Matrix3i m = Matrix3i::Random();
    cout << "Here is the matrix m:" << endl << m << endl;
    cout << "Here is the symmetric matrix extracted from the upper part of m:" << endl
         << Matrix3i(m.selfadjointView<Upper>()) << endl;
    cout << "Here is the symmetric matrix extracted from the lower part of m:" << endl
         << Matrix3i(m.selfadjointView<Lower>()) << endl;
    

    Output:

    Here is the matrix m:
     7  6 -3
    -2  9  6
     6 -6 -5
    Here is the symmetric matrix extracted from the upper part of m:
     7  6 -3
     6  9  6
    -3  6 -5
    Here is the symmetric matrix extracted from the lower part of m:
     7 -2  6
    -2  9 -6
     6 -6 -5
    

    Assuming your matrix is upper triangular, the following should answer your question.

    Matrix3i m = [] {
       Matrix3i tmp;
       tmp << 1, 2, 3, 0, 4, 5, 0, 0, 6;
       return tmp;
    }();
    cout << "Here is the matrix m:" << endl << m << endl;
    cout << "Here is the symmetric matrix extracted from the upper part of m:" << endl
         << Matrix3i(m.selfadjointView<Upper>()) << endl;
    

    Output:

    Here is the matrix m:
     1  2  3
     0  4  5
     0  0  6
    Here is the symmetric matrix extracted from the upper part of m:
     1  2  3
     2  4  5
     3  5  6