Introduction:
I'm using the Intel Math Kernel Library (MKL) functions LAPACKE_dgeqrf
and LAPACKE_dorgqr
for generating the QR decomposition of a general input matrix A of size (m x n) stored in row-major order, (where m is the number of A's rows and n is the number of A's columns).
Below is the code I use:
C++ Code:
void qr (double *Q, double *R, double *A, const size_t m, const size_t n) {
std::size_t k = std::max(std::size_t(1), std::min(m, n)); // The number of elementary reflectors
std::unique_ptr<double[]> tau(new double[k]); // Scalars that define elementary reflectors
LAPACKE_dgeqrf(LAPACK_ROW_MAJOR, m, n, A, n, tau.get());
// Generate R matrix
for (std::size_t i(0); i < n; ++i) {
std::memset(R + i * n , 0 , i * sizeof(double));
std::memcpy(R + i * n + i, A + i * n + i, (n - i) * sizeof(double));
}
// Generate Q matrix
LAPACKE_dorgqr(LAPACK_ROW_MAJOR, m, k, k, A, n, tau.get());
if(m == n) {
std::memcpy(Q, A, sizeof(double) * (m * m));
} else {
for(std::size_t i(0); i < m; ++i) {
std::memcpy(Q + i * k, A + i * n, sizeof(double) * (k));
}
}
}
Related Info:
The code above is a slightly refactored version of the code I found in another related answer to a similar question.
https://stackoverflow.com/a/29408035/2352671
Description:
LAPACKE_dgeqrf
overwrites on the upper triangular part of input matrix A, the upper triangular part of (mxn) upper triangular matrix R. So matrix R can be easily extracted as shown in the code.- The lower triangular part of the overwritten matrix, A, holds information about the Householder transformations.
- In array tau the scalar factors of the elementary reflectors used in the Householder transformations are stored.
- In order to extract matrix Q from the above given information, we use
LAPACKE_dorgqr
. LAPACKE_dorgqr
seems to work well for input matrices where (m ≤ n) (i.e., the number of rows of input matrix A is less than or equal to the number of its columns). That is, when (m == n),LAPACKE_dorgqr
overwrites on input matrix A, which as shown is the result ofLAPACKE_dgeqrf
, (mxm) matrix Q. When (m < n) first m columns of overwritten matrix A represent (mxm) matrix Q. So in these cases as illustrated in the code, Q can be easily extracted.- However, in the case where (m > n) (i.e., the number of rows of input matrix A is greater than the number of its columns),
LAPACKE_dorgqr
outputs only the first n columns of matrix Q.
Questions:
- How to generate the rest of the missing columns of Q in the case where the input matrix's rows are greater than the number of its columns?
- Am I missing something? That is, am I misusing the API?
- Is this API's normal behavior, and I've to generate the rest of the column orthogonal vectors of matrix Q using some generation process like Gram–Schmidt from the existing orthogonal column vectors?
- Do I have to solve a system for obtaining the full matrix Q, since I have matrix R?