Language Reference

ORTVEC Call

provides columnwise orthogonalization by the Gram-Schmidt process and stepwise QR decomposition by the Gram-Schmidt process

CALL ORTVEC( w, r, \rho, lindep, v\lt, q>);

The ORTVEC subroutine returns the following values:



w
If the Gram-Schmidt process converges (lindep=0), w is the m x 1 vector {w} orthonormal to the columns of {q}, which is assumed to have n \leq m (nearly) orthonormal columns. If the Gram-Schmidt process does not converge (lindep=1), w is a vector of missing values. For stepwise QR decomposition, w is the (n+1)th orthogonal column of the matrix {q}. If there is no matrix {q}, that is, if the q argument is not specified, w is the normalized value of the vector {v},
{w}= \frac{{v}}{\sqrt{{v}^' {v}}}

r
If the Gram-Schmidt process converges (lindep=0), r specifies the n x 1 vector {r} of Fourier coefficients. If the Gram-Schmidt process does not converge (lindep=1), r is a vector of missing values. If the q argument is not specified, r is a vector with zero dimension. For stepwise QR decomposition, r contains the n upper triangular elements of the (n+1)th column of {{r}}.

\rho
If the Gram-Schmidt process converges (lindep=0), \rho specifies the distance from {w} to the range of {q}. Even if the Gram-Schmidt process converges, if \rho is sufficiently small, the vector {v} can be linearly dependent on the columns of {q}. If the Gram-Schmidt process does not converge (lindep=1), \rho is set to 0. For stepwise QR decomposition, \rho contains the diagonal element of the (n+1)th column of {{r}}.

lindep
returns a value of 1 if the Gram-Schmidt process does not converge in 10 iterations. In most cases, if lindep=1, the input vector {v} is linearly dependent on the n columns of the input matrix {q}. In that case, \rho is set to 0, and the results w and r contain missing values. If lindep=0, the Gram-Schmidt process did converge, and the results w, r, and \rho are computed.

The inputs to the ORTVEC subroutine are as follows:



v
specifies an m x 1 vector {v} that is to be orthogonalized to the n columns of {q}. For stepwise QR decomposition of a matrix, {v} is the (n+1)th matrix column before its orthogonalization.

q
specifies an optional m x n matrix {q} that is assumed to have n \leq m (nearly) orthonormal columns. Thus, the n x n matrix {q}^' {q} should approximate the identity matrix. The column orthonormality assumption is not tested in the ORTVEC call. If it is violated, the results are not predictable. The argument q can be omitted or can have zero rows and columns. For stepwise QR decomposition of a matrix, q contains the first n matrix columns that are already orthogonal.


The relevant formula for the ORTVEC subroutine is
{v}= {qr} + \rho {w}
Assuming that the m x n matrix {q} has n (nearly) orthonormal columns, the ORTVEC subroutine orthogonalizes the vector {v} to the columns of {q}. The vector {r} is the array of Fourier coefficients, and \rho is the distance from {w} to the range of {q}.

There are two special cases:

The case m \lt n is not possible since {q} is assumed to have n (nearly) orthonormal columns.

To initialize a stepwise QR decomposition, ORTVEC can be called to normalize {v} only, that is, to compute {w}= {v}/ \sqrt{{v}^' {v}} and \rho = \sqrt{{v}^' {v}} only. There are two ways of using the ORTVEC call for this reason:

In both cases, {r} is a column vector with zero rows.

The ORTVEC subroutine is useful for the following applications:

The 4 x 3 matrix {q} contains the unit vectors {e}_1, {e}_3, and {e}_4. The column vector {v} is pairwise linearly independent with the three columns of {q}. As expected, the ORTVEC call computes the vector {w} as the unit vector {e}_2 with {u}= (1,1,1) and \rho = 1. Here is the code:

  
    q = { 1  0  0, 
          0  0  0, 
          0  1  0, 
          0  0  1 }; 
    v = { 1, 1, 1, 1 }; 
    call ortvec(w,u,rho,lindep,v,q); 
    print rho u w;
 

You can perform the QR decomposition of the linearly independent columns of an m x n matrix {a} with the following statements:

  
    a = { . . . enter matrix A here . . . }; 
    nind = 0;  ndep = 0;  dmax = 0.; 
    n = ncol(a);  m = nrow(a); 
    free q; 
    do j = 1 to n; 
       v = a[ ,j]; 
       call ortvec(w,u,rho,lindep,v,q); 
       aro = abs(rho); 
       if aro > dmax then dmax = aro; 
       if aro <= 1.e-10 * dmax then lindep = 1; 
       if lindep = 0 then do; 
          nind = nind + 1; 
          q = q || w; 
          if nind = n then r = r || (u // rho); 
          else r = r || (u // rho // j(n-nind,1,0.)); 
       end; 
       else do; 
          print "Column " j " is linearly dependent."; 
          ndep = ndep + 1; ind[ndep] = j; 
       end; 
    end;
 
Next, process the remaining columns of {a}:
  
    do j = 1 to ndep; 
       k = ind[ndep-j+1]; 
       v = a[ ,k]; 
       call ortvec(w,u,rho,lindep,v,q); 
       if lindep = 0 then do; 
          nind = nind + 1; 
          q = q || w; 
          if nind = n then r = r || (u // rho); 
          else r = r || (u // rho // j(n-nind,1,0.)); 
       end; 
    end;
 
Now compute the null space in the last columns of {q}:
  
    do i = 1 to m; 
       if nind < m then do; 
         v = j(m,1,0.); v[i] = 1.; 
         call ortvec(w,u,rho,lindep,v,q); 
         aro = abs(rho); 
         if aro > dmax then dmax = aro; 
         if aro <= 1.e-10 * dmax then lindep = 1; 
         if lindep = 0 then do; 
           nind = nind + 1; 
           q = q || w; 
         end; 
         else print "Unit vector" i "linearly dependent."; 
       end; 
    end; 
    if nind < m then do; 
       print "This is theoretically not possible."; 
    end;
 

Previous Page | Next Page | Top of Page