I am posed with a problem whereby I am trying to decompose a rank deficient matrix into its Q-R components. This is the matrix we are interested in:
1 -2 4 -8
1 -1 1 -1
1 0 0 0
1 1 1 1
1 2 4 8
Let's call it mymatrix.
When I call the qr(mymatrix, 0) function in MATLAB, here is the R-matrix that gets returned to me:
-2.2361 -0.0000 -4.4721 -0.0000
0 3.1623 0.0000 10.7517
0 0 3.7417 0.0000
0 0 0 3.7947
Now, in eigen c++, I tried to do the same but, alas, I am overwhelmed with an altogether different matrix:
11.4018 -8.88178e-16 -2.22045e-16 2.982
0 -5.83095 -1.71499 3.33067e-16
0 0 -1.43486 9.41987e-17
0 0 0 -1.05247
Here's the function that returns my QR matrix in eigen:
#include <Eigen/LU>
#include <Eigen/Dense>
#include <Eigen/QR>
#include <cmath>
using namespace Eigen;
using namespace std;
int main(){
//inter is initialized as mymatrix
ColPivHouseholderQR<MatrixXd> qr(inter.rows(), inter.cols());
qr.compute(mymatrix);
FullPivLU<MatrixXd>lu_decomp(inter);
int Rank = lu_decomp.rank() ;
cout <<"\nInter's Rank is: " << Rank << endl;
if (Rank == inter.rows() + 1 || Rank == inter.cols() + 1 )
{
MatrixXd R = qr.matrixR().template triangularView<Upper>(); //retrieve the R - Matrix
cout << "\nR Matrix: \n" << R << endl;
}
else //For rank deficient matrices
{
FullPivLU<MatrixXd>lu_decomp(inter);
MatrixXd R = qr.matrixR().topLeftCorner(lu_decomp.rank(), lu_decomp.rank()).template triangularView<Upper>();
cout <<"\n R with rank deficiency: \n" << R << endl;
}
return 0;
}
What could I possibly be missing?
The documentation is rather sparse for Eigen's QR documentation. You could retrieve the Q matrix from the
householderQR module as outlined here. After retrieving the QR matrix, extracting the R matrix is simply a matter of extracting the upper triangular matrix ofmatrixQR.Suppose we have a full rank matrix, we could retrieve the R matrix as follows:
If the original matrix is rank deficient, this would do:
I hope this would help someone down the lane.