Language Reference

QR Call

CALL QR (q, r, piv, lindep, a <, ord> <, b> ) ;

This subroutine is supported by the IML procedure and the iml action.

The QR subroutine produces the QR decomposition of a matrix by using Householder transformations.

The QR subroutine returns the following values:

q

specifies an orthogonal matrix bold upper Q that is the product of the Householder transformations applied to the m times n matrix bold upper A, if the b argument is not specified. In this case, the min left-parenthesis m comma n right-parenthesis Householder transformations are applied, and q is an m times m matrix. If the b argument is specified, q is the m times p matrix bold upper Q prime bold upper B that has the transposed Householder transformations bold upper Q prime applied on the p columns of the argument matrix bold upper B.

r

specifies a min left-parenthesis m comma n right-parenthesis times n upper triangular matrix bold upper R that is the upper part of the m times n upper triangular matrix bold upper R overTilde of the QR decomposition of the matrix bold upper A. The matrix bold upper R overTilde of the QR decomposition can be obtained by vertical concatenation (by using the operator //) of the left-parenthesis m minus min left-parenthesis m comma n right-parenthesis right-parenthesis times n zero matrix to the result matrix bold upper R.

piv

specifies an n times 1 vector of permutations of the columns of bold upper A; that is, on return, the QR decomposition is computed, not of bold upper A, but of the permuted matrix whose columns are left-bracket bold upper A Subscript piv left-bracket 1 right-bracket Baseline ellipsis bold upper A Subscript piv left-bracket n right-bracket Baseline right-bracket. The vector piv corresponds to an n times n permutation matrix bold upper Pi.

lindep

is the number of linearly dependent columns in matrix bold upper A detected by applying the min left-parenthesis m comma n right-parenthesis Householder transformations in the order specified by the argument vector piv.

The input arguments to the QR subroutine are as follows:

a

specifies an m times n matrix bold upper A that is to be decomposed into the product of the orthogonal matrix bold upper Q and the upper triangular matrix bold upper R overTilde.

ord

specifies an optional n times 1 vector that specifies the order of Householder transformations applied to matrix bold upper A. When you specify the ord argument, the columns of bold upper A can be divided into the following groups:

ord[j]>0

Column j of bold upper A is an initial column, meaning it has to be processed at the start in increasing order of ord[j]. This specification defines the first n Subscript l columns of bold upper A that are to be processed.

ord[j]=0

Column j of bold upper A is a pivot column, meaning it is to be processed in order of decreasing residual Euclidean norms. The pivot columns of bold upper A are processed after the n Subscript l initial columns and before the n Subscript u final columns.

ord[j]<0

Column j of bold upper A is a final column, meaning it has to be processed at the end in decreasing order of ord[j]. This specification defines the last n Subscript u columns of bold upper A that are to be processed. If n greater-than m, some of these columns are not processed.

The default is ord[j]=j, in which case the Householder transformations are processed in the same order in which the columns are stored in matrix bold upper A (without pivoting).

b

specifies an optional m times p matrix bold upper B that is to be multiplied by the transposed m times m matrix bold upper Q prime. If b is specified, the result q contains the m times p matrix bold upper Q prime bold upper B. If b is not specified, the result q contains the m times m matrix bold upper Q.

The QR subroutine decomposes an m times n matrix bold upper A into the product of an m times m orthogonal matrix bold upper Q and an m times n upper triangular matrix bold upper R overTilde, so that

by means of min left-parenthesis m comma n right-parenthesis Householder transformations.

The m times m orthogonal matrix bold upper Q is computed only if the last argument b is not specified, as in the following example:

call qr(q, r, piv, lindep, a, ord);

In many applications, the number of rows, m, is very large. In these cases, the explicit computation of the m times m matrix bold upper Q might require too much memory or time.

In the usual case where m greater-than n,

StartLayout 1st Row 1st Column bold upper A equals Start 5 By 3 Matrix 1st Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 2nd Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 3rd Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 4th Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 5th Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk EndMatrix 2nd Column Blank 3rd Column bold upper Q equals Start 5 By 5 Matrix 1st Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 4th Column asterisk 5th Column asterisk 2nd Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 4th Column asterisk 5th Column asterisk 3rd Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 4th Column asterisk 5th Column asterisk 4th Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 4th Column asterisk 5th Column asterisk 5th Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 4th Column asterisk 5th Column asterisk EndMatrix 2nd Row 1st Column bold upper R overTilde equals Start 5 By 3 Matrix 1st Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 2nd Row 1st Column 0 2nd Column asterisk 3rd Column asterisk 3rd Row 1st Column 0 2nd Column 0 3rd Column asterisk 4th Row 1st Column 0 2nd Column 0 3rd Column 0 5th Row 1st Column 0 2nd Column 0 3rd Column 0 EndMatrix 2nd Column Blank 3rd Column bold upper R equals Start 3 By 3 Matrix 1st Row 1st Column asterisk 2nd Column asterisk 3rd Column asterisk 2nd Row 1st Column 0 2nd Column asterisk 3rd Column asterisk 3rd Row 1st Column 0 2nd Column 0 3rd Column asterisk EndMatrix 3rd Row 1st Column bold upper Q equals left-bracket bold upper Q 1 bold upper Q 2 right-bracket comma 2nd Column Blank 3rd Column bold upper R overTilde equals StartBinomialOrMatrix bold upper R Choose bold 0 EndBinomialOrMatrix EndLayout

where bold upper R is the result returned by the QR subroutine.

The n columns of matrix bold upper Q 1 provide an orthonormal basis for the n columns of bold upper A and are called the range space of bold upper A. Since the m minus n columns of bold upper Q 2 are orthogonal to the n columns of bold upper A, bold upper Q prime 2 bold upper A equals bold 0, they provide an orthonormal basis for the orthogonal complement of the columns of bold upper A and are called the null space of bold upper A.

In the case where m less-than n,

Specifying the argument ord as an n vector lets you specify a special order of the columns in matrix bold upper A on which the Householder transformations are applied. There are two special cases:

  • If you do not specify the ord argument, the default values ordleft-bracket j right-bracket equals j are used. In this case, Householder transformations are done in the same order in which the columns are stored in bold upper A (without pivoting).

  • If you set all components of ord to zero, the Householder transformations are done in order of decreasing Euclidean norms of the columns of bold upper A.

To check the QR decomposition, use the following statements to compute the three residual sum of squares (represented by the variables SS0, SS1, and SS2), which should be close to zero:

a = shape(1:20, 5);
m = nrow(a); n = ncol(a);
ord = j(1, n, 0);
call qr(q, r, piv, lindep, a);
ss0 = ssq(a[ ,piv] - q[,1:n] * r);
ss1 = ssq(q * q` - i(m));
ss2 = ssq(q` * q - i(m));
print ss0 ss1 ss2;

Figure 324: Result of a QR Decomposition

ss0ss1ss2
4.488E-285.447E-314.655E-31


If the QR subroutine detects linearly dependent columns while processing matrix bold upper A, the column order given in the result vector piv can differ from an explicitly specified order in the argument vector ord. If a column of bold upper A is found to be linearly dependent on columns already processed, this column is swapped to the end of matrix bold upper A. The order of columns in the result matrix bold upper R corresponds to the order of columns processed in bold upper A. The swapping of a linearly dependent column of bold upper A to the end of the matrix corresponds to the swapping of the same column in bold upper R and leads to a zero row at the end of the upper triangular matrix bold upper R.

The scalar result lindep counts the number of linearly dependent columns that are detected in constructing the first min left-parenthesis m comma n right-parenthesis Householder transformations in the order specified by the argument vector ord. The test of linear dependence depends on the singularity criterion, which is 1E–8 by default.

Solving the linear system upper R x equals upper Q prime b with an upper triangular matrix bold upper R whose columns are permuted corresponding to the result vector piv leads to a solution x with permuted components. You can reorder the components of x by using the index vector piv at the left-hand side of an expression, as follows:

a = {3  0  0 -1,
     0  1  2  0,
     4 -4 -1  1,
    -1  2  3  4};
b = {-1, 8, -3, 28};

n = ncol(a); p = ncol(b);
ord = j(1, n, 0);
call qr(qtb, r, piv, lindep, a, ord, b);
print piv;

x = j(n,1);
x[piv] = inv(r) * qtb[1:n, 1:p];
print x;

Figure 325: Solution to a Linear System

piv
1423

x
1
2
3
4


The Full-Rank Linear Least Squares Problem

This example solves the full-rank linear least squares problem. Specify the argument b as an m times p matrix bold upper B, as follows:

call qr(q, r, piv, lindep, a, ord, b);

When you specify the b argument, the QR subroutine computes the matrix upper Q prime upper B (instead of Q) as the result q. Now you can compute the p least squares solutions x Subscript k of an overdetermined linear system with an m times n comma m greater-than n coefficient matrix A, rank(A) = n, and p right-hand sides bSubscript k stored as the columns of the m times p matrix B:

where double-vertical-bar dot double-vertical-bar is the Euclidean vector norm. This is accomplished by solving the p upper triangular systems with back substitution:

For most applications, the number of rows of bold upper A, m, is much larger than n, the number of columns of bold upper A, or p, the number of right-hand sides. In these cases, you are advised not to compute the large m times m matrix bold upper Q (which can consume too much memory and time) if you can solve your problem by computing only the smaller m times p matrix bold upper Q prime bold upper B implicitly.

For example, use the first five columns of the 6 times 6 Hilbert matrix bold upper A, as follows:

a= {  36      -630      3360     -7560      7560     -2772,
    -630     14700    -88200    211680   -220500     83160,
    3360    -88200    564480  -1411200   1512000   -582120,
   -7560    211680  -1411200   3628800  -3969000   1552320,
    7560   -220500   1512000  -3969000   4410000  -1746360,
   -2772     83160   -582120   1552320  -1746360    698544 };
aa = a[, 1:5];
b= { 463, -13860, 97020, -258720, 291060, -116424};

m = nrow(aa); n = ncol(aa); p = ncol(b);
call qr(qtb, r, piv, lindep, aa, , b);

if lindep=0 then do;
   x=inv(r)*qtb[1:n];
   print x;  /* x solves aa*x=b */
end;
else /* handle linear dependence */;

Figure 326: Solution to Least Squares Problem

x
1
0.5
0.3333333
0.25
0.2


Note that you are using only the first n rows, bold upper Q prime 1 bold upper B, of the qtb matrix. The IF-THEN statement of the preceding example can be replaced by the more efficient TRISOLV function:

if lindep=0 then
   x = trisolv(1, r, qtb[1:n], piv);

For information about solving rank-deficient linear least squares problems, see the RZLIND call.

Last updated: April 16, 2021