| 49 | |
| 50 | template <typename MatrixType> |
| 51 | void DecomposeMatrixRQ(const MatrixType& A, MatrixType* R, MatrixType* Q) { |
| 52 | const MatrixType A_flipud_transpose = |
| 53 | A.transpose().rowwise().reverse().eval(); |
| 54 | |
| 55 | const Eigen::HouseholderQR<MatrixType> QR(A_flipud_transpose); |
| 56 | const MatrixType& Q0 = QR.householderQ(); |
| 57 | const MatrixType& R0 = QR.matrixQR(); |
| 58 | |
| 59 | *R = R0.transpose().colwise().reverse().eval(); |
| 60 | *R = R->rowwise().reverse().eval(); |
| 61 | for (int i = 0; i < R->rows(); ++i) { |
| 62 | for (int j = 0; j < R->cols() && (R->cols() - j) > (R->rows() - i); ++j) { |
| 63 | (*R)(i, j) = 0; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | *Q = Q0.transpose().colwise().reverse().eval(); |
| 68 | |
| 69 | // Make the decomposition unique by requiring that det(Q) > 0. |
| 70 | if (Q->determinant() < 0) { |
| 71 | Q->row(1) *= -1.0; |
| 72 | R->col(1) *= -1.0; |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | } // namespace colmap |
no outgoing calls