| C Dqrdc2 is a *modification* of Linpack's dqrdc ('DQRDC') for R |
| c |
| c dqrdc2 uses householder transformations to compute the qr |
| c factorization of an n by p matrix x. a limited column |
| c pivoting strategy based on the 2-norms of the reduced columns |
| c moves columns with near-zero norm to the right-hand edge of |
| c the x matrix. this strategy means that sequential one |
| c degree-of-freedom effects can be computed in a natural way. |
| c |
| c i am very nervous about modifying linpack code in this way. |
| c if you are a computational linear algebra guru and you really |
| c understand how to solve this problem please feel free to |
| c suggest improvements to this code. |
| c |
| c Another change was to compute the rank. |
| c |
| c on entry |
| c |
| c x double precision(ldx,p), where ldx .ge. n. |
| c x contains the matrix whose decomposition is to be |
| c computed. |
| c |
| c ldx integer. |
| c ldx is the leading dimension of the array x. |
| c |
| c n integer. |
| c n is the number of rows of the matrix x. |
| c |
| c p integer. |
| c p is the number of columns of the matrix x. |
| c |
| c tol double precision |
| c tol is the nonnegative tolerance used to |
| c determine the subset of the columns of x |
| c included in the solution. |
| c |
| c jpvt integer(p). |
| c integers which are swapped in the same way as the |
| c the columns of x during pivoting. on entry these |
| c should be set equal to the column indices of the |
| c columns of the x matrix (typically 1 to p). |
| c |
| c work double precision(p,2). |
| c work is a work array. |
| c |
| c on return |
| c |
| c x x contains in its upper triangle the upper |
| c triangular matrix r of the qr factorization. |
| c below its diagonal x contains information from |
| c which the orthogonal part of the decomposition |
| c can be recovered. note that if pivoting has |
| c been requested, the decomposition is not that |
| c of the original matrix x but that of x |
| c with its columns permuted as described by jpvt. |
| c |
| c k integer. |
| c k contains the number of columns of x judged |
| c to be linearly independent, i.e., "the rank" |
| c |
| c qraux double precision(p). |
| c qraux contains further information required to recover |
| c the orthogonal part of the decomposition. |
| c |
| c jpvt jpvt(j) contains the index of the column of the |
| c original matrix that has been interchanged into |
| c the j-th column. Consequently, jpvt[] codes a |
| c permutation of 1:p; it is called 'pivot' in R |
| |
| c |
| c original (dqrdc.f) linpack version dated 08/14/78 . |
| c g.w. stewart, university of maryland, argonne national lab. |
| c |
| C This version dated 22 August 1995 |
| C Ross Ihaka |
| c |
| c bug fixes 29 September 1999 BDR (p > n case, inaccurate ranks) |
| c |
| c |
| c dqrdc2 uses the following functions and subprograms. |
| c |
| c blas daxpy,ddot,dscal,dnrm2 |
| c fortran dabs,dmax1,min0,dsqrt |
| c |
| subroutine dqrdc2(x,ldx,n,p,tol,k,qraux,jpvt,work) |
| integer ldx,n,p |
| integer jpvt(p) |
| double precision x(ldx,p),qraux(p),work(p,2),tol |
| c |
| c internal variables |
| c |
| integer i,j,l,lp1,lup,k |
| double precision dnrm2,tt,ttt |
| double precision ddot,nrmxl,t |
| c |
| c |
| c compute the norms of the columns of x. |
| c |
| if (n .gt. 0) then |
| c avoid accessing element beyond the bound |
| do 70 j = 1, p |
| qraux(j) = dnrm2(n,x(1,j),1) |
| work(j,1) = qraux(j) |
| work(j,2) = qraux(j) |
| if(work(j,2) .eq. 0.0d0) work(j,2) = 1.0d0 |
| 70 continue |
| endif |
| c |
| c perform the householder reduction of x. |
| c |
| lup = min0(n,p) |
| k = p + 1 |
| do 200 l = 1, lup |
| c |
| c previous version only cycled l to lup |
| c |
| c cycle the columns from l to p left-to-right until one |
| c with non-negligible norm is located. a column is considered |
| c to have become negligible if its norm has fallen below |
| c tol times its original norm. the check for l .le. k |
| c avoids infinite cycling. |
| c |
| 80 continue |
| if (l .ge. k .or. qraux(l) .ge. work(l,2)*tol) go to 120 |
| lp1 = l+1 |
| do 100 i=1,n |
| t = x(i,l) |
| do 90 j=lp1,p |
| x(i,j-1) = x(i,j) |
| 90 continue |
| x(i,p) = t |
| 100 continue |
| i = jpvt(l) |
| t = qraux(l) |
| tt = work(l,1) |
| ttt = work(l,2) |
| do 110 j=lp1,p |
| jpvt(j-1) = jpvt(j) |
| qraux(j-1) = qraux(j) |
| work(j-1,1) = work(j,1) |
| work(j-1,2) = work(j,2) |
| 110 continue |
| jpvt(p) = i |
| qraux(p) = t |
| work(p,1) = tt |
| work(p,2) = ttt |
| k = k - 1 |
| go to 80 |
| 120 continue |
| if (l .eq. n) go to 190 |
| c |
| c compute the householder transformation for column l. |
| c |
| nrmxl = dnrm2(n-l+1,x(l,l),1) |
| if (nrmxl .eq. 0.0d0) go to 180 |
| if (x(l,l) .ne. 0.0d0) nrmxl = dsign(nrmxl,x(l,l)) |
| call dscal(n-l+1,1.0d0/nrmxl,x(l,l),1) |
| x(l,l) = 1.0d0 + x(l,l) |
| c |
| c apply the transformation to the remaining columns, |
| c updating the norms. |
| c |
| lp1 = l + 1 |
| if (p .lt. lp1) go to 170 |
| do 160 j = lp1, p |
| t = -ddot(n-l+1,x(l,l),1,x(l,j),1)/x(l,l) |
| call daxpy(n-l+1,t,x(l,l),1,x(l,j),1) |
| if (qraux(j) .eq. 0.0d0) go to 150 |
| tt = 1.0d0 - (dabs(x(l,j))/qraux(j))**2 |
| tt = dmax1(tt,0.0d0) |
| t = tt |
| c |
| c modified 9/99 by BDR. Re-compute norms if there is large reduction |
| c The tolerance here is on the squared norm |
| c In this version we need accurate norms, so re-compute often. |
| c work(j,1) is only updated in one case: looks like a bug -- no longer used |
| c |
| c tt = 1.0d0 + 0.05d0*tt*(qraux(j)/work(j,1))**2 |
| c if (tt .eq. 1.0d0) go to 130 |
| if (dabs(t) .lt. 1d-6) go to 130 |
| qraux(j) = qraux(j)*dsqrt(t) |
| go to 140 |
| 130 continue |
| qraux(j) = dnrm2(n-l,x(l+1,j),1) |
| work(j,1) = qraux(j) |
| 140 continue |
| 150 continue |
| 160 continue |
| 170 continue |
| c |
| c save the transformation. |
| c |
| qraux(l) = x(l,l) |
| x(l,l) = -nrmxl |
| 180 continue |
| 190 continue |
| 200 continue |
| k = min0(k - 1, n) |
| return |
| end |