Search code examples
c++eigeneigenvectoreigenvalue

Copying upper MatrixXd to lower MatrixXd (Eigen3) C++ library


I've got a lower triangular MatrixXd and I want to copy its lower values to the upper side as it'll become a symmetric matrix. How can I do it?

So far I've done:

 MatrixXd m(n,n); 
 .....
 //do something with m
 for(j=0; j < n; j++)
       {
         for(i=0; i<j; i++)
           {
             m(i,j) = m(j,i);

           }
       }

Is there a fastest way to do it? I was thinking of some internal method that is able to "copy" the lower triangular matrix to the upper. Say I've got this matrix, we call m:

1 2 3
4 5 6
7 8 9

what I need to obtain in m is :

1 4 7
4 5 8
7 8 9

I also know you can get the upper or the lower part of the matrix to do something:

MatrixXd m1(n,n);
 m1 = m.triangularView<Eigen::Upper>();
cout << m1 <<endl;

1 2 3
0 5 6
0 0 9

But I can't yet get what I want...


Solution

  • I assume here that you are referring to working with the Eigen3 c++ library. This is not clear from your question. if not, you should consider it. In any case, within Eigen, there is no need to actually copy the triangular part, to get a selfadjoint matrix. Eigen has the concept of views, and you can use a self adjoint view in order to perform an operation like e.g.

    using namespace Eigen;
    MatrixXd m(m,n);
    ...
    (generate uppper triangular entries in m)
    ...
    VectorXd r(n), p(n);
    r = m.selfadjointView<Upper>() * p;
    

    here is a small example to illustrate using fixed size matrices:

    #include <Eigen/Core>
    
    using namespace std;
    using namespace Eigen;
    
    int main()
    {
        Matrix2d m,c;
        m << 1, 2,
             0, 1;
    
        Vector2d x(0,2), r;
    
        // perform copy operation 
        c = m.selfadjointView<Upper>(); 
        cout << c << endl;
    
        // directly apply selfadjoint view in matrix operation
        // (no entries are copied)
        r = m.selfadjointView<Upper>() * x;
    } 
    

    the output will be [1, 2, 2, 1]. now, the result in r is the same as if you had used c * x instead. Just that there is no need for copying the values in the original matrix to make it selfadjoint.