blob: f11aa55fa038fc493a830e1e55e29920a5724d48 [file] [log] [blame]
c
c dqrdc uses householder transformations to compute the qr
c factorization of an n by p matrix x. column pivoting
c based on the 2-norms of the reduced columns may be
c performed at the users option.
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 jpvt integer(p).
c jpvt contains integers that control the selection
c of the pivot columns. the k-th column x(k) of x
c is placed in one of three classes according to the
c value of jpvt(k).
c
c if jpvt(k) .gt. 0, then x(k) is an initial
c column.
c
c if jpvt(k) .eq. 0, then x(k) is a free column.
c
c if jpvt(k) .lt. 0, then x(k) is a final column.
c
c before the decomposition is computed, initial columns
c are moved to the beginning of the array x and final
c columns to the end. both initial and final columns
c are frozen in place during the computation and only
c free columns are moved. at the k-th stage of the
c reduction, if x(k) is occupied by a free column
c it is interchanged with the free column of largest
c reduced norm. jpvt is not referenced if
c job .eq. 0.
c
c work double precision(p).
c work is a work array. work is not referenced if
c job .eq. 0.
c
c job integer.
c job is an integer that initiates column pivoting.
c if job .eq. 0, no pivoting is done.
c if job .ne. 0, pivoting is done.
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 qraux double precision(p).
c qraux contains further information required to recover
c the orthogonal part of the decomposition.
c
c jpvt jpvt(k) contains the index of the column of the
c original matrix that has been interchanged into
c the k-th column, if pivoting was requested.
c
c linpack. this version dated 08/14/78 .
c g.w. stewart, university of maryland, argonne national lab.
c
c dqrdc uses the following functions and subprograms.
c
c blas daxpy,ddot,dscal,dswap,dnrm2
c fortran dabs,dmax1,min0,dsqrt
c
subroutine dqrdc(x,ldx,n,p,qraux,jpvt,work,job)
integer ldx,n,p,job
integer jpvt(p)
double precision x(ldx,p),qraux(p),work(p)
c
c internal variables
c
integer j,jp,jj, l,lp1,lup,maxj,pl,pu
double precision maxnrm,dnrm2,tt
double precision ddot,nrmxl,t
logical negj,swapj
c
c
pl = 1
pu = 0
if (job .eq. 0) go to 60
c
c pivoting has been requested. rearrange the columns
c according to jpvt.
c
do 20 j = 1, p
swapj = jpvt(j) .gt. 0
negj = jpvt(j) .lt. 0
jpvt(j) = j
if (negj) jpvt(j) = -j
if (.not.swapj) go to 10
if (j .ne. pl) call dswap(n,x(1,pl),1,x(1,j),1)
jpvt(j) = jpvt(pl)
jpvt(pl) = j
pl = pl + 1
10 continue
20 continue
pu = p
do 50 jj = 1, p
j = p - jj + 1
if (jpvt(j) .ge. 0) go to 40
jpvt(j) = -jpvt(j)
if (j .eq. pu) go to 30
call dswap(n,x(1,pu),1,x(1,j),1)
jp = jpvt(pu)
jpvt(pu) = jpvt(j)
jpvt(j) = jp
30 continue
pu = pu - 1
40 continue
50 continue
60 continue
c
c compute the norms of the free columns.
c
if (pu .lt. pl) go to 80
do 70 j = pl, pu
qraux(j) = dnrm2(n,x(1,j),1)
work(j) = qraux(j)
70 continue
80 continue
c
c perform the householder reduction of x.
c
lup = min0(n,p)
do 200 l = 1, lup
if (l .lt. pl .or. l .ge. pu) go to 120
c
c locate the column of largest norm and bring it
c into the pivot position.
c
maxnrm = 0.0d0
maxj = l
do 100 j = l, pu
if (qraux(j) .le. maxnrm) go to 90
maxnrm = qraux(j)
maxj = j
90 continue
100 continue
if (maxj .eq. l) go to 110
call dswap(n,x(1,l),1,x(1,maxj),1)
qraux(maxj) = qraux(l)
work(maxj) = work(l)
jp = jpvt(maxj)
jpvt(maxj) = jpvt(l)
jpvt(l) = jp
110 continue
120 continue
qraux(l) = 0.0d0
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 (j .lt. pl .or. j .gt. pu) go to 150
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
tt = 1.0d0 + 0.05d0*tt*(qraux(j)/work(j))**2
if (tt .eq. 1.0d0) 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) = 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
return
end