Rev 35751 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
SUBROUTINE DBDSDC( UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ,$ WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* December 1, 1999** .. Scalar Arguments ..CHARACTER COMPQ, UPLOINTEGER INFO, LDU, LDVT, N* ..* .. Array Arguments ..INTEGER IQ( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), Q( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** Purpose* =======** DBDSDC computes the singular value decomposition (SVD) of a real* N-by-N (upper or lower) bidiagonal matrix B: B = U * S * VT,* using a divide and conquer method, where S is a diagonal matrix* with non-negative diagonal elements (the singular values of B), and* U and VT are orthogonal matrices of left and right singular vectors,* respectively. DBDSDC can be used to compute all singular values,* and optionally, singular vectors or singular vectors in compact form.** This code makes very mild assumptions about floating point* arithmetic. It will work on machines with a guard digit in* add/subtract, or on those binary machines without guard digits* which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.* It could conceivably fail on hexadecimal or decimal machines* without guard digits, but we know of none. See DLASD3 for details.** The code currently call DLASDQ if singular values only are desired.* However, it can be slightly modified to compute singular values* using the divide and conquer method.** Arguments* =========** UPLO (input) CHARACTER*1* = 'U': B is upper bidiagonal.* = 'L': B is lower bidiagonal.** COMPQ (input) CHARACTER*1* Specifies whether singular vectors are to be computed* as follows:* = 'N': Compute singular values only;* = 'P': Compute singular values and compute singular* vectors in compact form;* = 'I': Compute singular values and singular vectors.** N (input) INTEGER* The order of the matrix B. N >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the n diagonal elements of the bidiagonal matrix B.* On exit, if INFO=0, the singular values of B.** E (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the elements of E contain the offdiagonal* elements of the bidiagonal matrix whose SVD is desired.* On exit, E has been destroyed.** U (output) DOUBLE PRECISION array, dimension (LDU,N)* If COMPQ = 'I', then:* On exit, if INFO = 0, U contains the left singular vectors* of the bidiagonal matrix.* For other values of COMPQ, U is not referenced.** LDU (input) INTEGER* The leading dimension of the array U. LDU >= 1.* If singular vectors are desired, then LDU >= max( 1, N ).** VT (output) DOUBLE PRECISION array, dimension (LDVT,N)* If COMPQ = 'I', then:* On exit, if INFO = 0, VT' contains the right singular* vectors of the bidiagonal matrix.* For other values of COMPQ, VT is not referenced.** LDVT (input) INTEGER* The leading dimension of the array VT. LDVT >= 1.* If singular vectors are desired, then LDVT >= max( 1, N ).** Q (output) DOUBLE PRECISION array, dimension (LDQ)* If COMPQ = 'P', then:* On exit, if INFO = 0, Q and IQ contain the left* and right singular vectors in a compact form,* requiring O(N log N) space instead of 2*N**2.* In particular, Q contains all the DOUBLE PRECISION data in* LDQ >= N*(11 + 2*SMLSIZ + 8*INT(LOG_2(N/(SMLSIZ+1))))* words of memory, where SMLSIZ is returned by ILAENV and* is equal to the maximum size of the subproblems at the* bottom of the computation tree (usually about 25).* For other values of COMPQ, Q is not referenced.** IQ (output) INTEGER array, dimension (LDIQ)* If COMPQ = 'P', then:* On exit, if INFO = 0, Q and IQ contain the left* and right singular vectors in a compact form,* requiring O(N log N) space instead of 2*N**2.* In particular, IQ contains all INTEGER data in* LDIQ >= N*(3 + 3*INT(LOG_2(N/(SMLSIZ+1))))* words of memory, where SMLSIZ is returned by ILAENV and* is equal to the maximum size of the subproblems at the* bottom of the computation tree (usually about 25).* For other values of COMPQ, IQ is not referenced.** WORK (workspace) DOUBLE PRECISION array, dimension (LWORK)* If COMPQ = 'N' then LWORK >= (4 * N).* If COMPQ = 'P' then LWORK >= (6 * N).* If COMPQ = 'I' then LWORK >= (3 * N**2 + 4 * N).** IWORK (workspace) INTEGER array, dimension (8*N)** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: The algorithm failed to compute an singular value.* The update process of divide and conquer failed.** Further Details* ===============** Based on contributions by* Ming Gu and Huan Ren, Computer Science Division, University of* California at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER DIFL, DIFR, GIVCOL, GIVNUM, GIVPTR, I, IC,$ ICOMPQ, IERR, II, IS, IU, IUPLO, IVT, J, K, KK,$ MLVL, NM1, NSIZE, PERM, POLES, QSTART, SMLSIZ,$ SMLSZP, SQRE, START, WSTART, ZDOUBLE PRECISION CS, EPS, ORGNRM, P, R, SN* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, ILAENV, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DLARTG, DLASCL, DLASD0, DLASDA, DLASDQ,$ DLASET, DLASR, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, SIGN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IUPLO = 0IF( LSAME( UPLO, 'U' ) )$ IUPLO = 1IF( LSAME( UPLO, 'L' ) )$ IUPLO = 2IF( LSAME( COMPQ, 'N' ) ) THENICOMPQ = 0ELSE IF( LSAME( COMPQ, 'P' ) ) THENICOMPQ = 1ELSE IF( LSAME( COMPQ, 'I' ) ) THENICOMPQ = 2ELSEICOMPQ = -1END IFIF( IUPLO.EQ.0 ) THENINFO = -1ELSE IF( ICOMPQ.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ( LDU.LT.1 ) .OR. ( ( ICOMPQ.EQ.2 ) .AND. ( LDU.LT.$ N ) ) ) THENINFO = -7ELSE IF( ( LDVT.LT.1 ) .OR. ( ( ICOMPQ.EQ.2 ) .AND. ( LDVT.LT.$ N ) ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DBDSDC', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNSMLSIZ = ILAENV( 9, 'DBDSDC', ' ', 0, 0, 0, 0 )IF( N.EQ.1 ) THENIF( ICOMPQ.EQ.1 ) THENQ( 1 ) = SIGN( ONE, D( 1 ) )Q( 1+SMLSIZ*N ) = ONEELSE IF( ICOMPQ.EQ.2 ) THENU( 1, 1 ) = SIGN( ONE, D( 1 ) )VT( 1, 1 ) = ONEEND IFD( 1 ) = ABS( D( 1 ) )RETURNEND IFNM1 = N - 1** If matrix lower bidiagonal, rotate to be upper bidiagonal* by applying Givens rotations on the left*WSTART = 1QSTART = 3IF( ICOMPQ.EQ.1 ) THENCALL DCOPY( N, D, 1, Q( 1 ), 1 )CALL DCOPY( N-1, E, 1, Q( N+1 ), 1 )END IFIF( IUPLO.EQ.2 ) THENQSTART = 5WSTART = 2*N - 1DO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )IF( ICOMPQ.EQ.1 ) THENQ( I+2*N ) = CSQ( I+3*N ) = SNELSE IF( ICOMPQ.EQ.2 ) THENWORK( I ) = CSWORK( NM1+I ) = -SNEND IF10 CONTINUEEND IF** If ICOMPQ = 0, use DLASDQ to compute the singular values.*IF( ICOMPQ.EQ.0 ) THENCALL DLASDQ( 'U', 0, N, 0, 0, 0, D, E, VT, LDVT, U, LDU, U,$ LDU, WORK( WSTART ), INFO )GO TO 40END IF** If N is smaller than the minimum divide size SMLSIZ, then solve* the problem with another solver.*IF( N.LE.SMLSIZ ) THENIF( ICOMPQ.EQ.2 ) THENCALL DLASET( 'A', N, N, ZERO, ONE, U, LDU )CALL DLASET( 'A', N, N, ZERO, ONE, VT, LDVT )CALL DLASDQ( 'U', 0, N, N, N, 0, D, E, VT, LDVT, U, LDU, U,$ LDU, WORK( WSTART ), INFO )ELSE IF( ICOMPQ.EQ.1 ) THENIU = 1IVT = IU + NCALL DLASET( 'A', N, N, ZERO, ONE, Q( IU+( QSTART-1 )*N ),$ N )CALL DLASET( 'A', N, N, ZERO, ONE, Q( IVT+( QSTART-1 )*N ),$ N )CALL DLASDQ( 'U', 0, N, N, N, 0, D, E,$ Q( IVT+( QSTART-1 )*N ), N,$ Q( IU+( QSTART-1 )*N ), N,$ Q( IU+( QSTART-1 )*N ), N, WORK( WSTART ),$ INFO )END IFGO TO 40END IF*IF( ICOMPQ.EQ.2 ) THENCALL DLASET( 'A', N, N, ZERO, ONE, U, LDU )CALL DLASET( 'A', N, N, ZERO, ONE, VT, LDVT )END IF** Scale.*ORGNRM = DLANST( 'M', N, D, E )IF( ORGNRM.EQ.ZERO )$ RETURNCALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, IERR )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, IERR )*EPS = DLAMCH( 'Epsilon' )*MLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1SMLSZP = SMLSIZ + 1*IF( ICOMPQ.EQ.1 ) THENIU = 1IVT = 1 + SMLSIZDIFL = IVT + SMLSZPDIFR = DIFL + MLVLZ = DIFR + MLVL*2IC = Z + MLVLIS = IC + 1POLES = IS + 1GIVNUM = POLES + 2*MLVL*K = 1GIVPTR = 2PERM = 3GIVCOL = PERM + MLVLEND IF*DO 20 I = 1, NIF( ABS( D( I ) ).LT.EPS ) THEND( I ) = SIGN( EPS, D( I ) )END IF20 CONTINUE*START = 1SQRE = 0*DO 30 I = 1, NM1IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN** Subproblem found. First determine its size and then* apply divide and conquer on it.*IF( I.LT.NM1 ) THEN** A subproblem with E(I) small for I < NM1.*NSIZE = I - START + 1ELSE IF( ABS( E( I ) ).GE.EPS ) THEN** A subproblem with E(NM1) not too small but I = NM1.*NSIZE = N - START + 1ELSE** A subproblem with E(NM1) small. This implies an* 1-by-1 subproblem at D(N). Solve this 1-by-1 problem* first.*NSIZE = I - START + 1IF( ICOMPQ.EQ.2 ) THENU( N, N ) = SIGN( ONE, D( N ) )VT( N, N ) = ONEELSE IF( ICOMPQ.EQ.1 ) THENQ( N+( QSTART-1 )*N ) = SIGN( ONE, D( N ) )Q( N+( SMLSIZ+QSTART-1 )*N ) = ONEEND IFD( N ) = ABS( D( N ) )END IFIF( ICOMPQ.EQ.2 ) THENCALL DLASD0( NSIZE, SQRE, D( START ), E( START ),$ U( START, START ), LDU, VT( START, START ),$ LDVT, SMLSIZ, IWORK, WORK( WSTART ), INFO )ELSECALL DLASDA( ICOMPQ, SMLSIZ, NSIZE, SQRE, D( START ),$ E( START ), Q( START+( IU+QSTART-2 )*N ), N,$ Q( START+( IVT+QSTART-2 )*N ),$ IQ( START+K*N ), Q( START+( DIFL+QSTART-2 )*$ N ), Q( START+( DIFR+QSTART-2 )*N ),$ Q( START+( Z+QSTART-2 )*N ),$ Q( START+( POLES+QSTART-2 )*N ),$ IQ( START+GIVPTR*N ), IQ( START+GIVCOL*N ),$ N, IQ( START+PERM*N ),$ Q( START+( GIVNUM+QSTART-2 )*N ),$ Q( START+( IC+QSTART-2 )*N ),$ Q( START+( IS+QSTART-2 )*N ),$ WORK( WSTART ), IWORK, INFO )IF( INFO.NE.0 ) THENRETURNEND IFEND IFSTART = I + 1END IF30 CONTINUE** Unscale*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, IERR )40 CONTINUE** Use Selection Sort to minimize swaps of singular vectors*DO 60 II = 2, NI = II - 1KK = IP = D( I )DO 50 J = II, NIF( D( J ).GT.P ) THENKK = JP = D( J )END IF50 CONTINUEIF( KK.NE.I ) THEND( KK ) = D( I )D( I ) = PIF( ICOMPQ.EQ.1 ) THENIQ( I ) = KKELSE IF( ICOMPQ.EQ.2 ) THENCALL DSWAP( N, U( 1, I ), 1, U( 1, KK ), 1 )CALL DSWAP( N, VT( I, 1 ), LDVT, VT( KK, 1 ), LDVT )END IFELSE IF( ICOMPQ.EQ.1 ) THENIQ( I ) = IEND IF60 CONTINUE** If ICOMPQ = 1, use IQ(N,1) as the indicator for UPLO*IF( ICOMPQ.EQ.1 ) THENIF( IUPLO.EQ.1 ) THENIQ( N ) = 1ELSEIQ( N ) = 0END IFEND IF** If B is lower bidiagonal, update U by those Givens rotations* which rotated B to be upper bidiagonal*IF( ( IUPLO.EQ.2 ) .AND. ( ICOMPQ.EQ.2 ) )$ CALL DLASR( 'L', 'V', 'B', N, N, WORK( 1 ), WORK( N ), U, LDU )*RETURN** End of DBDSDC*ENDSUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,$ LDU, C, LDC, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** Purpose* =======** DBDSQR computes the singular value decomposition (SVD) of a real* N-by-N (upper or lower) bidiagonal matrix B: B = Q * S * P' (P'* denotes the transpose of P), where S is a diagonal matrix with* non-negative diagonal elements (the singular values of B), and Q* and P are orthogonal matrices.** The routine computes S, and optionally computes U * Q, P' * VT,* or Q' * C, for given real input matrices U, VT, and C.** See "Computing Small Singular Values of Bidiagonal Matrices With* Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,* LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,* no. 5, pp. 873-912, Sept 1990) and* "Accurate singular values and differential qd algorithms," by* B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics* Department, University of California at Berkeley, July 1992* for a detailed description of the algorithm.** Arguments* =========** UPLO (input) CHARACTER*1* = 'U': B is upper bidiagonal;* = 'L': B is lower bidiagonal.** N (input) INTEGER* The order of the matrix B. N >= 0.** NCVT (input) INTEGER* The number of columns of the matrix VT. NCVT >= 0.** NRU (input) INTEGER* The number of rows of the matrix U. NRU >= 0.** NCC (input) INTEGER* The number of columns of the matrix C. NCC >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the n diagonal elements of the bidiagonal matrix B.* On exit, if INFO=0, the singular values of B in decreasing* order.** E (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the elements of E contain the* offdiagonal elements of the bidiagonal matrix whose SVD* is desired. On normal exit (INFO = 0), E is destroyed.* If the algorithm does not converge (INFO > 0), D and E* will contain the diagonal and superdiagonal elements of a* bidiagonal matrix orthogonally equivalent to the one given* as input. E(N) is used for workspace.** VT (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)* On entry, an N-by-NCVT matrix VT.* On exit, VT is overwritten by P' * VT.* VT is not referenced if NCVT = 0.** LDVT (input) INTEGER* The leading dimension of the array VT.* LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.** U (input/output) DOUBLE PRECISION array, dimension (LDU, N)* On entry, an NRU-by-N matrix U.* On exit, U is overwritten by U * Q.* U is not referenced if NRU = 0.** LDU (input) INTEGER* The leading dimension of the array U. LDU >= max(1,NRU).** C (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)* On entry, an N-by-NCC matrix C.* On exit, C is overwritten by Q' * C.* C is not referenced if NCC = 0.** LDC (input) INTEGER* The leading dimension of the array C.* LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.** WORK (workspace) DOUBLE PRECISION array, dimension (4*N)** INFO (output) INTEGER* = 0: successful exit* < 0: If INFO = -i, the i-th argument had an illegal value* > 0: the algorithm did not converge; D and E contain the* elements of a bidiagonal matrix which is orthogonally* similar to the input matrix B; if INFO = i, i* elements of E have not converged to zero.** Internal Parameters* ===================** TOLMUL DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8)))* TOLMUL controls the convergence criterion of the QR loop.* If it is positive, TOLMUL*EPS is the desired relative* precision in the computed singular values.* If it is negative, abs(TOLMUL*EPS*sigma_max) is the* desired absolute accuracy in the computed singular* values (corresponds to relative accuracy* abs(TOLMUL*EPS) in the largest singular value.* abs(TOLMUL) should be between 1 and 1/EPS, and preferably* between 10 (for fast convergence) and .1/EPS* (for there to be some accuracy in the results).* Default is to lose at either one eighth or 2 of the* available decimal digits in each computed singular value* (whichever is smaller).** MAXITR INTEGER, default = 6* MAXITR controls the maximum number of passes of the* algorithm through its inner loop. The algorithms stops* (and so fails to converge) if the number of passes* through the inner loop exceeds MAXITR*N**2.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION NEGONEPARAMETER ( NEGONE = -1.0D0 )DOUBLE PRECISION HNDRTHPARAMETER ( HNDRTH = 0.01D0 )DOUBLE PRECISION TENPARAMETER ( TEN = 10.0D0 )DOUBLE PRECISION HNDRDPARAMETER ( HNDRD = 100.0D0 )DOUBLE PRECISION MEIGTHPARAMETER ( MEIGTH = -0.125D0 )INTEGER MAXITRPARAMETER ( MAXITR = 6 )* ..* .. Local Scalars ..LOGICAL LOWER, ROTATEINTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,$ NM12, NM13, OLDLL, OLDMDOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,$ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,$ SINR, SLL, SMAX, SMIN, SMINL, SMINLO, SMINOA,$ SN, THRESH, TOL, TOLMUL, UNFL* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLARTG, DLAS2, DLASQ1, DLASR, DLASV2, DROT,$ DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0LOWER = LSAME( UPLO, 'L' )IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NCVT.LT.0 ) THENINFO = -3ELSE IF( NRU.LT.0 ) THENINFO = -4ELSE IF( NCC.LT.0 ) THENINFO = -5ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.$ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THENINFO = -9ELSE IF( LDU.LT.MAX( 1, NRU ) ) THENINFO = -11ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.$ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DBDSQR', -INFO )RETURNEND IFIF( N.EQ.0 )$ RETURNIF( N.EQ.1 )$ GO TO 160** ROTATE is true if any singular vectors desired, false otherwise*ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )** If no singular vectors desired, use qd algorithm*IF( .NOT.ROTATE ) THENCALL DLASQ1( N, D, E, WORK, INFO )RETURNEND IF*NM1 = N - 1NM12 = NM1 + NM1NM13 = NM12 + NM1IDIR = 0** Get machine constants*EPS = DLAMCH( 'Epsilon' )UNFL = DLAMCH( 'Safe minimum' )** If matrix lower bidiagonal, rotate to be upper bidiagonal* by applying Givens rotations on the left*IF( LOWER ) THENDO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )WORK( I ) = CSWORK( NM1+I ) = SN10 CONTINUE** Update singular vectors if desired*IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ), WORK( N ), U,$ LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ), WORK( N ), C,$ LDC )END IF** Compute singular values to relative accuracy TOL* (By setting TOL to be negative, algorithm will compute* singular values to absolute accuracy ABS(TOL)*norm(input matrix))*TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )TOL = TOLMUL*EPS** Compute approximate maximum, minimum singular values*SMAX = ZERODO 20 I = 1, NSMAX = MAX( SMAX, ABS( D( I ) ) )20 CONTINUEDO 30 I = 1, N - 1SMAX = MAX( SMAX, ABS( E( I ) ) )30 CONTINUESMINL = ZEROIF( TOL.GE.ZERO ) THEN** Relative accuracy desired*SMINOA = ABS( D( 1 ) )IF( SMINOA.EQ.ZERO )$ GO TO 50MU = SMINOADO 40 I = 2, NMU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )SMINOA = MIN( SMINOA, MU )IF( SMINOA.EQ.ZERO )$ GO TO 5040 CONTINUE50 CONTINUESMINOA = SMINOA / SQRT( DBLE( N ) )THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )ELSE** Absolute accuracy desired*THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )END IF** Prepare for main iteration loop for the singular values* (MAXIT is the maximum number of passes through the inner* loop permitted before nonconvergence signalled.)*MAXIT = MAXITR*N*NITER = 0OLDLL = -1OLDM = -1** M points to last element of unconverged part of matrix*M = N** Begin main iteration loop*60 CONTINUE** Check for convergence or exceeding iteration count*IF( M.LE.1 )$ GO TO 160IF( ITER.GT.MAXIT )$ GO TO 200** Find diagonal block of matrix to work on*IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )$ D( M ) = ZEROSMAX = ABS( D( M ) )SMIN = SMAXDO 70 LLL = 1, M - 1LL = M - LLLABSS = ABS( D( LL ) )ABSE = ABS( E( LL ) )IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )$ D( LL ) = ZEROIF( ABSE.LE.THRESH )$ GO TO 80SMIN = MIN( SMIN, ABSS )SMAX = MAX( SMAX, ABSS, ABSE )70 CONTINUELL = 0GO TO 9080 CONTINUEE( LL ) = ZERO** Matrix splits since E(LL) = 0*IF( LL.EQ.M-1 ) THEN** Convergence of bottom singular value, return to top of loop*M = M - 1GO TO 60END IF90 CONTINUELL = LL + 1** E(LL) through E(M-1) are nonzero, E(LL-1) is zero*IF( LL.EQ.M-1 ) THEN** 2 by 2 block, handle separately*CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,$ COSR, SINL, COSL )D( M-1 ) = SIGMXE( M-1 ) = ZEROD( M ) = SIGMN** Compute singular vectors, if desired*IF( NCVT.GT.0 )$ CALL DROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, COSR,$ SINR )IF( NRU.GT.0 )$ CALL DROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )IF( NCC.GT.0 )$ CALL DROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,$ SINL )M = M - 2GO TO 60END IF** If working on new submatrix, choose shift direction* (from larger end diagonal element towards smaller)*IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THENIF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN** Chase bulge from top (big end) to bottom (small end)*IDIR = 1ELSE** Chase bulge from bottom (big end) to top (small end)*IDIR = 2END IFEND IF** Apply convergence tests*IF( IDIR.EQ.1 ) THEN** Run convergence test in forward direction* First apply standard test to bottom of matrix*IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.$ ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THENE( M-1 ) = ZEROGO TO 60END IF*IF( TOL.GE.ZERO ) THEN** If relative accuracy desired,* apply convergence criterion forward*MU = ABS( D( LL ) )SMINL = MUDO 100 LLL = LL, M - 1IF( ABS( E( LLL ) ).LE.TOL*MU ) THENE( LLL ) = ZEROGO TO 60END IFSMINLO = SMINLMU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )SMINL = MIN( SMINL, MU )100 CONTINUEEND IF*ELSE** Run convergence test in backward direction* First apply standard test to top of matrix*IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.$ ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THENE( LL ) = ZEROGO TO 60END IF*IF( TOL.GE.ZERO ) THEN** If relative accuracy desired,* apply convergence criterion backward*MU = ABS( D( M ) )SMINL = MUDO 110 LLL = M - 1, LL, -1IF( ABS( E( LLL ) ).LE.TOL*MU ) THENE( LLL ) = ZEROGO TO 60END IFSMINLO = SMINLMU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )SMINL = MIN( SMINL, MU )110 CONTINUEEND IFEND IFOLDLL = LLOLDM = M** Compute shift. First, test if shifting would ruin relative* accuracy, and if so set the shift to zero.*IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.$ MAX( EPS, HNDRTH*TOL ) ) THEN** Use a zero shift to avoid loss of relative accuracy*SHIFT = ZEROELSE** Compute the shift from 2-by-2 block at end of matrix*IF( IDIR.EQ.1 ) THENSLL = ABS( D( LL ) )CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )ELSESLL = ABS( D( M ) )CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )END IF** Test if shift negligible, and if so set to zero*IF( SLL.GT.ZERO ) THENIF( ( SHIFT / SLL )**2.LT.EPS )$ SHIFT = ZEROEND IFEND IF** Increment iteration count*ITER = ITER + M - LL** If SHIFT = 0, do simplified QR iteration*IF( SHIFT.EQ.ZERO ) THENIF( IDIR.EQ.1 ) THEN** Chase bulge from top to bottom* Save cosines and sines for later singular vector updates*CS = ONEOLDCS = ONEDO 120 I = LL, M - 1CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )IF( I.GT.LL )$ E( I-1 ) = OLDSN*RCALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )WORK( I-LL+1 ) = CSWORK( I-LL+1+NM1 ) = SNWORK( I-LL+1+NM12 ) = OLDCSWORK( I-LL+1+NM13 ) = OLDSN120 CONTINUEH = D( M )*CSD( M ) = H*OLDCSE( M-1 ) = H*OLDSN** Update singular vectors*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),$ WORK( N ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),$ WORK( NM13+1 ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),$ WORK( NM13+1 ), C( LL, 1 ), LDC )** Test convergence*IF( ABS( E( M-1 ) ).LE.THRESH )$ E( M-1 ) = ZERO*ELSE** Chase bulge from bottom to top* Save cosines and sines for later singular vector updates*CS = ONEOLDCS = ONEDO 130 I = M, LL + 1, -1CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )IF( I.LT.M )$ E( I ) = OLDSN*RCALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )WORK( I-LL ) = CSWORK( I-LL+NM1 ) = -SNWORK( I-LL+NM12 ) = OLDCSWORK( I-LL+NM13 ) = -OLDSN130 CONTINUEH = D( LL )*CSD( LL ) = H*OLDCSE( LL ) = H*OLDSN** Update singular vectors*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),$ WORK( NM13+1 ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),$ WORK( N ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),$ WORK( N ), C( LL, 1 ), LDC )** Test convergence*IF( ABS( E( LL ) ).LE.THRESH )$ E( LL ) = ZEROEND IFELSE** Use nonzero shift*IF( IDIR.EQ.1 ) THEN** Chase bulge from top to bottom* Save cosines and sines for later singular vector updates*F = ( ABS( D( LL ) )-SHIFT )*$ ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )G = E( LL )DO 140 I = LL, M - 1CALL DLARTG( F, G, COSR, SINR, R )IF( I.GT.LL )$ E( I-1 ) = RF = COSR*D( I ) + SINR*E( I )E( I ) = COSR*E( I ) - SINR*D( I )G = SINR*D( I+1 )D( I+1 ) = COSR*D( I+1 )CALL DLARTG( F, G, COSL, SINL, R )D( I ) = RF = COSL*E( I ) + SINL*D( I+1 )D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )IF( I.LT.M-1 ) THENG = SINL*E( I+1 )E( I+1 ) = COSL*E( I+1 )END IFWORK( I-LL+1 ) = COSRWORK( I-LL+1+NM1 ) = SINRWORK( I-LL+1+NM12 ) = COSLWORK( I-LL+1+NM13 ) = SINL140 CONTINUEE( M-1 ) = F** Update singular vectors*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),$ WORK( N ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),$ WORK( NM13+1 ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),$ WORK( NM13+1 ), C( LL, 1 ), LDC )** Test convergence*IF( ABS( E( M-1 ) ).LE.THRESH )$ E( M-1 ) = ZERO*ELSE** Chase bulge from bottom to top* Save cosines and sines for later singular vector updates*F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /$ D( M ) )G = E( M-1 )DO 150 I = M, LL + 1, -1CALL DLARTG( F, G, COSR, SINR, R )IF( I.LT.M )$ E( I ) = RF = COSR*D( I ) + SINR*E( I-1 )E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )G = SINR*D( I-1 )D( I-1 ) = COSR*D( I-1 )CALL DLARTG( F, G, COSL, SINL, R )D( I ) = RF = COSL*E( I-1 ) + SINL*D( I-1 )D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )IF( I.GT.LL+1 ) THENG = SINL*E( I-2 )E( I-2 ) = COSL*E( I-2 )END IFWORK( I-LL ) = COSRWORK( I-LL+NM1 ) = -SINRWORK( I-LL+NM12 ) = COSLWORK( I-LL+NM13 ) = -SINL150 CONTINUEE( LL ) = F** Test convergence*IF( ABS( E( LL ) ).LE.THRESH )$ E( LL ) = ZERO** Update singular vectors if desired*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),$ WORK( NM13+1 ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),$ WORK( N ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),$ WORK( N ), C( LL, 1 ), LDC )END IFEND IF** QR iteration finished, go back and check convergence*GO TO 60** All singular values converged, so make them positive*160 CONTINUEDO 170 I = 1, NIF( D( I ).LT.ZERO ) THEND( I ) = -D( I )** Change sign of singular vectors, if desired*IF( NCVT.GT.0 )$ CALL DSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )END IF170 CONTINUE** Sort the singular values into decreasing order (insertion sort on* singular values, but only one transposition per singular vector)*DO 190 I = 1, N - 1** Scan for smallest D(I)*ISUB = 1SMIN = D( 1 )DO 180 J = 2, N + 1 - IIF( D( J ).LE.SMIN ) THENISUB = JSMIN = D( J )END IF180 CONTINUEIF( ISUB.NE.N+1-I ) THEN** Swap singular values and vectors*D( ISUB ) = D( N+1-I )D( N+1-I ) = SMINIF( NCVT.GT.0 )$ CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),$ LDVT )IF( NRU.GT.0 )$ CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )IF( NCC.GT.0 )$ CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )END IF190 CONTINUEGO TO 220** Maximum number of iterations exceeded, failure to converge*200 CONTINUEINFO = 0DO 210 I = 1, N - 1IF( E( I ).NE.ZERO )$ INFO = INFO + 1210 CONTINUE220 CONTINUERETURN** End of DBDSQR*ENDSUBROUTINE DDISNA( JOB, M, N, D, SEP, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER JOBINTEGER INFO, M, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), SEP( * )* ..** Purpose* =======** DDISNA computes the reciprocal condition numbers for the eigenvectors* of a real symmetric or complex Hermitian matrix or for the left or* right singular vectors of a general m-by-n matrix. The reciprocal* condition number is the 'gap' between the corresponding eigenvalue or* singular value and the nearest other one.** The bound on the error, measured by angle in radians, in the I-th* computed vector is given by** DLAMCH( 'E' ) * ( ANORM / SEP( I ) )** where ANORM = 2-norm(A) = max( abs( D(j) ) ). SEP(I) is not allowed* to be smaller than DLAMCH( 'E' )*ANORM in order to limit the size of* the error bound.** DDISNA may also be used to compute error bounds for eigenvectors of* the generalized symmetric definite eigenproblem.** Arguments* =========** JOB (input) CHARACTER*1* Specifies for which problem the reciprocal condition numbers* should be computed:* = 'E': the eigenvectors of a symmetric/Hermitian matrix;* = 'L': the left singular vectors of a general matrix;* = 'R': the right singular vectors of a general matrix.** M (input) INTEGER* The number of rows of the matrix. M >= 0.** N (input) INTEGER* If JOB = 'L' or 'R', the number of columns of the matrix,* in which case N >= 0. Ignored if JOB = 'E'.** D (input) DOUBLE PRECISION array, dimension (M) if JOB = 'E'* dimension (min(M,N)) if JOB = 'L' or 'R'* The eigenvalues (if JOB = 'E') or singular values (if JOB =* 'L' or 'R') of the matrix, in either increasing or decreasing* order. If singular values, they must be non-negative.** SEP (output) DOUBLE PRECISION array, dimension (M) if JOB = 'E'* dimension (min(M,N)) if JOB = 'L' or 'R'* The reciprocal condition numbers of the vectors.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL DECR, EIGEN, INCR, LEFT, RIGHT, SINGINTEGER I, KDOUBLE PRECISION ANORM, EPS, NEWGAP, OLDGAP, SAFMIN, THRESH* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input arguments*INFO = 0EIGEN = LSAME( JOB, 'E' )LEFT = LSAME( JOB, 'L' )RIGHT = LSAME( JOB, 'R' )SING = LEFT .OR. RIGHTIF( EIGEN ) THENK = MELSE IF( SING ) THENK = MIN( M, N )END IFIF( .NOT.EIGEN .AND. .NOT.SING ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( K.LT.0 ) THENINFO = -3ELSEINCR = .TRUE.DECR = .TRUE.DO 10 I = 1, K - 1IF( INCR )$ INCR = INCR .AND. D( I ).LE.D( I+1 )IF( DECR )$ DECR = DECR .AND. D( I ).GE.D( I+1 )10 CONTINUEIF( SING .AND. K.GT.0 ) THENIF( INCR )$ INCR = INCR .AND. ZERO.LE.D( 1 )IF( DECR )$ DECR = DECR .AND. D( K ).GE.ZEROEND IFIF( .NOT.( INCR .OR. DECR ) )$ INFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DDISNA', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.0 )$ RETURN** Compute reciprocal condition numbers*IF( K.EQ.1 ) THENSEP( 1 ) = DLAMCH( 'O' )ELSEOLDGAP = ABS( D( 2 )-D( 1 ) )SEP( 1 ) = OLDGAPDO 20 I = 2, K - 1NEWGAP = ABS( D( I+1 )-D( I ) )SEP( I ) = MIN( OLDGAP, NEWGAP )OLDGAP = NEWGAP20 CONTINUESEP( K ) = OLDGAPEND IFIF( SING ) THENIF( ( LEFT .AND. M.GT.N ) .OR. ( RIGHT .AND. M.LT.N ) ) THENIF( INCR )$ SEP( 1 ) = MIN( SEP( 1 ), D( 1 ) )IF( DECR )$ SEP( K ) = MIN( SEP( K ), D( K ) )END IFEND IF** Ensure that reciprocal condition numbers are not less than* threshold, in order to limit the size of the error bound*EPS = DLAMCH( 'E' )SAFMIN = DLAMCH( 'S' )ANORM = MAX( ABS( D( 1 ) ), ABS( D( K ) ) )IF( ANORM.EQ.ZERO ) THENTHRESH = EPSELSETHRESH = MAX( EPS*ANORM, SAFMIN )END IFDO 30 I = 1, KSEP( I ) = MAX( SEP( I ), THRESH )30 CONTINUE*RETURN** End of DDISNA*ENDSUBROUTINE DGBBRD( VECT, M, N, NCC, KL, KU, AB, LDAB, D, E, Q,$ LDQ, PT, LDPT, C, LDC, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER VECTINTEGER INFO, KL, KU, LDAB, LDC, LDPT, LDQ, M, N, NCC* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), C( LDC, * ), D( * ), E( * ),$ PT( LDPT, * ), Q( LDQ, * ), WORK( * )* ..** Purpose* =======** DGBBRD reduces a real general m-by-n band matrix A to upper* bidiagonal form B by an orthogonal transformation: Q' * A * P = B.** The routine computes B, and optionally forms Q or P', or computes* Q'*C for a given matrix C.** Arguments* =========** VECT (input) CHARACTER*1* Specifies whether or not the matrices Q and P' are to be* formed.* = 'N': do not form Q or P';* = 'Q': form Q only;* = 'P': form P' only;* = 'B': form both.** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** NCC (input) INTEGER* The number of columns of the matrix C. NCC >= 0.** KL (input) INTEGER* The number of subdiagonals of the matrix A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals of the matrix A. KU >= 0.** AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)* On entry, the m-by-n band matrix A, stored in rows 1 to* KL+KU+1. The j-th column of A is stored in the j-th column of* the array AB as follows:* AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl).* On exit, A is overwritten by values generated during the* reduction.** LDAB (input) INTEGER* The leading dimension of the array A. LDAB >= KL+KU+1.** D (output) DOUBLE PRECISION array, dimension (min(M,N))* The diagonal elements of the bidiagonal matrix B.** E (output) DOUBLE PRECISION array, dimension (min(M,N)-1)* The superdiagonal elements of the bidiagonal matrix B.** Q (output) DOUBLE PRECISION array, dimension (LDQ,M)* If VECT = 'Q' or 'B', the m-by-m orthogonal matrix Q.* If VECT = 'N' or 'P', the array Q is not referenced.** LDQ (input) INTEGER* The leading dimension of the array Q.* LDQ >= max(1,M) if VECT = 'Q' or 'B'; LDQ >= 1 otherwise.** PT (output) DOUBLE PRECISION array, dimension (LDPT,N)* If VECT = 'P' or 'B', the n-by-n orthogonal matrix P'.* If VECT = 'N' or 'Q', the array PT is not referenced.** LDPT (input) INTEGER* The leading dimension of the array PT.* LDPT >= max(1,N) if VECT = 'P' or 'B'; LDPT >= 1 otherwise.** C (input/output) DOUBLE PRECISION array, dimension (LDC,NCC)* On entry, an m-by-ncc matrix C.* On exit, C is overwritten by Q'*C.* C is not referenced if NCC = 0.** LDC (input) INTEGER* The leading dimension of the array C.* LDC >= max(1,M) if NCC > 0; LDC >= 1 if NCC = 0.** WORK (workspace) DOUBLE PRECISION array, dimension (2*max(M,N))** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL WANTB, WANTC, WANTPT, WANTQINTEGER I, INCA, J, J1, J2, KB, KB1, KK, KLM, KLU1,$ KUN, L, MINMN, ML, ML0, MN, MU, MU0, NR, NRTDOUBLE PRECISION RA, RB, RC, RS* ..* .. External Subroutines ..EXTERNAL DLARGV, DLARTG, DLARTV, DLASET, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Test the input parameters*WANTB = LSAME( VECT, 'B' )WANTQ = LSAME( VECT, 'Q' ) .OR. WANTBWANTPT = LSAME( VECT, 'P' ) .OR. WANTBWANTC = NCC.GT.0KLU1 = KL + KU + 1INFO = 0IF( .NOT.WANTQ .AND. .NOT.WANTPT .AND. .NOT.LSAME( VECT, 'N' ) )$ THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NCC.LT.0 ) THENINFO = -4ELSE IF( KL.LT.0 ) THENINFO = -5ELSE IF( KU.LT.0 ) THENINFO = -6ELSE IF( LDAB.LT.KLU1 ) THENINFO = -8ELSE IF( LDQ.LT.1 .OR. WANTQ .AND. LDQ.LT.MAX( 1, M ) ) THENINFO = -12ELSE IF( LDPT.LT.1 .OR. WANTPT .AND. LDPT.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDC.LT.1 .OR. WANTC .AND. LDC.LT.MAX( 1, M ) ) THENINFO = -16END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBBRD', -INFO )RETURNEND IF** Initialize Q and P' to the unit matrix, if needed*IF( WANTQ )$ CALL DLASET( 'Full', M, M, ZERO, ONE, Q, LDQ )IF( WANTPT )$ CALL DLASET( 'Full', N, N, ZERO, ONE, PT, LDPT )** Quick return if possible.*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN*MINMN = MIN( M, N )*IF( KL+KU.GT.1 ) THEN** Reduce to upper bidiagonal form if KU > 0; if KU = 0, reduce* first to lower bidiagonal form and then transform to upper* bidiagonal*IF( KU.GT.0 ) THENML0 = 1MU0 = 2ELSEML0 = 2MU0 = 1END IF** Wherever possible, plane rotations are generated and applied in* vector operations of length NR over the index set J1:J2:KLU1.** The sines of the plane rotations are stored in WORK(1:max(m,n))* and the cosines in WORK(max(m,n)+1:2*max(m,n)).*MN = MAX( M, N )KLM = MIN( M-1, KL )KUN = MIN( N-1, KU )KB = KLM + KUNKB1 = KB + 1INCA = KB1*LDABNR = 0J1 = KLM + 2J2 = 1 - KUN*DO 90 I = 1, MINMN** Reduce i-th column and i-th row of matrix to bidiagonal form*ML = KLM + 1MU = KUN + 1DO 80 KK = 1, KBJ1 = J1 + KBJ2 = J2 + KB** generate plane rotations to annihilate nonzero elements* which have been created below the band*IF( NR.GT.0 )$ CALL DLARGV( NR, AB( KLU1, J1-KLM-1 ), INCA,$ WORK( J1 ), KB1, WORK( MN+J1 ), KB1 )** apply plane rotations from the left*DO 10 L = 1, KBIF( J2-KLM+L-1.GT.N ) THENNRT = NR - 1ELSENRT = NREND IFIF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KLU1-L, J1-KLM+L-1 ), INCA,$ AB( KLU1-L+1, J1-KLM+L-1 ), INCA,$ WORK( MN+J1 ), WORK( J1 ), KB1 )10 CONTINUE*IF( ML.GT.ML0 ) THENIF( ML.LE.M-I+1 ) THEN** generate plane rotation to annihilate a(i+ml-1,i)* within the band, and apply rotation from the left*CALL DLARTG( AB( KU+ML-1, I ), AB( KU+ML, I ),$ WORK( MN+I+ML-1 ), WORK( I+ML-1 ),$ RA )AB( KU+ML-1, I ) = RAIF( I.LT.N )$ CALL DROT( MIN( KU+ML-2, N-I ),$ AB( KU+ML-2, I+1 ), LDAB-1,$ AB( KU+ML-1, I+1 ), LDAB-1,$ WORK( MN+I+ML-1 ), WORK( I+ML-1 ) )END IFNR = NR + 1J1 = J1 - KB1END IF*IF( WANTQ ) THEN** accumulate product of plane rotations in Q*DO 20 J = J1, J2, KB1CALL DROT( M, Q( 1, J-1 ), 1, Q( 1, J ), 1,$ WORK( MN+J ), WORK( J ) )20 CONTINUEEND IF*IF( WANTC ) THEN** apply plane rotations to C*DO 30 J = J1, J2, KB1CALL DROT( NCC, C( J-1, 1 ), LDC, C( J, 1 ), LDC,$ WORK( MN+J ), WORK( J ) )30 CONTINUEEND IF*IF( J2+KUN.GT.N ) THEN** adjust J2 to keep within the bounds of the matrix*NR = NR - 1J2 = J2 - KB1END IF*DO 40 J = J1, J2, KB1** create nonzero element a(j-1,j+ku) above the band* and store it in WORK(n+1:2*n)*WORK( J+KUN ) = WORK( J )*AB( 1, J+KUN )AB( 1, J+KUN ) = WORK( MN+J )*AB( 1, J+KUN )40 CONTINUE** generate plane rotations to annihilate nonzero elements* which have been generated above the band*IF( NR.GT.0 )$ CALL DLARGV( NR, AB( 1, J1+KUN-1 ), INCA,$ WORK( J1+KUN ), KB1, WORK( MN+J1+KUN ),$ KB1 )** apply plane rotations from the right*DO 50 L = 1, KBIF( J2+L-1.GT.M ) THENNRT = NR - 1ELSENRT = NREND IFIF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L+1, J1+KUN-1 ), INCA,$ AB( L, J1+KUN ), INCA,$ WORK( MN+J1+KUN ), WORK( J1+KUN ),$ KB1 )50 CONTINUE*IF( ML.EQ.ML0 .AND. MU.GT.MU0 ) THENIF( MU.LE.N-I+1 ) THEN** generate plane rotation to annihilate a(i,i+mu-1)* within the band, and apply rotation from the right*CALL DLARTG( AB( KU-MU+3, I+MU-2 ),$ AB( KU-MU+2, I+MU-1 ),$ WORK( MN+I+MU-1 ), WORK( I+MU-1 ),$ RA )AB( KU-MU+3, I+MU-2 ) = RACALL DROT( MIN( KL+MU-2, M-I ),$ AB( KU-MU+4, I+MU-2 ), 1,$ AB( KU-MU+3, I+MU-1 ), 1,$ WORK( MN+I+MU-1 ), WORK( I+MU-1 ) )END IFNR = NR + 1J1 = J1 - KB1END IF*IF( WANTPT ) THEN** accumulate product of plane rotations in P'*DO 60 J = J1, J2, KB1CALL DROT( N, PT( J+KUN-1, 1 ), LDPT,$ PT( J+KUN, 1 ), LDPT, WORK( MN+J+KUN ),$ WORK( J+KUN ) )60 CONTINUEEND IF*IF( J2+KB.GT.M ) THEN** adjust J2 to keep within the bounds of the matrix*NR = NR - 1J2 = J2 - KB1END IF*DO 70 J = J1, J2, KB1** create nonzero element a(j+kl+ku,j+ku-1) below the* band and store it in WORK(1:n)*WORK( J+KB ) = WORK( J+KUN )*AB( KLU1, J+KUN )AB( KLU1, J+KUN ) = WORK( MN+J+KUN )*AB( KLU1, J+KUN )70 CONTINUE*IF( ML.GT.ML0 ) THENML = ML - 1ELSEMU = MU - 1END IF80 CONTINUE90 CONTINUEEND IF*IF( KU.EQ.0 .AND. KL.GT.0 ) THEN** A has been reduced to lower bidiagonal form** Transform lower bidiagonal form to upper bidiagonal by applying* plane rotations from the left, storing diagonal elements in D* and off-diagonal elements in E*DO 100 I = 1, MIN( M-1, N )CALL DLARTG( AB( 1, I ), AB( 2, I ), RC, RS, RA )D( I ) = RAIF( I.LT.N ) THENE( I ) = RS*AB( 1, I+1 )AB( 1, I+1 ) = RC*AB( 1, I+1 )END IFIF( WANTQ )$ CALL DROT( M, Q( 1, I ), 1, Q( 1, I+1 ), 1, RC, RS )IF( WANTC )$ CALL DROT( NCC, C( I, 1 ), LDC, C( I+1, 1 ), LDC, RC,$ RS )100 CONTINUEIF( M.LE.N )$ D( M ) = AB( 1, M )ELSE IF( KU.GT.0 ) THEN** A has been reduced to upper bidiagonal form*IF( M.LT.N ) THEN** Annihilate a(m,m+1) by applying plane rotations from the* right, storing diagonal elements in D and off-diagonal* elements in E*RB = AB( KU, M+1 )DO 110 I = M, 1, -1CALL DLARTG( AB( KU+1, I ), RB, RC, RS, RA )D( I ) = RAIF( I.GT.1 ) THENRB = -RS*AB( KU, I )E( I-1 ) = RC*AB( KU, I )END IFIF( WANTPT )$ CALL DROT( N, PT( I, 1 ), LDPT, PT( M+1, 1 ), LDPT,$ RC, RS )110 CONTINUEELSE** Copy off-diagonal elements to E and diagonal elements to D*DO 120 I = 1, MINMN - 1E( I ) = AB( KU, I+1 )120 CONTINUEDO 130 I = 1, MINMND( I ) = AB( KU+1, I )130 CONTINUEEND IFELSE** A is diagonal. Set elements of E to zero and copy diagonal* elements to D.*DO 140 I = 1, MINMN - 1E( I ) = ZERO140 CONTINUEDO 150 I = 1, MINMND( I ) = AB( 1, I )150 CONTINUEEND IFRETURN** End of DGBBRD*ENDSUBROUTINE DGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,$ WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER NORMINTEGER INFO, KL, KU, LDAB, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** Purpose* =======** DGBCON estimates the reciprocal of the condition number of a real* general band matrix A, in either the 1-norm or the infinity-norm,* using the LU factorization computed by DGBTRF.** An estimate is obtained for norm(inv(A)), and the reciprocal of the* condition number is computed as* RCOND = 1 / ( norm(A) * norm(inv(A)) ).** Arguments* =========** NORM (input) CHARACTER*1* Specifies whether the 1-norm condition number or the* infinity-norm condition number is required:* = '1' or 'O': 1-norm;* = 'I': Infinity-norm.** N (input) INTEGER* The order of the matrix A. N >= 0.** KL (input) INTEGER* The number of subdiagonals within the band of A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals within the band of A. KU >= 0.** AB (input) DOUBLE PRECISION array, dimension (LDAB,N)* Details of the LU factorization of the band matrix A, as* computed by DGBTRF. U is stored as an upper triangular band* matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and* the multipliers used during the factorization are stored in* rows KL+KU+2 to 2*KL+KU+1.** LDAB (input) INTEGER* The leading dimension of the array AB. LDAB >= 2*KL+KU+1.** IPIV (input) INTEGER array, dimension (N)* The pivot indices; for 1 <= i <= N, row i of the matrix was* interchanged with row IPIV(i).** ANORM (input) DOUBLE PRECISION* If NORM = '1' or 'O', the 1-norm of the original matrix A.* If NORM = 'I', the infinity-norm of the original matrix A.** RCOND (output) DOUBLE PRECISION* The reciprocal of the condition number of the matrix A,* computed as RCOND = 1/(norm(A) * norm(inv(A))).** WORK (workspace) DOUBLE PRECISION array, dimension (3*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LNOTI, ONENRMCHARACTER NORMININTEGER IX, J, JP, KASE, KASE1, KD, LMDOUBLE PRECISION AINVNM, SCALE, SMLNUM, T* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DLACON, DLATBS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.2*KL+KU+1 ) THENINFO = -6ELSE IF( ANORM.LT.ZERO ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the norm of inv(A).*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKD = KL + KU + 1LNOTI = KL.GT.0KASE = 010 CONTINUECALL DLACON( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(L).*IF( LNOTI ) THENDO 20 J = 1, N - 1LM = MIN( KL, N-J )JP = IPIV( J )T = WORK( JP )IF( JP.NE.J ) THENWORK( JP ) = WORK( J )WORK( J ) = TEND IFCALL DAXPY( LM, -T, AB( KD+1, J ), 1, WORK( J+1 ), 1 )20 CONTINUEEND IF** Multiply by inv(U).*CALL DLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),$ INFO )ELSE** Multiply by inv(U').*CALL DLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,$ KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),$ INFO )** Multiply by inv(L').*IF( LNOTI ) THENDO 30 J = N - 1, 1, -1LM = MIN( KL, N-J )WORK( J ) = WORK( J ) - DDOT( LM, AB( KD+1, J ), 1,$ WORK( J+1 ), 1 )JP = IPIV( J )IF( JP.NE.J ) THENT = WORK( JP )WORK( JP ) = WORK( J )WORK( J ) = TEND IF30 CONTINUEEND IFEND IF** Divide X by 1/SCALE if doing so will not cause overflow.*NORMIN = 'Y'IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 40CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*40 CONTINUERETURN** End of DGBCON*ENDSUBROUTINE DGBEQU( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,$ AMAX, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* March 31, 1993** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..** Purpose* =======** DGBEQU computes row and column scalings intended to equilibrate an* M-by-N band matrix A and reduce its condition number. R returns the* row scale factors and C the column scale factors, chosen to try to* make the largest element in each row and column of the matrix B with* elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.** R(i) and C(j) are restricted to be between SMLNUM = smallest safe* number and BIGNUM = largest safe number. Use of these scaling* factors is not guaranteed to reduce the condition number of A but* works well in practice.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** KL (input) INTEGER* The number of subdiagonals within the band of A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals within the band of A. KU >= 0.** AB (input) DOUBLE PRECISION array, dimension (LDAB,N)* The band matrix A, stored in rows 1 to KL+KU+1. The j-th* column of A is stored in the j-th column of the array AB as* follows:* AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl).** LDAB (input) INTEGER* The leading dimension of the array AB. LDAB >= KL+KU+1.** R (output) DOUBLE PRECISION array, dimension (M)* If INFO = 0, or INFO > M, R contains the row scale factors* for A.** C (output) DOUBLE PRECISION array, dimension (N)* If INFO = 0, C contains the column scale factors for A.** ROWCND (output) DOUBLE PRECISION* If INFO = 0 or INFO > M, ROWCND contains the ratio of the* smallest R(i) to the largest R(i). If ROWCND >= 0.1 and* AMAX is neither too large nor too small, it is not worth* scaling by R.** COLCND (output) DOUBLE PRECISION* If INFO = 0, COLCND contains the ratio of the smallest* C(i) to the largest C(i). If COLCND >= 0.1, it is not* worth scaling by C.** AMAX (output) DOUBLE PRECISION* Absolute value of largest matrix element. If AMAX is very* close to overflow or very close to underflow, the matrix* should be scaled.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, and i is* <= M: the i-th row of A is exactly zero* > M: the (i-M)-th column of A is exactly zero** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, KDDOUBLE PRECISION BIGNUM, RCMAX, RCMIN, SMLNUM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KU+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBEQU', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENROWCND = ONECOLCND = ONEAMAX = ZERORETURNEND IF** Get machine constants.*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUM** Compute row scale factors.*DO 10 I = 1, MR( I ) = ZERO10 CONTINUE** Find the maximum element in each row.*KD = KU + 1DO 30 J = 1, NDO 20 I = MAX( J-KU, 1 ), MIN( J+KL, M )R( I ) = MAX( R( I ), ABS( AB( KD+I-J, J ) ) )20 CONTINUE30 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 40 I = 1, MRCMAX = MAX( RCMAX, R( I ) )RCMIN = MIN( RCMIN, R( I ) )40 CONTINUEAMAX = RCMAX*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 50 I = 1, MIF( R( I ).EQ.ZERO ) THENINFO = IRETURNEND IF50 CONTINUEELSE** Invert the scale factors.*DO 60 I = 1, MR( I ) = ONE / MIN( MAX( R( I ), SMLNUM ), BIGNUM )60 CONTINUE** Compute ROWCND = min(R(I)) / max(R(I))*ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF** Compute column scale factors*DO 70 J = 1, NC( J ) = ZERO70 CONTINUE** Find the maximum element in each column,* assuming the row scaling computed above.*KD = KU + 1DO 90 J = 1, NDO 80 I = MAX( J-KU, 1 ), MIN( J+KL, M )C( J ) = MAX( C( J ), ABS( AB( KD+I-J, J ) )*R( I ) )80 CONTINUE90 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 100 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )100 CONTINUE*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 110 J = 1, NIF( C( J ).EQ.ZERO ) THENINFO = M + JRETURNEND IF110 CONTINUEELSE** Invert the scale factors.*DO 120 J = 1, NC( J ) = ONE / MIN( MAX( C( J ), SMLNUM ), BIGNUM )120 CONTINUE** Compute COLCND = min(C(J)) / max(C(J))*COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF*RETURN** End of DGBEQU*ENDSUBROUTINE DGBRFS( TRANS, N, KL, KU, NRHS, AB, LDAB, AFB, LDAFB,$ IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, KL, KU, LDAB, LDAFB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** Purpose* =======** DGBRFS improves the computed solution to a system of linear* equations when the coefficient matrix is banded, and provides* error bounds and backward error estimates for the solution.** Arguments* =========** TRANS (input) CHARACTER*1* Specifies the form of the system of equations:* = 'N': A * X = B (No transpose)* = 'T': A**T * X = B (Transpose)* = 'C': A**H * X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A. N >= 0.** KL (input) INTEGER* The number of subdiagonals within the band of A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals within the band of A. KU >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrices B and X. NRHS >= 0.** AB (input) DOUBLE PRECISION array, dimension (LDAB,N)* The original band matrix A, stored in rows 1 to KL+KU+1.* The j-th column of A is stored in the j-th column of the* array AB as follows:* AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(n,j+kl).** LDAB (input) INTEGER* The leading dimension of the array AB. LDAB >= KL+KU+1.** AFB (input) DOUBLE PRECISION array, dimension (LDAFB,N)* Details of the LU factorization of the band matrix A, as* computed by DGBTRF. U is stored as an upper triangular band* matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and* the multipliers used during the factorization are stored in* rows KL+KU+2 to 2*KL+KU+1.** LDAFB (input) INTEGER* The leading dimension of the array AFB. LDAFB >= 2*KL*KU+1.** IPIV (input) INTEGER array, dimension (N)* The pivot indices from DGBTRF; for 1<=i<=N, row i of the* matrix was interchanged with row IPIV(i).** B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)* The right hand side matrix B.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** X (input/output) DOUBLE PRECISION array, dimension (LDX,NRHS)* On entry, the solution matrix X, as computed by DGBTRS.* On exit, the improved solution matrix X.** LDX (input) INTEGER* The leading dimension of the array X. LDX >= max(1,N).** FERR (output) DOUBLE PRECISION array, dimension (NRHS)* The estimated forward error bound for each solution vector* X(j) (the j-th column of the solution matrix X).* If XTRUE is the true solution corresponding to X(j), FERR(j)* is an estimated upper bound for the magnitude of the largest* element in (X(j) - XTRUE) divided by the magnitude of the* largest element in X(j). The estimate is as reliable as* the estimate for RCOND, and is almost always a slight* overestimate of the true error.** BERR (output) DOUBLE PRECISION array, dimension (NRHS)* The componentwise relative backward error of each solution* vector X(j) (i.e., the smallest relative change in* any element of A or B that makes X(j) an exact solution).** WORK (workspace) DOUBLE PRECISION array, dimension (3*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Internal Parameters* ===================** ITMAX is the maximum number of steps of iterative refinement.** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANCHARACTER TRANSTINTEGER COUNT, I, J, K, KASE, KK, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGBMV, DGBTRS, DLACON, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.KL+KU+1 ) THENINFO = -7ELSE IF( LDAFB.LT.2*KL+KU+1 ) THENINFO = -9ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -12ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = MIN( KL+KU+2, N+1 )EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - op(A) * X,* where op(A) = A, A**T, or A**H, depending on TRANS.*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DGBMV( TRANS, N, N, KL, KU, -ONE, AB, LDAB, X( 1, J ), 1,$ ONE, WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(op(A))*abs(X) + abs(B).*IF( NOTRAN ) THENDO 50 K = 1, NKK = KU + 1 - KXK = ABS( X( K, J ) )DO 40 I = MAX( 1, K-KU ), MIN( N, K+KL )WORK( I ) = WORK( I ) + ABS( AB( KK+I, K ) )*XK40 CONTINUE50 CONTINUEELSEDO 70 K = 1, NS = ZEROKK = KU + 1 - KDO 60 I = MAX( 1, K-KU ), MIN( N, K+KL )S = S + ABS( AB( KK+I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DGBTRS( TRANS, N, KL, KU, 1, AFB, LDAFB, IPIV,$ WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACON to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACON( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DGBTRS( TRANST, N, KL, KU, 1, AFB, LDAFB, IPIV,$ WORK( N+1 ), N, INFO )DO 110 I = 1, NWORK( N+I ) = WORK( N+I )*WORK( I )110 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( N+I )*WORK( I )120 CONTINUECALL DGBTRS( TRANS, N, KL, KU, 1, AFB, LDAFB, IPIV,$ WORK( N+1 ), N, INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DGBRFS*ENDSUBROUTINE DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * )* ..** Purpose* =======** DGBTF2 computes an LU factorization of a real m-by-n band matrix A* using partial pivoting with row interchanges.** This is the unblocked version of the algorithm, calling Level 2 BLAS.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** KL (input) INTEGER* The number of subdiagonals within the band of A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals within the band of A. KU >= 0.** AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)* On entry, the matrix A in band storage, in rows KL+1 to* 2*KL+KU+1; rows 1 to KL of the array need not be set.* The j-th column of A is stored in the j-th column of the* array AB as follows:* AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)** On exit, details of the factorization: U is stored as an* upper triangular band matrix with KL+KU superdiagonals in* rows 1 to KL+KU+1, and the multipliers used during the* factorization are stored in rows KL+KU+2 to 2*KL+KU+1.* See below for further details.** LDAB (input) INTEGER* The leading dimension of the array AB. LDAB >= 2*KL+KU+1.** IPIV (output) INTEGER array, dimension (min(M,N))* The pivot indices; for 1 <= i <= min(M,N), row i of the* matrix was interchanged with row IPIV(i).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = +i, U(i,i) is exactly zero. The factorization* has been completed, but the factor U is exactly* singular, and division by zero will occur if it is used* to solve a system of equations.** Further Details* ===============** The band storage scheme is illustrated by the following example, when* M = N = 6, KL = 2, KU = 1:** On entry: On exit:** * * * + + + * * * u14 u25 u36* * * + + + + * * u13 u24 u35 u46* * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56* a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66* a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 ** a31 a42 a53 a64 * * m31 m42 m53 m64 * *** Array elements marked * are not used by the routine; elements marked* + need not be set on entry, but are required by the routine to store* elements of U, because of fill-in resulting from the row* interchanges.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, JP, JU, KM, KV* ..* .. External Functions ..INTEGER IDAMAXEXTERNAL IDAMAX* ..* .. External Subroutines ..EXTERNAL DGER, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** KV is the number of superdiagonals in the factor U, allowing for* fill-in.*KV = KU + KL** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KV+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBTF2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Gaussian elimination with partial pivoting** Set fill-in elements in columns KU+2 to KV to zero.*DO 20 J = KU + 2, MIN( KV, N )DO 10 I = KV - J + 2, KLAB( I, J ) = ZERO10 CONTINUE20 CONTINUE** JU is the index of the last column affected by the current stage* of the factorization.*JU = 1*DO 40 J = 1, MIN( M, N )** Set fill-in elements in column J+KV to zero.*IF( J+KV.LE.N ) THENDO 30 I = 1, KLAB( I, J+KV ) = ZERO30 CONTINUEEND IF** Find pivot and test for singularity. KM is the number of* subdiagonal elements in the current column.*KM = MIN( KL, M-J )JP = IDAMAX( KM+1, AB( KV+1, J ), 1 )IPIV( J ) = JP + J - 1IF( AB( KV+JP, J ).NE.ZERO ) THENJU = MAX( JU, MIN( J+KU+JP-1, N ) )** Apply interchange to columns J to JU.*IF( JP.NE.1 )$ CALL DSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1,$ AB( KV+1, J ), LDAB-1 )*IF( KM.GT.0 ) THEN** Compute multipliers.*CALL DSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 )** Update trailing submatrix within the band.*IF( JU.GT.J )$ CALL DGER( KM, JU-J, -ONE, AB( KV+2, J ), 1,$ AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ),$ LDAB-1 )END IFELSE** If pivot is zero, set INFO to the index of the pivot* unless a zero pivot has already been found.*IF( INFO.EQ.0 )$ INFO = JEND IF40 CONTINUERETURN** End of DGBTF2*ENDSUBROUTINE DGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * )* ..** Purpose* =======** DGBTRF computes an LU factorization of a real m-by-n band matrix A* using partial pivoting with row interchanges.** This is the blocked version of the algorithm, calling Level 3 BLAS.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** KL (input) INTEGER* The number of subdiagonals within the band of A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals within the band of A. KU >= 0.** AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)* On entry, the matrix A in band storage, in rows KL+1 to* 2*KL+KU+1; rows 1 to KL of the array need not be set.* The j-th column of A is stored in the j-th column of the* array AB as follows:* AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)** On exit, details of the factorization: U is stored as an* upper triangular band matrix with KL+KU superdiagonals in* rows 1 to KL+KU+1, and the multipliers used during the* factorization are stored in rows KL+KU+2 to 2*KL+KU+1.* See below for further details.** LDAB (input) INTEGER* The leading dimension of the array AB. LDAB >= 2*KL+KU+1.** IPIV (output) INTEGER array, dimension (min(M,N))* The pivot indices; for 1 <= i <= min(M,N), row i of the* matrix was interchanged with row IPIV(i).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = +i, U(i,i) is exactly zero. The factorization* has been completed, but the factor U is exactly* singular, and division by zero will occur if it is used* to solve a system of equations.** Further Details* ===============** The band storage scheme is illustrated by the following example, when* M = N = 6, KL = 2, KU = 1:** On entry: On exit:** * * * + + + * * * u14 u25 u36* * * + + + + * * u13 u24 u35 u46* * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56* a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66* a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 ** a31 a42 a53 a64 * * m31 m42 m53 m64 * *** Array elements marked * are not used by the routine; elements marked* + need not be set on entry, but are required by the routine to store* elements of U because of fill-in resulting from the row interchanges.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )INTEGER NBMAX, LDWORKPARAMETER ( NBMAX = 64, LDWORK = NBMAX+1 )* ..* .. Local Scalars ..INTEGER I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP,$ JU, K2, KM, KV, NB, NWDOUBLE PRECISION TEMP* ..* .. Local Arrays ..DOUBLE PRECISION WORK13( LDWORK, NBMAX ),$ WORK31( LDWORK, NBMAX )* ..* .. External Functions ..INTEGER IDAMAX, ILAENVEXTERNAL IDAMAX, ILAENV* ..* .. External Subroutines ..EXTERNAL DCOPY, DGBTF2, DGEMM, DGER, DLASWP, DSCAL,$ DSWAP, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** KV is the number of superdiagonals in the factor U, allowing for* fill-in*KV = KU + KL** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KV+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBTRF', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Determine the block size for this environment*NB = ILAENV( 1, 'DGBTRF', ' ', M, N, KL, KU )** The block size must not exceed the limit set by the size of the* local arrays WORK13 and WORK31.*NB = MIN( NB, NBMAX )*IF( NB.LE.1 .OR. NB.GT.KL ) THEN** Use unblocked code*CALL DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )ELSE** Use blocked code** Zero the superdiagonal elements of the work array WORK13*DO 20 J = 1, NBDO 10 I = 1, J - 1WORK13( I, J ) = ZERO10 CONTINUE20 CONTINUE** Zero the subdiagonal elements of the work array WORK31*DO 40 J = 1, NBDO 30 I = J + 1, NBWORK31( I, J ) = ZERO30 CONTINUE40 CONTINUE** Gaussian elimination with partial pivoting** Set fill-in elements in columns KU+2 to KV to zero*DO 60 J = KU + 2, MIN( KV, N )DO 50 I = KV - J + 2, KLAB( I, J ) = ZERO50 CONTINUE60 CONTINUE** JU is the index of the last column affected by the current* stage of the factorization*JU = 1*DO 180 J = 1, MIN( M, N ), NBJB = MIN( NB, MIN( M, N )-J+1 )** The active part of the matrix is partitioned** A11 A12 A13* A21 A22 A23* A31 A32 A33** Here A11, A21 and A31 denote the current block of JB columns* which is about to be factorized. The number of rows in the* partitioning are JB, I2, I3 respectively, and the numbers* of columns are JB, J2, J3. The superdiagonal elements of A13* and the subdiagonal elements of A31 lie outside the band.*I2 = MIN( KL-JB, M-J-JB+1 )I3 = MIN( JB, M-J-KL+1 )** J2 and J3 are computed after JU has been updated.** Factorize the current block of JB columns*DO 80 JJ = J, J + JB - 1** Set fill-in elements in column JJ+KV to zero*IF( JJ+KV.LE.N ) THENDO 70 I = 1, KLAB( I, JJ+KV ) = ZERO70 CONTINUEEND IF** Find pivot and test for singularity. KM is the number of* subdiagonal elements in the current column.*KM = MIN( KL, M-JJ )JP = IDAMAX( KM+1, AB( KV+1, JJ ), 1 )IPIV( JJ ) = JP + JJ - JIF( AB( KV+JP, JJ ).NE.ZERO ) THENJU = MAX( JU, MIN( JJ+KU+JP-1, N ) )IF( JP.NE.1 ) THEN** Apply interchange to columns J to J+JB-1*IF( JP+JJ-1.LT.J+KL ) THEN*CALL DSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,$ AB( KV+JP+JJ-J, J ), LDAB-1 )ELSE** The interchange affects columns J to JJ-1 of A31* which are stored in the work array WORK31*CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,$ WORK31( JP+JJ-J-KL, 1 ), LDWORK )CALL DSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1,$ AB( KV+JP, JJ ), LDAB-1 )END IFEND IF** Compute multipliers*CALL DSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ),$ 1 )** Update trailing submatrix within the band and within* the current block. JM is the index of the last column* which needs to be updated.*JM = MIN( JU, J+JB-1 )IF( JM.GT.JJ )$ CALL DGER( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1,$ AB( KV, JJ+1 ), LDAB-1,$ AB( KV+1, JJ+1 ), LDAB-1 )ELSE** If pivot is zero, set INFO to the index of the pivot* unless a zero pivot has already been found.*IF( INFO.EQ.0 )$ INFO = JJEND IF** Copy current column of A31 into the work array WORK31*NW = MIN( JJ-J+1, I3 )IF( NW.GT.0 )$ CALL DCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1,$ WORK31( 1, JJ-J+1 ), 1 )80 CONTINUEIF( J+JB.LE.N ) THEN** Apply the row interchanges to the other blocks.*J2 = MIN( JU-J+1, KV ) - JBJ3 = MAX( 0, JU-J-KV+1 )** Use DLASWP to apply the row interchanges to A12, A22, and* A32.*CALL DLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB,$ IPIV( J ), 1 )** Adjust the pivot indices.*DO 90 I = J, J + JB - 1IPIV( I ) = IPIV( I ) + J - 190 CONTINUE** Apply the row interchanges to A13, A23, and A33* columnwise.*K2 = J - 1 + JB + J2DO 110 I = 1, J3JJ = K2 + IDO 100 II = J + I - 1, J + JB - 1IP = IPIV( II )IF( IP.NE.II ) THENTEMP = AB( KV+1+II-JJ, JJ )AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ )AB( KV+1+IP-JJ, JJ ) = TEMPEND IF100 CONTINUE110 CONTINUE** Update the relevant part of the trailing submatrix*IF( J2.GT.0 ) THEN** Update A12*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit',$ JB, J2, ONE, AB( KV+1, J ), LDAB-1,$ AB( KV+1-JB, J+JB ), LDAB-1 )*IF( I2.GT.0 ) THEN** Update A22*CALL DGEMM( 'No transpose', 'No transpose', I2, J2,$ JB, -ONE, AB( KV+1+JB, J ), LDAB-1,$ AB( KV+1-JB, J+JB ), LDAB-1, ONE,$ AB( KV+1, J+JB ), LDAB-1 )END IF*IF( I3.GT.0 ) THEN** Update A32*CALL DGEMM( 'No transpose', 'No transpose', I3, J2,$ JB, -ONE, WORK31, LDWORK,$ AB( KV+1-JB, J+JB ), LDAB-1, ONE,$ AB( KV+KL+1-JB, J+JB ), LDAB-1 )END IFEND IF*IF( J3.GT.0 ) THEN** Copy the lower triangle of A13 into the work array* WORK13*DO 130 JJ = 1, J3DO 120 II = JJ, JBWORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 )120 CONTINUE130 CONTINUE** Update A13 in the work array*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit',$ JB, J3, ONE, AB( KV+1, J ), LDAB-1,$ WORK13, LDWORK )*IF( I2.GT.0 ) THEN** Update A23*CALL DGEMM( 'No transpose', 'No transpose', I2, J3,$ JB, -ONE, AB( KV+1+JB, J ), LDAB-1,$ WORK13, LDWORK, ONE, AB( 1+JB, J+KV ),$ LDAB-1 )END IF*IF( I3.GT.0 ) THEN** Update A33*CALL DGEMM( 'No transpose', 'No transpose', I3, J3,$ JB, -ONE, WORK31, LDWORK, WORK13,$ LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 )END IF** Copy the lower triangle of A13 back into place*DO 150 JJ = 1, J3DO 140 II = JJ, JBAB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ )140 CONTINUE150 CONTINUEEND IFELSE** Adjust the pivot indices.*DO 160 I = J, J + JB - 1IPIV( I ) = IPIV( I ) + J - 1160 CONTINUEEND IF** Partially undo the interchanges in the current block to* restore the upper triangular form of A31 and copy the upper* triangle of A31 back into place*DO 170 JJ = J + JB - 1, J, -1JP = IPIV( JJ ) - JJ + 1IF( JP.NE.1 ) THEN** Apply interchange to columns J to JJ-1*IF( JP+JJ-1.LT.J+KL ) THEN** The interchange does not affect A31*CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,$ AB( KV+JP+JJ-J, J ), LDAB-1 )ELSE** The interchange does affect A31*CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,$ WORK31( JP+JJ-J-KL, 1 ), LDWORK )END IFEND IF** Copy the current column of A31 back into place*NW = MIN( I3, JJ-J+1 )IF( NW.GT.0 )$ CALL DCOPY( NW, WORK31( 1, JJ-J+1 ), 1,$ AB( KV+KL+1-JJ+J, JJ ), 1 )170 CONTINUE180 CONTINUEEND IF*RETURN** End of DGBTRF*ENDSUBROUTINE DGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* March 31, 1993** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, KL, KU, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..** Purpose* =======** DGBTRS solves a system of linear equations* A * X = B or A' * X = B* with a general band matrix A using the LU factorization computed* by DGBTRF.** Arguments* =========** TRANS (input) CHARACTER*1* Specifies the form of the system of equations.* = 'N': A * X = B (No transpose)* = 'T': A'* X = B (Transpose)* = 'C': A'* X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A. N >= 0.** KL (input) INTEGER* The number of subdiagonals within the band of A. KL >= 0.** KU (input) INTEGER* The number of superdiagonals within the band of A. KU >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrix B. NRHS >= 0.** AB (input) DOUBLE PRECISION array, dimension (LDAB,N)* Details of the LU factorization of the band matrix A, as* computed by DGBTRF. U is stored as an upper triangular band* matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and* the multipliers used during the factorization are stored in* rows KL+KU+2 to 2*KL+KU+1.** LDAB (input) INTEGER* The leading dimension of the array AB. LDAB >= 2*KL+KU+1.** IPIV (input) INTEGER array, dimension (N)* The pivot indices; for 1 <= i <= N, row i of the matrix was* interchanged with row IPIV(i).** B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)* On entry, the right hand side matrix B.* On exit, the solution matrix X.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LNOTI, NOTRANINTEGER I, J, KD, L, LM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER, DSWAP, DTBSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*KD = KU + KL + 1LNOTI = KL.GT.0*IF( NOTRAN ) THEN** Solve A*X = B.** Solve L*X = B, overwriting B with X.** L is represented as a product of permutations and unit lower* triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1),* where each transformation L(i) is a rank-one modification of* the identity matrix.*IF( LNOTI ) THENDO 10 J = 1, N - 1LM = MIN( KL, N-J )L = IPIV( J )IF( L.NE.J )$ CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )CALL DGER( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ),$ LDB, B( J+1, 1 ), LDB )10 CONTINUEEND IF*DO 20 I = 1, NRHS** Solve U*X = B, overwriting B with X.*CALL DTBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU,$ AB, LDAB, B( 1, I ), 1 )20 CONTINUE*ELSE** Solve A'*X = B.*DO 30 I = 1, NRHS** Solve U'*X = B, overwriting B with X.*CALL DTBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB,$ LDAB, B( 1, I ), 1 )30 CONTINUE** Solve L'*X = B, overwriting B with X.*IF( LNOTI ) THENDO 40 J = N - 1, 1, -1LM = MIN( KL, N-J )CALL DGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ),$ LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB )L = IPIV( J )IF( L.NE.J )$ CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )40 CONTINUEEND IFEND IFRETURN** End of DGBTRS*ENDSUBROUTINE DGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER JOB, SIDEINTEGER IHI, ILO, INFO, LDV, M, N* ..* .. Array Arguments ..DOUBLE PRECISION SCALE( * ), V( LDV, * )* ..** Purpose* =======** DGEBAK forms the right or left eigenvectors of a real general matrix* by backward transformation on the computed eigenvectors of the* balanced matrix output by DGEBAL.** Arguments* =========** JOB (input) CHARACTER*1* Specifies the type of backward transformation required:* = 'N', do nothing, return immediately;* = 'P', do backward transformation for permutation only;* = 'S', do backward transformation for scaling only;* = 'B', do backward transformations for both permutation and* scaling.* JOB must be the same as the argument JOB supplied to DGEBAL.** SIDE (input) CHARACTER*1* = 'R': V contains right eigenvectors;* = 'L': V contains left eigenvectors.** N (input) INTEGER* The number of rows of the matrix V. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* The integers ILO and IHI determined by DGEBAL.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** SCALE (input) DOUBLE PRECISION array, dimension (N)* Details of the permutation and scaling factors, as returned* by DGEBAL.** M (input) INTEGER* The number of columns of the matrix V. M >= 0.** V (input/output) DOUBLE PRECISION array, dimension (LDV,M)* On entry, the matrix of right or left eigenvectors to be* transformed, as returned by DHSEIN or DTREVC.* On exit, V is overwritten by the transformed eigenvectors.** LDV (input) INTEGER* The leading dimension of the array V. LDV >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LEFTV, RIGHTVINTEGER I, II, KDOUBLE PRECISION S* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Decode and Test the input parameters*RIGHTV = LSAME( SIDE, 'R' )LEFTV = LSAME( SIDE, 'L' )*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -4ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -5ELSE IF( M.LT.0 ) THENINFO = -7ELSE IF( LDV.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEBAK', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( M.EQ.0 )$ RETURNIF( LSAME( JOB, 'N' ) )$ RETURN*IF( ILO.EQ.IHI )$ GO TO 30** Backward balance*IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN*IF( RIGHTV ) THENDO 10 I = ILO, IHIS = SCALE( I )CALL DSCAL( M, S, V( I, 1 ), LDV )10 CONTINUEEND IF*IF( LEFTV ) THENDO 20 I = ILO, IHIS = ONE / SCALE( I )CALL DSCAL( M, S, V( I, 1 ), LDV )20 CONTINUEEND IF*END IF** Backward permutation** For I = ILO-1 step -1 until 1,* IHI+1 step 1 until N do --*30 CONTINUEIF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THENIF( RIGHTV ) THENDO 40 II = 1, NI = IIIF( I.GE.ILO .AND. I.LE.IHI )$ GO TO 40IF( I.LT.ILO )$ I = ILO - IIK = SCALE( I )IF( K.EQ.I )$ GO TO 40CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )40 CONTINUEEND IF*IF( LEFTV ) THENDO 50 II = 1, NI = IIIF( I.GE.ILO .AND. I.LE.IHI )$ GO TO 50IF( I.LT.ILO )$ I = ILO - IIK = SCALE( I )IF( K.EQ.I )$ GO TO 50CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )50 CONTINUEEND IFEND IF*RETURN** End of DGEBAK*ENDSUBROUTINE DGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER JOBINTEGER IHI, ILO, INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), SCALE( * )* ..** Purpose* =======** DGEBAL balances a general real matrix A. This involves, first,* permuting A by a similarity transformation to isolate eigenvalues* in the first 1 to ILO-1 and last IHI+1 to N elements on the* diagonal; and second, applying a diagonal similarity transformation* to rows and columns ILO to IHI to make the rows and columns as* close in norm as possible. Both steps are optional.** Balancing may reduce the 1-norm of the matrix, and improve the* accuracy of the computed eigenvalues and/or eigenvectors.** Arguments* =========** JOB (input) CHARACTER*1* Specifies the operations to be performed on A:* = 'N': none: simply set ILO = 1, IHI = N, SCALE(I) = 1.0* for i = 1,...,N;* = 'P': permute only;* = 'S': scale only;* = 'B': both permute and scale.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the input matrix A.* On exit, A is overwritten by the balanced matrix.* If JOB = 'N', A is not referenced.* See Further Details.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** ILO (output) INTEGER* IHI (output) INTEGER* ILO and IHI are set to integers such that on exit* A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.* If JOB = 'N' or 'S', ILO = 1 and IHI = N.** SCALE (output) DOUBLE PRECISION array, dimension (N)* Details of the permutations and scaling factors applied to* A. If P(j) is the index of the row and column interchanged* with row and column j and D(j) is the scaling factor* applied to row and column j, then* SCALE(j) = P(j) for j = 1,...,ILO-1* = D(j) for j = ILO,...,IHI* = P(j) for j = IHI+1,...,N.* The order in which the interchanges are made is N to IHI+1,* then 1 to ILO-1.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The permutations consist of row and column interchanges which put* the matrix in the form** ( T1 X Y )* P A P = ( 0 B Z )* ( 0 0 T2 )** where T1 and T2 are upper triangular matrices whose eigenvalues lie* along the diagonal. The column indices ILO and IHI mark the starting* and ending columns of the submatrix B. Balancing consists of applying* a diagonal similarity transformation inv(D) * B * D to make the* 1-norms of each row of B and its corresponding column nearly equal.* The output matrix is** ( T1 X*D Y )* ( 0 inv(D)*B*D inv(D)*Z ).* ( 0 0 T2 )** Information about the permutations P and the diagonal matrix D is* returned in the vector SCALE.** This subroutine is based on the EISPACK routine BALANC.** Modified by Tzu-Yi Chen, Computer Science Division, University of* California at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION SCLFACPARAMETER ( SCLFAC = 0.8D+1 )DOUBLE PRECISION FACTORPARAMETER ( FACTOR = 0.95D+0 )* ..* .. Local Scalars ..LOGICAL NOCONVINTEGER I, ICA, IEXC, IRA, J, K, L, MDOUBLE PRECISION C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,$ SFMIN2* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL LSAME, IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEBAL', -INFO )RETURNEND IF*K = 1L = N*IF( N.EQ.0 )$ GO TO 210*IF( LSAME( JOB, 'N' ) ) THENDO 10 I = 1, NSCALE( I ) = ONE10 CONTINUEGO TO 210END IF*IF( LSAME( JOB, 'S' ) )$ GO TO 120** Permutation to isolate eigenvalues if possible*GO TO 50** Row and column exchange.*20 CONTINUESCALE( M ) = JIF( J.EQ.M )$ GO TO 30*CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )CALL DSWAP( N-K+1, A( J, K ), LDA, A( M, K ), LDA )*30 CONTINUEGO TO ( 40, 80 )IEXC** Search for rows isolating an eigenvalue and push them down.*40 CONTINUEIF( L.EQ.1 )$ GO TO 210L = L - 1*50 CONTINUEDO 70 J = L, 1, -1*DO 60 I = 1, LIF( I.EQ.J )$ GO TO 60IF( A( J, I ).NE.ZERO )$ GO TO 7060 CONTINUE*M = LIEXC = 1GO TO 2070 CONTINUE*GO TO 90** Search for columns isolating an eigenvalue and push them left.*80 CONTINUEK = K + 1*90 CONTINUEDO 110 J = K, L*DO 100 I = K, LIF( I.EQ.J )$ GO TO 100IF( A( I, J ).NE.ZERO )$ GO TO 110100 CONTINUE*M = KIEXC = 2GO TO 20110 CONTINUE*120 CONTINUEDO 130 I = K, LSCALE( I ) = ONE130 CONTINUE*IF( LSAME( JOB, 'P' ) )$ GO TO 210** Balance the submatrix in rows K to L.** Iterative loop for norm reduction*SFMIN1 = DLAMCH( 'S' ) / DLAMCH( 'P' )SFMAX1 = ONE / SFMIN1SFMIN2 = SFMIN1*SCLFACSFMAX2 = ONE / SFMIN2140 CONTINUENOCONV = .FALSE.*DO 200 I = K, LC = ZEROR = ZERO*DO 150 J = K, LIF( J.EQ.I )$ GO TO 150C = C + ABS( A( J, I ) )R = R + ABS( A( I, J ) )150 CONTINUEICA = IDAMAX( L, A( 1, I ), 1 )CA = ABS( A( ICA, I ) )IRA = IDAMAX( N-K+1, A( I, K ), LDA )RA = ABS( A( I, IRA+K-1 ) )** Guard against zero C or R due to underflow.*IF( C.EQ.ZERO .OR. R.EQ.ZERO )$ GO TO 200G = R / SCLFACF = ONES = C + R160 CONTINUEIF( C.GE.G .OR. MAX( F, C, CA ).GE.SFMAX2 .OR.$ MIN( R, G, RA ).LE.SFMIN2 )GO TO 170F = F*SCLFACC = C*SCLFACCA = CA*SCLFACR = R / SCLFACG = G / SCLFACRA = RA / SCLFACGO TO 160*170 CONTINUEG = C / SCLFAC180 CONTINUEIF( G.LT.R .OR. MAX( R, RA ).GE.SFMAX2 .OR.$ MIN( F, C, G, CA ).LE.SFMIN2 )GO TO 190F = F / SCLFACC = C / SCLFACG = G / SCLFACCA = CA / SCLFACR = R*SCLFACRA = RA*SCLFACGO TO 180** Now balance.*190 CONTINUEIF( ( C+R ).GE.FACTOR*S )$ GO TO 200IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THENIF( F*SCALE( I ).LE.SFMIN1 )$ GO TO 200END IFIF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THENIF( SCALE( I ).GE.SFMAX1 / F )$ GO TO 200END IFG = ONE / FSCALE( I ) = SCALE( I )*FNOCONV = .TRUE.*CALL DSCAL( N-K+1, G, A( I, K ), LDA )CALL DSCAL( L, F, A( 1, I ), 1 )*200 CONTINUE*IF( NOCONV )$ GO TO 140*210 CONTINUEILO = KIHI = L*RETURN** End of DGEBAL*ENDSUBROUTINE DGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),$ TAUQ( * ), WORK( * )* ..** Purpose* =======** DGEBD2 reduces a real general m by n matrix A to upper or lower* bidiagonal form B by an orthogonal transformation: Q' * A * P = B.** If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.** Arguments* =========** M (input) INTEGER* The number of rows in the matrix A. M >= 0.** N (input) INTEGER* The number of columns in the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n general matrix to be reduced.* On exit,* if m >= n, the diagonal and the first superdiagonal are* overwritten with the upper bidiagonal matrix B; the* elements below the diagonal, with the array TAUQ, represent* the orthogonal matrix Q as a product of elementary* reflectors, and the elements above the first superdiagonal,* with the array TAUP, represent the orthogonal matrix P as* a product of elementary reflectors;* if m < n, the diagonal and the first subdiagonal are* overwritten with the lower bidiagonal matrix B; the* elements below the first subdiagonal, with the array TAUQ,* represent the orthogonal matrix Q as a product of* elementary reflectors, and the elements above the diagonal,* with the array TAUP, represent the orthogonal matrix P as* a product of elementary reflectors.* See Further Details.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** D (output) DOUBLE PRECISION array, dimension (min(M,N))* The diagonal elements of the bidiagonal matrix B:* D(i) = A(i,i).** E (output) DOUBLE PRECISION array, dimension (min(M,N)-1)* The off-diagonal elements of the bidiagonal matrix B:* if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;* if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.** TAUQ (output) DOUBLE PRECISION array dimension (min(M,N))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Q. See Further Details.** TAUP (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix P. See Further Details.** WORK (workspace) DOUBLE PRECISION array, dimension (max(M,N))** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The matrices Q and P are represented as products of elementary* reflectors:** If m >= n,** Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1)** Each H(i) and G(i) has the form:** H(i) = I - tauq * v * v' and G(i) = I - taup * u * u'** where tauq and taup are real scalars, and v and u are real vectors;* v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);* u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);* tauq is stored in TAUQ(i) and taup in TAUP(i).** If m < n,** Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m)** Each H(i) and G(i) has the form:** H(i) = I - tauq * v * v' and G(i) = I - taup * u * u'** where tauq and taup are real scalars, and v and u are real vectors;* v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);* u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);* tauq is stored in TAUQ(i) and taup in TAUP(i).** The contents of A on exit are illustrated by the following examples:** m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n):** ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 )* ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 )* ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 )* ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 )* ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 )* ( v1 v2 v3 v4 v5 )** where d and e denote diagonal and off-diagonal elements of B, vi* denotes an element of the vector defining H(i), and ui an element of* the vector defining G(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.LT.0 ) THENCALL XERBLA( 'DGEBD2', -INFO )RETURNEND IF*IF( M.GE.N ) THEN** Reduce to upper bidiagonal form*DO 10 I = 1, N** Generate elementary reflector H(i) to annihilate A(i+1:m,i)*CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ TAUQ( I ) )D( I ) = A( I, I )A( I, I ) = ONE** Apply H(i) to A(i:m,i+1:n) from the left*CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAUQ( I ),$ A( I, I+1 ), LDA, WORK )A( I, I ) = D( I )*IF( I.LT.N ) THEN** Generate elementary reflector G(i) to annihilate* A(i,i+2:n)*CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),$ LDA, TAUP( I ) )E( I ) = A( I, I+1 )A( I, I+1 ) = ONE** Apply G(i) to A(i+1:m,i+1:n) from the right*CALL DLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA,$ TAUP( I ), A( I+1, I+1 ), LDA, WORK )A( I, I+1 ) = E( I )ELSETAUP( I ) = ZEROEND IF10 CONTINUEELSE** Reduce to lower bidiagonal form*DO 20 I = 1, M** Generate elementary reflector G(i) to annihilate A(i,i+1:n)*CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,$ TAUP( I ) )D( I ) = A( I, I )A( I, I ) = ONE** Apply G(i) to A(i+1:m,i:n) from the right*CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAUP( I ),$ A( MIN( I+1, M ), I ), LDA, WORK )A( I, I ) = D( I )*IF( I.LT.M ) THEN** Generate elementary reflector H(i) to annihilate* A(i+2:m,i)*CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,$ TAUQ( I ) )E( I ) = A( I+1, I )A( I+1, I ) = ONE** Apply H(i) to A(i+1:m,i+1:n) from the left*CALL DLARF( 'Left', M-I, N-I, A( I+1, I ), 1, TAUQ( I ),$ A( I+1, I+1 ), LDA, WORK )A( I+1, I ) = E( I )ELSETAUQ( I ) = ZEROEND IF20 CONTINUEEND IFRETURN** End of DGEBD2*ENDSUBROUTINE DGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),$ TAUQ( * ), WORK( * )* ..** Purpose* =======** DGEBRD reduces a general real M-by-N matrix A to upper or lower* bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.** If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.** Arguments* =========** M (input) INTEGER* The number of rows in the matrix A. M >= 0.** N (input) INTEGER* The number of columns in the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N general matrix to be reduced.* On exit,* if m >= n, the diagonal and the first superdiagonal are* overwritten with the upper bidiagonal matrix B; the* elements below the diagonal, with the array TAUQ, represent* the orthogonal matrix Q as a product of elementary* reflectors, and the elements above the first superdiagonal,* with the array TAUP, represent the orthogonal matrix P as* a product of elementary reflectors;* if m < n, the diagonal and the first subdiagonal are* overwritten with the lower bidiagonal matrix B; the* elements below the first subdiagonal, with the array TAUQ,* represent the orthogonal matrix Q as a product of* elementary reflectors, and the elements above the diagonal,* with the array TAUP, represent the orthogonal matrix P as* a product of elementary reflectors.* See Further Details.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** D (output) DOUBLE PRECISION array, dimension (min(M,N))* The diagonal elements of the bidiagonal matrix B:* D(i) = A(i,i).** E (output) DOUBLE PRECISION array, dimension (min(M,N)-1)* The off-diagonal elements of the bidiagonal matrix B:* if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;* if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.** TAUQ (output) DOUBLE PRECISION array dimension (min(M,N))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Q. See Further Details.** TAUP (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix P. See Further Details.** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The length of the array WORK. LWORK >= max(1,M,N).* For optimum performance LWORK >= (M+N)*NB, where NB* is the optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The matrices Q and P are represented as products of elementary* reflectors:** If m >= n,** Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1)** Each H(i) and G(i) has the form:** H(i) = I - tauq * v * v' and G(i) = I - taup * u * u'** where tauq and taup are real scalars, and v and u are real vectors;* v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);* u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);* tauq is stored in TAUQ(i) and taup in TAUP(i).** If m < n,** Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m)** Each H(i) and G(i) has the form:** H(i) = I - tauq * v * v' and G(i) = I - taup * u * u'** where tauq and taup are real scalars, and v and u are real vectors;* v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);* u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);* tauq is stored in TAUQ(i) and taup in TAUP(i).** The contents of A on exit are illustrated by the following examples:** m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n):** ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 )* ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 )* ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 )* ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 )* ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 )* ( v1 v2 v3 v4 v5 )** where d and e denote diagonal and off-diagonal elements of B, vi* denotes an element of the vector defining H(i), and ui an element of* the vector defining G(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IINFO, J, LDWRKX, LDWRKY, LWKOPT, MINMN, NB,$ NBMIN, NXDOUBLE PRECISION WS* ..* .. External Subroutines ..EXTERNAL DGEBD2, DGEMM, DLABRD, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB = MAX( 1, ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 ) )LWKOPT = ( M+N )*NBWORK( 1 ) = DBLE( LWKOPT )LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, M, N ) .AND. .NOT.LQUERY ) THENINFO = -10END IFIF( INFO.LT.0 ) THENCALL XERBLA( 'DGEBRD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*MINMN = MIN( M, N )IF( MINMN.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*WS = MAX( M, N )LDWRKX = MLDWRKY = N*IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN** Set the crossover point NX.*NX = MAX( NB, ILAENV( 3, 'DGEBRD', ' ', M, N, -1, -1 ) )** Determine when to switch from blocked to unblocked code.*IF( NX.LT.MINMN ) THENWS = ( M+N )*NBIF( LWORK.LT.WS ) THEN** Not enough work space for the optimal NB, consider using* a smaller block size.*NBMIN = ILAENV( 2, 'DGEBRD', ' ', M, N, -1, -1 )IF( LWORK.GE.( M+N )*NBMIN ) THENNB = LWORK / ( M+N )ELSENB = 1NX = MINMNEND IFEND IFEND IFELSENX = MINMNEND IF*DO 30 I = 1, MINMN - NX, NB** Reduce rows and columns i:i+nb-1 to bidiagonal form and return* the matrices X and Y which are needed to update the unreduced* part of the matrix*CALL DLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ),$ TAUQ( I ), TAUP( I ), WORK, LDWRKX,$ WORK( LDWRKX*NB+1 ), LDWRKY )** Update the trailing submatrix A(i+nb:m,i+nb:n), using an update* of the form A := A - V*Y' - X*U'*CALL DGEMM( 'No transpose', 'Transpose', M-I-NB+1, N-I-NB+1,$ NB, -ONE, A( I+NB, I ), LDA,$ WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE,$ A( I+NB, I+NB ), LDA )CALL DGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1,$ NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA,$ ONE, A( I+NB, I+NB ), LDA )** Copy diagonal and off-diagonal elements of B back into A*IF( M.GE.N ) THENDO 10 J = I, I + NB - 1A( J, J ) = D( J )A( J, J+1 ) = E( J )10 CONTINUEELSEDO 20 J = I, I + NB - 1A( J, J ) = D( J )A( J+1, J ) = E( J )20 CONTINUEEND IF30 CONTINUE** Use unblocked code to reduce the remainder of the matrix*CALL DGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ),$ TAUQ( I ), TAUP( I ), WORK, IINFO )WORK( 1 ) = WSRETURN** End of DGEBRD*ENDSUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..CHARACTER NORMINTEGER INFO, LDA, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** Purpose* =======** DGECON estimates the reciprocal of the condition number of a general* real matrix A, in either the 1-norm or the infinity-norm, using* the LU factorization computed by DGETRF.** An estimate is obtained for norm(inv(A)), and the reciprocal of the* condition number is computed as* RCOND = 1 / ( norm(A) * norm(inv(A)) ).** Arguments* =========** NORM (input) CHARACTER*1* Specifies whether the 1-norm condition number or the* infinity-norm condition number is required:* = '1' or 'O': 1-norm;* = 'I': Infinity-norm.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The factors L and U from the factorization A = P*L*U* as computed by DGETRF.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** ANORM (input) DOUBLE PRECISION* If NORM = '1' or 'O', the 1-norm of the original matrix A.* If NORM = 'I', the infinity-norm of the original matrix A.** RCOND (output) DOUBLE PRECISION* The reciprocal of the condition number of the matrix A,* computed as RCOND = 1/(norm(A) * norm(inv(A))).** WORK (workspace) DOUBLE PRECISION array, dimension (4*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ONENRMCHARACTER NORMININTEGER IX, KASE, KASE1DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL LSAME, IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLACON, DLATRS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( ANORM.LT.ZERO ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGECON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the norm of inv(A).*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 010 CONTINUECALL DLACON( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(L).*CALL DLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A,$ LDA, WORK, SL, WORK( 2*N+1 ), INFO )** Multiply by inv(U).*CALL DLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ A, LDA, WORK, SU, WORK( 3*N+1 ), INFO )ELSE** Multiply by inv(U').*CALL DLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,$ LDA, WORK, SU, WORK( 3*N+1 ), INFO )** Multiply by inv(L').*CALL DLATRS( 'Lower', 'Transpose', 'Unit', NORMIN, N, A,$ LDA, WORK, SL, WORK( 2*N+1 ), INFO )END IF** Divide X by 1/(SL*SU) if doing so will not cause overflow.*SCALE = SL*SUNORMIN = 'Y'IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*20 CONTINUERETURN** End of DGECON*ENDSUBROUTINE DGEEQU( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* March 31, 1993** .. Scalar Arguments ..INTEGER INFO, LDA, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..** Purpose* =======** DGEEQU computes row and column scalings intended to equilibrate an* M-by-N matrix A and reduce its condition number. R returns the row* scale factors and C the column scale factors, chosen to try to make* the largest element in each row and column of the matrix B with* elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.** R(i) and C(j) are restricted to be between SMLNUM = smallest safe* number and BIGNUM = largest safe number. Use of these scaling* factors is not guaranteed to reduce the condition number of A but* works well in practice.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The M-by-N matrix whose equilibration factors are* to be computed.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** R (output) DOUBLE PRECISION array, dimension (M)* If INFO = 0 or INFO > M, R contains the row scale factors* for A.** C (output) DOUBLE PRECISION array, dimension (N)* If INFO = 0, C contains the column scale factors for A.** ROWCND (output) DOUBLE PRECISION* If INFO = 0 or INFO > M, ROWCND contains the ratio of the* smallest R(i) to the largest R(i). If ROWCND >= 0.1 and* AMAX is neither too large nor too small, it is not worth* scaling by R.** COLCND (output) DOUBLE PRECISION* If INFO = 0, COLCND contains the ratio of the smallest* C(i) to the largest C(i). If COLCND >= 0.1, it is not* worth scaling by C.** AMAX (output) DOUBLE PRECISION* Absolute value of largest matrix element. If AMAX is very* close to overflow or very close to underflow, the matrix* should be scaled.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, and i is* <= M: the i-th row of A is exactly zero* > M: the (i-M)-th column of A is exactly zero** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION BIGNUM, RCMAX, RCMIN, SMLNUM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEQU', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENROWCND = ONECOLCND = ONEAMAX = ZERORETURNEND IF** Get machine constants.*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUM** Compute row scale factors.*DO 10 I = 1, MR( I ) = ZERO10 CONTINUE** Find the maximum element in each row.*DO 30 J = 1, NDO 20 I = 1, MR( I ) = MAX( R( I ), ABS( A( I, J ) ) )20 CONTINUE30 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 40 I = 1, MRCMAX = MAX( RCMAX, R( I ) )RCMIN = MIN( RCMIN, R( I ) )40 CONTINUEAMAX = RCMAX*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 50 I = 1, MIF( R( I ).EQ.ZERO ) THENINFO = IRETURNEND IF50 CONTINUEELSE** Invert the scale factors.*DO 60 I = 1, MR( I ) = ONE / MIN( MAX( R( I ), SMLNUM ), BIGNUM )60 CONTINUE** Compute ROWCND = min(R(I)) / max(R(I))*ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF** Compute column scale factors*DO 70 J = 1, NC( J ) = ZERO70 CONTINUE** Find the maximum element in each column,* assuming the row scaling computed above.*DO 90 J = 1, NDO 80 I = 1, MC( J ) = MAX( C( J ), ABS( A( I, J ) )*R( I ) )80 CONTINUE90 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 100 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )100 CONTINUE*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 110 J = 1, NIF( C( J ).EQ.ZERO ) THENINFO = M + JRETURNEND IF110 CONTINUEELSE** Invert the scale factors.*DO 120 J = 1, NC( J ) = ONE / MIN( MAX( C( J ), SMLNUM ), BIGNUM )120 CONTINUE** Compute COLCND = min(C(J)) / max(C(J))*COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF*RETURN** End of DGEEQU*ENDSUBROUTINE DGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1992** .. Scalar Arguments ..INTEGER IHI, ILO, INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEHD2 reduces a real general matrix A to upper Hessenberg form H by* an orthogonal similarity transformation: Q' * A * Q = H .** Arguments* =========** N (input) INTEGER* The order of the matrix A. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* It is assumed that A is already upper triangular in rows* and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally* set by a previous call to DGEBAL; otherwise they should be* set to 1 and N respectively. See Further Details.* 1 <= ILO <= IHI <= max(1,N).** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the n by n general matrix to be reduced.* On exit, the upper triangle and the first subdiagonal of A* are overwritten with the upper Hessenberg matrix H, and the* elements below the first subdiagonal, with the array TAU,* represent the orthogonal matrix Q as a product of elementary* reflectors. See Further Details.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** TAU (output) DOUBLE PRECISION array, dimension (N-1)* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The matrix Q is represented as a product of (ihi-ilo) elementary* reflectors** Q = H(ilo) H(ilo+1) . . . H(ihi-1).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on* exit in A(i+2:ihi,i), and tau in TAU(i).** The contents of A are illustrated by the following example, with* n = 7, ilo = 2 and ihi = 6:** on entry, on exit,** ( a a a a a a a ) ( a a h h h h a )* ( a a a a a a ) ( a h h h h a )* ( a a a a a a ) ( h h h h h h )* ( a a a a a a ) ( v2 h h h h h )* ( a a a a a a ) ( v2 v3 h h h h )* ( a a a a a a ) ( v2 v3 v4 h h h )* ( a ) ( a )** where a denotes an element of the original matrix A, h denotes a* modified element of the upper Hessenberg matrix H, and vi denotes an* element of the vector defining H(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -2ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEHD2', -INFO )RETURNEND IF*DO 10 I = ILO, IHI - 1** Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)*CALL DLARFG( IHI-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,$ TAU( I ) )AII = A( I+1, I )A( I+1, I ) = ONE** Apply H(i) to A(1:ihi,i+1:ihi) from the right*CALL DLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ),$ A( 1, I+1 ), LDA, WORK )** Apply H(i) to A(i+1:ihi,i+1:n) from the left*CALL DLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1, TAU( I ),$ A( I+1, I+1 ), LDA, WORK )*A( I+1, I ) = AII10 CONTINUE*RETURN** End of DGEHD2*ENDSUBROUTINE DGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER IHI, ILO, INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEHRD reduces a real general matrix A to upper Hessenberg form H by* an orthogonal similarity transformation: Q' * A * Q = H .** Arguments* =========** N (input) INTEGER* The order of the matrix A. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* It is assumed that A is already upper triangular in rows* and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally* set by a previous call to DGEBAL; otherwise they should be* set to 1 and N respectively. See Further Details.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the N-by-N general matrix to be reduced.* On exit, the upper triangle and the first subdiagonal of A* are overwritten with the upper Hessenberg matrix H, and the* elements below the first subdiagonal, with the array TAU,* represent the orthogonal matrix Q as a product of elementary* reflectors. See Further Details.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** TAU (output) DOUBLE PRECISION array, dimension (N-1)* The scalar factors of the elementary reflectors (see Further* Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to* zero.** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The length of the array WORK. LWORK >= max(1,N).* For optimum performance LWORK >= N*NB, where NB is the* optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The matrix Q is represented as a product of (ihi-ilo) elementary* reflectors** Q = H(ilo) H(ilo+1) . . . H(ihi-1).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on* exit in A(i+2:ihi,i), and tau in TAU(i).** The contents of A are illustrated by the following example, with* n = 7, ilo = 2 and ihi = 6:** on entry, on exit,** ( a a a a a a a ) ( a a h h h h a )* ( a a a a a a ) ( a h h h h a )* ( a a a a a a ) ( h h h h h h )* ( a a a a a a ) ( v2 h h h h h )* ( a a a a a a ) ( v2 v3 h h h h )* ( a a a a a a ) ( v2 v3 v4 h h h )* ( a ) ( a )** where a denotes an element of the original matrix A, h denotes a* modified element of the upper Hessenberg matrix H, and vi denotes an* element of the vector defining H(i).** =====================================================================** .. Parameters ..INTEGER NBMAX, LDTPARAMETER ( NBMAX = 64, LDT = NBMAX+1 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, LDWORK, LWKOPT, NB, NBMIN,$ NH, NXDOUBLE PRECISION EI* ..* .. Local Arrays ..DOUBLE PRECISION T( LDT, NBMAX )* ..* .. External Subroutines ..EXTERNAL DGEHD2, DGEMM, DLAHRD, DLARFB, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB = MIN( NBMAX, ILAENV( 1, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -2ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEHRD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Set elements 1:ILO-1 and IHI:N-1 of TAU to zero*DO 10 I = 1, ILO - 1TAU( I ) = ZERO10 CONTINUEDO 20 I = MAX( 1, IHI ), N - 1TAU( I ) = ZERO20 CONTINUE** Quick return if possible*NH = IHI - ILO + 1IF( NH.LE.1 ) THENWORK( 1 ) = 1RETURNEND IF** Determine the block size.*NB = MIN( NBMAX, ILAENV( 1, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )NBMIN = 2IWS = 1IF( NB.GT.1 .AND. NB.LT.NH ) THEN** Determine when to cross over from blocked to unblocked code* (last block is always handled by unblocked code).*NX = MAX( NB, ILAENV( 3, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )IF( NX.LT.NH ) THEN** Determine if workspace is large enough for blocked code.*IWS = N*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: determine the* minimum value of NB, and reduce NB or force use of* unblocked code.*NBMIN = MAX( 2, ILAENV( 2, 'DGEHRD', ' ', N, ILO, IHI,$ -1 ) )IF( LWORK.GE.N*NBMIN ) THENNB = LWORK / NELSENB = 1END IFEND IFEND IFEND IFLDWORK = N*IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN** Use unblocked code below*I = ILO*ELSE** Use blocked code*DO 30 I = ILO, IHI - 1 - NX, NBIB = MIN( NB, IHI-I )** Reduce columns i:i+ib-1 to Hessenberg form, returning the* matrices V and T of the block reflector H = I - V*T*V'* which performs the reduction, and also the matrix Y = A*V*T*CALL DLAHRD( IHI, I, IB, A( 1, I ), LDA, TAU( I ), T, LDT,$ WORK, LDWORK )** Apply the block reflector H to A(1:ihi,i+ib:ihi) from the* right, computing A := A - Y * V'. V(i+ib,ib-1) must be set* to 1.*EI = A( I+IB, I+IB-1 )A( I+IB, I+IB-1 ) = ONECALL DGEMM( 'No transpose', 'Transpose', IHI, IHI-I-IB+1,$ IB, -ONE, WORK, LDWORK, A( I+IB, I ), LDA, ONE,$ A( 1, I+IB ), LDA )A( I+IB, I+IB-1 ) = EI** Apply the block reflector H to A(i+1:ihi,i+ib:n) from the* left*CALL DLARFB( 'Left', 'Transpose', 'Forward', 'Columnwise',$ IHI-I, N-I-IB+1, IB, A( I+1, I ), LDA, T, LDT,$ A( I+1, I+IB ), LDA, WORK, LDWORK )30 CONTINUEEND IF** Use unblocked code to reduce the rest of the matrix*CALL DGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )WORK( 1 ) = IWS*RETURN** End of DGEHRD*ENDSUBROUTINE DGELQ2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGELQ2 computes an LQ factorization of a real m by n matrix A:* A = L * Q.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n matrix A.* On exit, the elements on and below the diagonal of the array* contain the m by min(m,n) lower trapezoidal matrix L (L is* lower triangular if m <= n); the elements above the diagonal,* with the array TAU, represent the orthogonal matrix Q as a* product of elementary reflectors (see Further Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace) DOUBLE PRECISION array, dimension (M)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(k) . . . H(2) H(1), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),* and tau in TAU(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGELQ2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = 1, K** Generate elementary reflector H(i) to annihilate A(i,i+1:n)*CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,$ TAU( I ) )IF( I.LT.M ) THEN** Apply H(i) to A(i+1:m,i:n) from the right*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ),$ A( I+1, I ), LDA, WORK )A( I, I ) = AIIEND IF10 CONTINUERETURN** End of DGELQ2*ENDSUBROUTINE DGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGELQF computes an LQ factorization of a real M-by-N matrix A:* A = L * Q.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, the elements on and below the diagonal of the array* contain the m-by-min(m,n) lower trapezoidal matrix L (L is* lower triangular if m <= n); the elements above the diagonal,* with the array TAU, represent the orthogonal matrix Q as a* product of elementary reflectors (see Further Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,M).* For optimum performance LWORK >= M*NB, where NB is the* optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(k) . . . H(2) H(1), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),* and tau in TAU(i).** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DGELQ2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )LWKOPT = M*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGELQF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = MIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGELQF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGELQF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially*DO 10 I = 1, K - NX, NBIB = MIN( K-I+1, NB )** Compute the LQ factorization of the current block* A(i:i+ib-1,i:n)*CALL DGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )IF( I+IB.LE.M ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),$ LDA, TAU( I ), WORK, LDWORK )** Apply H to A(i+ib:m,i:n) from the right*CALL DLARFB( 'Right', 'No transpose', 'Forward',$ 'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),$ LDA, WORK, LDWORK, A( I+IB, I ), LDA,$ WORK( IB+1 ), LDWORK )END IF10 CONTINUEELSEI = 1END IF** Use unblocked code to factor the last or only block.*IF( I.LE.K )$ CALL DGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )*WORK( 1 ) = IWSRETURN** End of DGELQF*ENDSUBROUTINE DGEQL2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEQL2 computes a QL factorization of a real m by n matrix A:* A = Q * L.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n matrix A.* On exit, if m >= n, the lower triangle of the subarray* A(m-n+1:m,1:n) contains the n by n lower triangular matrix L;* if m <= n, the elements on and below the (n-m)-th* superdiagonal contain the m by n lower trapezoidal matrix L;* the remaining elements, with the array TAU, represent the* orthogonal matrix Q as a product of elementary reflectors* (see Further Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(k) . . . H(2) H(1), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in* A(1:m-k+i-1,n-k+i), and tau in TAU(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQL2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = K, 1, -1** Generate elementary reflector H(i) to annihilate* A(1:m-k+i-1,n-k+i)*CALL DLARFG( M-K+I, A( M-K+I, N-K+I ), A( 1, N-K+I ), 1,$ TAU( I ) )** Apply H(i) to A(1:m-k+i,1:n-k+i-1) from the left*AII = A( M-K+I, N-K+I )A( M-K+I, N-K+I ) = ONECALL DLARF( 'Left', M-K+I, N-K+I-1, A( 1, N-K+I ), 1, TAU( I ),$ A, LDA, WORK )A( M-K+I, N-K+I ) = AII10 CONTINUERETURN** End of DGEQL2*ENDSUBROUTINE DGEQLF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEQLF computes a QL factorization of a real M-by-N matrix A:* A = Q * L.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit,* if m >= n, the lower triangle of the subarray* A(m-n+1:m,1:n) contains the N-by-N lower triangular matrix L;* if m <= n, the elements on and below the (n-m)-th* superdiagonal contain the M-by-N lower trapezoidal matrix L;* the remaining elements, with the array TAU, represent the* orthogonal matrix Q as a product of elementary reflectors* (see Further Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N).* For optimum performance LWORK >= N*NB, where NB is the* optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(k) . . . H(2) H(1), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in* A(1:m-k+i-1,n-k+i), and tau in TAU(i).** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, KI, KK, LDWORK, LWKOPT,$ MU, NB, NBMIN, NU, NX* ..* .. External Subroutines ..EXTERNAL DGEQL2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGEQLF', ' ', M, N, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQLF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 1IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGEQLF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGEQLF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially.* The last kk columns are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )*DO 10 I = K - KK + KI + 1, K - KK + 1, -NBIB = MIN( K-I+1, NB )** Compute the QL factorization of the current block* A(1:m-k+i+ib-1,n-k+i:n-k+i+ib-1)*CALL DGEQL2( M-K+I+IB-1, IB, A( 1, N-K+I ), LDA, TAU( I ),$ WORK, IINFO )IF( N-K+I.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,$ A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )** Apply H' to A(1:m-k+i+ib-1,1:n-k+i-1) from the left*CALL DLARFB( 'Left', 'Transpose', 'Backward',$ 'Columnwise', M-K+I+IB-1, N-K+I-1, IB,$ A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,$ WORK( IB+1 ), LDWORK )END IF10 CONTINUEMU = M - K + I + NB - 1NU = N - K + I + NB - 1ELSEMU = MNU = NEND IF** Use unblocked code to factor the last or only block*IF( MU.GT.0 .AND. NU.GT.0 )$ CALL DGEQL2( MU, NU, A, LDA, TAU, WORK, IINFO )*WORK( 1 ) = IWSRETURN** End of DGEQLF*ENDSUBROUTINE DGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEQP3 computes a QR factorization with column pivoting of a* matrix A: A*P = Q*R using Level 3 BLAS.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, the upper triangle of the array contains the* min(M,N)-by-N upper trapezoidal matrix R; the elements below* the diagonal, together with the array TAU, represent the* orthogonal matrix Q as a product of min(M,N) elementary* reflectors.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** JPVT (input/output) INTEGER array, dimension (N)* On entry, if JPVT(J).ne.0, the J-th column of A is permuted* to the front of A*P (a leading column); if JPVT(J)=0,* the J-th column of A is a free column.* On exit, if JPVT(J)=K, then the J-th column of A*P was the* the K-th column of A.** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors.** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO=0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= 3*N+1.* For optimal performance LWORK >= 2*N+( N+1 )*NB, where NB* is the optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real/complex scalar, and v is a real/complex vector* with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in* A(i+1:m,i), and tau in TAU(i).** Based on contributions by* G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain* X. Sun, Computer Science Dept., Duke University, USA** =====================================================================** .. Parameters ..INTEGER INB, INBMIN, IXOVERPARAMETER ( INB = 1, INBMIN = 2, IXOVER = 3 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,$ NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN* ..* .. External Subroutines ..EXTERNAL DGEQRF, DLAQP2, DLAQPS, DORMQR, DSWAP, XERBLA* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DNRM2EXTERNAL ILAENV, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..*IWS = 3*N + 1MINMN = MIN( M, N )** Test input arguments* ====================*INFO = 0NB = ILAENV( INB, 'DGEQRF', ' ', M, N, -1, -1 )LWKOPT = 2*N + ( N+1 )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQP3', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible.*IF( MINMN.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF** Move initial columns up front.*NFXD = 1DO 10 J = 1, NIF( JPVT( J ).NE.0 ) THENIF( J.NE.NFXD ) THENCALL DSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )JPVT( J ) = JPVT( NFXD )JPVT( NFXD ) = JELSEJPVT( J ) = JEND IFNFXD = NFXD + 1ELSEJPVT( J ) = JEND IF10 CONTINUENFXD = NFXD - 1** Factorize fixed columns* =======================** Compute the QR factorization of fixed columns and update* remaining columns.*IF( NFXD.GT.0 ) THENNA = MIN( M, NFXD )*CC CALL DGEQR2( M, NA, A, LDA, TAU, WORK, INFO )CALL DGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )IWS = MAX( IWS, INT( WORK( 1 ) ) )IF( NA.LT.N ) THEN*CC CALL DORM2R( 'Left', 'Transpose', M, N-NA, NA, A, LDA,*CC $ TAU, A( 1, NA+1 ), LDA, WORK, INFO )CALL DORMQR( 'Left', 'Transpose', M, N-NA, NA, A, LDA, TAU,$ A( 1, NA+1 ), LDA, WORK, LWORK, INFO )IWS = MAX( IWS, INT( WORK( 1 ) ) )END IFEND IF** Factorize free columns* ======================*IF( NFXD.LT.MINMN ) THEN*SM = M - NFXDSN = N - NFXDSMINMN = MINMN - NFXD** Determine the block size.*NB = ILAENV( INB, 'DGEQRF', ' ', SM, SN, -1, -1 )NBMIN = 2NX = 0*IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( IXOVER, 'DGEQRF', ' ', SM, SN, -1,$ -1 ) )**IF( NX.LT.SMINMN ) THEN** Determine if workspace is large enough for blocked code.*MINWS = 2*SN + ( SN+1 )*NBIWS = MAX( IWS, MINWS )IF( LWORK.LT.MINWS ) THEN** Not enough workspace to use optimal NB: Reduce NB and* determine the minimum value of NB.*NB = ( LWORK-2*SN ) / ( SN+1 )NBMIN = MAX( 2, ILAENV( INBMIN, 'DGEQRF', ' ', SM, SN,$ -1, -1 ) )**END IFEND IFEND IF** Initialize partial column norms. The first N elements of work* store the exact column norms.*DO 20 J = NFXD + 1, NWORK( J ) = DNRM2( SM, A( NFXD+1, J ), 1 )WORK( N+J ) = WORK( J )20 CONTINUE*IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.$ ( NX.LT.SMINMN ) ) THEN** Use blocked code initially.*J = NFXD + 1** Compute factorization: while loop.**TOPBMN = MINMN - NX30 CONTINUEIF( J.LE.TOPBMN ) THENJB = MIN( NB, TOPBMN-J+1 )** Factorize JB columns among columns J:N.*CALL DLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,$ JPVT( J ), TAU( J ), WORK( J ), WORK( N+J ),$ WORK( 2*N+1 ), WORK( 2*N+JB+1 ), N-J+1 )*J = J + FJBGO TO 30END IFELSEJ = NFXD + 1END IF** Use unblocked code to factor the last or only block.**IF( J.LE.MINMN )$ CALL DLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),$ TAU( J ), WORK( J ), WORK( N+J ),$ WORK( 2*N+1 ) )*END IF*WORK( 1 ) = IWSRETURN** End of DGEQP3*ENDSUBROUTINE DGEQPF( M, N, A, LDA, JPVT, TAU, WORK, INFO )** -- LAPACK test routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* March 31, 1993** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** This routine is deprecated and has been replaced by routine DGEQP3.** DGEQPF computes a QR factorization with column pivoting of a* real M-by-N matrix A: A*P = Q*R.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, the upper triangle of the array contains the* min(M,N)-by-N upper triangular matrix R; the elements* below the diagonal, together with the array TAU,* represent the orthogonal matrix Q as a product of* min(m,n) elementary reflectors.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** JPVT (input/output) INTEGER array, dimension (N)* On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted* to the front of A*P (a leading column); if JPVT(i) = 0,* the i-th column of A is a free column.* On exit, if JPVT(i) = k, then the i-th column of A*P* was the k-th column of A.** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors.** WORK (workspace) DOUBLE PRECISION array, dimension (3*N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(n)** Each H(i) has the form** H = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i).** The matrix P is represented in jpvt as follows: If* jpvt(j) = i* then the jth column of P is the ith canonical unit vector.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, ITEMP, J, MA, MN, PVTDOUBLE PRECISION AII, TEMP, TEMP2* ..* .. External Subroutines ..EXTERNAL DGEQR2, DLARF, DLARFG, DORM2R, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DNRM2EXTERNAL IDAMAX, DNRM2* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQPF', -INFO )RETURNEND IF*MN = MIN( M, N )** Move initial columns up front*ITEMP = 1DO 10 I = 1, NIF( JPVT( I ).NE.0 ) THENIF( I.NE.ITEMP ) THENCALL DSWAP( M, A( 1, I ), 1, A( 1, ITEMP ), 1 )JPVT( I ) = JPVT( ITEMP )JPVT( ITEMP ) = IELSEJPVT( I ) = IEND IFITEMP = ITEMP + 1ELSEJPVT( I ) = IEND IF10 CONTINUEITEMP = ITEMP - 1** Compute the QR factorization and update remaining columns*IF( ITEMP.GT.0 ) THENMA = MIN( ITEMP, M )CALL DGEQR2( M, MA, A, LDA, TAU, WORK, INFO )IF( MA.LT.N ) THENCALL DORM2R( 'Left', 'Transpose', M, N-MA, MA, A, LDA, TAU,$ A( 1, MA+1 ), LDA, WORK, INFO )END IFEND IF*IF( ITEMP.LT.MN ) THEN** Initialize partial column norms. The first n elements of* work store the exact column norms.*DO 20 I = ITEMP + 1, NWORK( I ) = DNRM2( M-ITEMP, A( ITEMP+1, I ), 1 )WORK( N+I ) = WORK( I )20 CONTINUE** Compute factorization*DO 40 I = ITEMP + 1, MN** Determine ith pivot column and swap if necessary*PVT = ( I-1 ) + IDAMAX( N-I+1, WORK( I ), 1 )*IF( PVT.NE.I ) THENCALL DSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )ITEMP = JPVT( PVT )JPVT( PVT ) = JPVT( I )JPVT( I ) = ITEMPWORK( PVT ) = WORK( I )WORK( N+PVT ) = WORK( N+I )END IF** Generate elementary reflector H(i)*IF( I.LT.M ) THENCALL DLARFG( M-I+1, A( I, I ), A( I+1, I ), 1, TAU( I ) )ELSECALL DLARFG( 1, A( M, M ), A( M, M ), 1, TAU( M ) )END IF*IF( I.LT.N ) THEN** Apply H(i) to A(i:m,i+1:n) from the left*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'LEFT', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK( 2*N+1 ) )A( I, I ) = AIIEND IF** Update partial column norms*DO 30 J = I + 1, NIF( WORK( J ).NE.ZERO ) THENTEMP = ONE - ( ABS( A( I, J ) ) / WORK( J ) )**2TEMP = MAX( TEMP, ZERO )TEMP2 = ONE + 0.05D0*TEMP*$ ( WORK( J ) / WORK( N+J ) )**2IF( TEMP2.EQ.ONE ) THENIF( M-I.GT.0 ) THENWORK( J ) = DNRM2( M-I, A( I+1, J ), 1 )WORK( N+J ) = WORK( J )ELSEWORK( J ) = ZEROWORK( N+J ) = ZEROEND IFELSEWORK( J ) = WORK( J )*SQRT( TEMP )END IFEND IF30 CONTINUE*40 CONTINUEEND IFRETURN** End of DGEQPF*ENDSUBROUTINE DGEQR2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEQR2 computes a QR factorization of a real m by n matrix A:* A = Q * R.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n matrix A.* On exit, the elements on and above the diagonal of the array* contain the min(m,n) by n upper trapezoidal matrix R (R is* upper triangular if m >= n); the elements below the diagonal,* with the array TAU, represent the orthogonal matrix Q as a* product of elementary reflectors (see Further Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),* and tau in TAU(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQR2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = 1, K** Generate elementary reflector H(i) to annihilate A(i+1:m,i)*CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ TAU( I ) )IF( I.LT.N ) THEN** Apply H(i) to A(i:m,i+1:n) from the left*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK )A( I, I ) = AIIEND IF10 CONTINUERETURN** End of DGEQR2*ENDSUBROUTINE DGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGEQRF computes a QR factorization of a real M-by-N matrix A:* A = Q * R.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, the elements on and above the diagonal of the array* contain the min(M,N)-by-N upper trapezoidal matrix R (R is* upper triangular if m >= n); the elements below the diagonal,* with the array TAU, represent the orthogonal matrix Q as a* product of min(m,n) elementary reflectors (see Further* Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N).* For optimum performance LWORK >= N*NB, where NB is* the optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),* and tau in TAU(i).** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DGEQR2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQRF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGEQRF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGEQRF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially*DO 10 I = 1, K - NX, NBIB = MIN( K-I+1, NB )** Compute the QR factorization of the current block* A(i:m,i:i+ib-1)*CALL DGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )IF( I+IB.LE.N ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB,$ A( I, I ), LDA, TAU( I ), WORK, LDWORK )** Apply H' to A(i:m,i+ib:n) from the left*CALL DLARFB( 'Left', 'Transpose', 'Forward',$ 'Columnwise', M-I+1, N-I-IB+1, IB,$ A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),$ LDA, WORK( IB+1 ), LDWORK )END IF10 CONTINUEELSEI = 1END IF** Use unblocked code to factor the last or only block.*IF( I.LE.K )$ CALL DGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )*WORK( 1 ) = IWSRETURN** End of DGEQRF*ENDSUBROUTINE DGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,$ X, LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** Purpose* =======** DGERFS improves the computed solution to a system of linear* equations and provides error bounds and backward error estimates for* the solution.** Arguments* =========** TRANS (input) CHARACTER*1* Specifies the form of the system of equations:* = 'N': A * X = B (No transpose)* = 'T': A**T * X = B (Transpose)* = 'C': A**H * X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A. N >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrices B and X. NRHS >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The original N-by-N matrix A.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** AF (input) DOUBLE PRECISION array, dimension (LDAF,N)* The factors L and U from the factorization A = P*L*U* as computed by DGETRF.** LDAF (input) INTEGER* The leading dimension of the array AF. LDAF >= max(1,N).** IPIV (input) INTEGER array, dimension (N)* The pivot indices from DGETRF; for 1<=i<=N, row i of the* matrix was interchanged with row IPIV(i).** B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)* The right hand side matrix B.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** X (input/output) DOUBLE PRECISION array, dimension (LDX,NRHS)* On entry, the solution matrix X, as computed by DGETRS.* On exit, the improved solution matrix X.** LDX (input) INTEGER* The leading dimension of the array X. LDX >= max(1,N).** FERR (output) DOUBLE PRECISION array, dimension (NRHS)* The estimated forward error bound for each solution vector* X(j) (the j-th column of the solution matrix X).* If XTRUE is the true solution corresponding to X(j), FERR(j)* is an estimated upper bound for the magnitude of the largest* element in (X(j) - XTRUE) divided by the magnitude of the* largest element in X(j). The estimate is as reliable as* the estimate for RCOND, and is almost always a slight* overestimate of the true error.** BERR (output) DOUBLE PRECISION array, dimension (NRHS)* The componentwise relative backward error of each solution* vector X(j) (i.e., the smallest relative change in* any element of A or B that makes X(j) an exact solution).** WORK (workspace) DOUBLE PRECISION array, dimension (3*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Internal Parameters* ===================** ITMAX is the maximum number of steps of iterative refinement.** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANCHARACTER TRANSTINTEGER COUNT, I, J, K, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGETRS, DLACON, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGERFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - op(A) * X,* where op(A) = A, A**T, or A**H, depending on TRANS.*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DGEMV( TRANS, N, N, -ONE, A, LDA, X( 1, J ), 1, ONE,$ WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(op(A))*abs(X) + abs(B).*IF( NOTRAN ) THENDO 50 K = 1, NXK = ABS( X( K, J ) )DO 40 I = 1, NWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XK40 CONTINUE50 CONTINUEELSEDO 70 K = 1, NS = ZERODO 60 I = 1, NS = S + ABS( A( I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DGETRS( TRANS, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACON to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACON( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DGETRS( TRANST, N, 1, AF, LDAF, IPIV, WORK( N+1 ),$ N, INFO )DO 110 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )110 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )120 CONTINUECALL DGETRS( TRANS, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DGERFS*ENDSUBROUTINE DGERQ2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGERQ2 computes an RQ factorization of a real m by n matrix A:* A = R * Q.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n matrix A.* On exit, if m <= n, the upper triangle of the subarray* A(1:m,n-m+1:n) contains the m by m upper triangular matrix R;* if m >= n, the elements on and above the (m-n)-th subdiagonal* contain the m by n upper trapezoidal matrix R; the remaining* elements, with the array TAU, represent the orthogonal matrix* Q as a product of elementary reflectors (see Further* Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace) DOUBLE PRECISION array, dimension (M)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in* A(m-k+i,1:n-k+i-1), and tau in TAU(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGERQ2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = K, 1, -1** Generate elementary reflector H(i) to annihilate* A(m-k+i,1:n-k+i-1)*CALL DLARFG( N-K+I, A( M-K+I, N-K+I ), A( M-K+I, 1 ), LDA,$ TAU( I ) )** Apply H(i) to A(1:m-k+i-1,1:n-k+i) from the right*AII = A( M-K+I, N-K+I )A( M-K+I, N-K+I ) = ONECALL DLARF( 'Right', M-K+I-1, N-K+I, A( M-K+I, 1 ), LDA,$ TAU( I ), A, LDA, WORK )A( M-K+I, N-K+I ) = AII10 CONTINUERETURN** End of DGERQ2*ENDSUBROUTINE DGERQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DGERQF computes an RQ factorization of a real M-by-N matrix A:* A = R * Q.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit,* if m <= n, the upper triangle of the subarray* A(1:m,n-m+1:n) contains the M-by-M upper triangular matrix R;* if m >= n, the elements on and above the (m-n)-th subdiagonal* contain the M-by-N upper trapezoidal matrix R;* the remaining elements, with the array TAU, represent the* orthogonal matrix Q as a product of min(m,n) elementary* reflectors (see Further Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors (see Further* Details).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,M).* For optimum performance LWORK >= M*NB, where NB is* the optimal blocksize.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(m,n).** Each H(i) has the form** H(i) = I - tau * v * v'** where tau is a real scalar, and v is a real vector with* v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in* A(m-k+i,1:n-k+i-1), and tau in TAU(i).** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, KI, KK, LDWORK, LWKOPT,$ MU, NB, NBMIN, NU, NX* ..* .. External Subroutines ..EXTERNAL DGERQ2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )LWKOPT = M*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGERQF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 1IWS = MIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGERQF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGERQF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially.* The last kk rows are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )*DO 10 I = K - KK + KI + 1, K - KK + 1, -NBIB = MIN( K-I+1, NB )** Compute the RQ factorization of the current block* A(m-k+i:m-k+i+ib-1,1:n-k+i+ib-1)*CALL DGERQ2( IB, N-K+I+IB-1, A( M-K+I, 1 ), LDA, TAU( I ),$ WORK, IINFO )IF( M-K+I.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Rowwise', N-K+I+IB-1, IB,$ A( M-K+I, 1 ), LDA, TAU( I ), WORK, LDWORK )** Apply H to A(1:m-k+i-1,1:n-k+i+ib-1) from the right*CALL DLARFB( 'Right', 'No transpose', 'Backward',$ 'Rowwise', M-K+I-1, N-K+I+IB-1, IB,$ A( M-K+I, 1 ), LDA, WORK, LDWORK, A, LDA,$ WORK( IB+1 ), LDWORK )END IF10 CONTINUEMU = M - K + I + NB - 1NU = N - K + I + NB - 1ELSEMU = MNU = NEND IF** Use unblocked code to factor the last or only block*IF( MU.GT.0 .AND. NU.GT.0 )$ CALL DGERQ2( MU, NU, A, LDA, TAU, WORK, IINFO )*WORK( 1 ) = IWSRETURN** End of DGERQF*ENDSUBROUTINE DGETF2( M, N, A, LDA, IPIV, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1992** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** Purpose* =======** DGETF2 computes an LU factorization of a general m-by-n matrix A* using partial pivoting with row interchanges.** The factorization has the form* A = P * L * U* where P is a permutation matrix, L is lower triangular with unit* diagonal elements (lower trapezoidal if m > n), and U is upper* triangular (upper trapezoidal if m < n).** This is the right-looking Level 2 BLAS version of the algorithm.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n matrix to be factored.* On exit, the factors L and U from the factorization* A = P*L*U; the unit diagonal elements of L are not stored.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** IPIV (output) INTEGER array, dimension (min(M,N))* The pivot indices; for 1 <= i <= min(M,N), row i of the* matrix was interchanged with row IPIV(i).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -k, the k-th argument had an illegal value* > 0: if INFO = k, U(k,k) is exactly zero. The factorization* has been completed, but the factor U is exactly* singular, and division by zero will occur if it is used* to solve a system of equations.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER J, JP* ..* .. External Functions ..INTEGER IDAMAXEXTERNAL IDAMAX* ..* .. External Subroutines ..EXTERNAL DGER, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETF2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN*DO 10 J = 1, MIN( M, N )** Find pivot and test for singularity.*JP = J - 1 + IDAMAX( M-J+1, A( J, J ), 1 )IPIV( J ) = JPIF( A( JP, J ).NE.ZERO ) THEN** Apply the interchange to columns 1:N.*IF( JP.NE.J )$ CALL DSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA )** Compute elements J+1:M of J-th column.*IF( J.LT.M )$ CALL DSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 )*ELSE IF( INFO.EQ.0 ) THEN*INFO = JEND IF*IF( J.LT.MIN( M, N ) ) THEN** Update trailing submatrix.*CALL DGER( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ), LDA,$ A( J+1, J+1 ), LDA )END IF10 CONTINUERETURN** End of DGETF2*ENDSUBROUTINE DGETRF( M, N, A, LDA, IPIV, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* March 31, 1993** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** Purpose* =======** DGETRF computes an LU factorization of a general M-by-N matrix A* using partial pivoting with row interchanges.** The factorization has the form* A = P * L * U* where P is a permutation matrix, L is lower triangular with unit* diagonal elements (lower trapezoidal if m > n), and U is upper* triangular (upper trapezoidal if m < n).** This is the right-looking Level 3 BLAS version of the algorithm.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix to be factored.* On exit, the factors L and U from the factorization* A = P*L*U; the unit diagonal elements of L are not stored.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** IPIV (output) INTEGER array, dimension (min(M,N))* The pivot indices; for 1 <= i <= min(M,N), row i of the* matrix was interchanged with row IPIV(i).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, U(i,i) is exactly zero. The factorization* has been completed, but the factor U is exactly* singular, and division by zero will occur if it is used* to solve a system of equations.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, IINFO, J, JB, NB* ..* .. External Subroutines ..EXTERNAL DGEMM, DGETF2, DLASWP, DTRSM, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRF', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Determine the block size for this environment.*NB = ILAENV( 1, 'DGETRF', ' ', M, N, -1, -1 )IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN** Use unblocked code.*CALL DGETF2( M, N, A, LDA, IPIV, INFO )ELSE** Use blocked code.*DO 20 J = 1, MIN( M, N ), NBJB = MIN( MIN( M, N )-J+1, NB )** Factor diagonal and subdiagonal blocks and test for exact* singularity.*CALL DGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )** Adjust INFO and the pivot indices.*IF( INFO.EQ.0 .AND. IINFO.GT.0 )$ INFO = IINFO + J - 1DO 10 I = J, MIN( M, J+JB-1 )IPIV( I ) = J - 1 + IPIV( I )10 CONTINUE** Apply interchanges to columns 1:J-1.*CALL DLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 )*IF( J+JB.LE.N ) THEN** Apply interchanges to columns J+JB:N.*CALL DLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1,$ IPIV, 1 )** Compute block row of U.*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB,$ N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ),$ LDA )IF( J+JB.LE.M ) THEN** Update trailing submatrix.*CALL DGEMM( 'No transpose', 'No transpose', M-J-JB+1,$ N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA,$ A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ),$ LDA )END IFEND IF20 CONTINUEEND IFRETURN** End of DGETRF*ENDSUBROUTINE DGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** Purpose* =======** DGETRI computes the inverse of a matrix using the LU factorization* computed by DGETRF.** This method inverts U and then computes inv(A) by solving the system* inv(A)*L = inv(U) for inv(A).** Arguments* =========** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the factors L and U from the factorization* A = P*L*U as computed by DGETRF.* On exit, if INFO = 0, the inverse of the original matrix A.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** IPIV (input) INTEGER array, dimension (N)* The pivot indices from DGETRF; for 1<=i<=N, row i of the* matrix was interchanged with row IPIV(i).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO=0, then WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N).* For optimal performance LWORK >= N*NB, where NB is* the optimal blocksize returned by ILAENV.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, U(i,i) is exactly zero; the matrix is* singular and its inverse could not be computed.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,$ NBMIN, NN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. External Subroutines ..EXTERNAL DGEMM, DGEMV, DSWAP, DTRSM, DTRTRI, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NB = ILAENV( 1, 'DGETRI', ' ', N, -1, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -3ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRI', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form inv(U). If INFO > 0 from DTRTRI, then U is singular,* and the inverse is not computed.*CALL DTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )IF( INFO.GT.0 )$ RETURN*NBMIN = 2LDWORK = NIF( NB.GT.1 .AND. NB.LT.N ) THENIWS = MAX( LDWORK*NB, 1 )IF( LWORK.LT.IWS ) THENNB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGETRI', ' ', N, -1, -1, -1 ) )END IFELSEIWS = NEND IF** Solve the equation inv(A)*L = inv(U) for inv(A).*IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN** Use unblocked code.*DO 20 J = N, 1, -1** Copy current column of L to WORK and replace with zeros.*DO 10 I = J + 1, NWORK( I ) = A( I, J )A( I, J ) = ZERO10 CONTINUE** Compute current column of inv(A).*IF( J.LT.N )$ CALL DGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),$ LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )20 CONTINUEELSE** Use blocked code.*NN = ( ( N-1 ) / NB )*NB + 1DO 50 J = NN, 1, -NBJB = MIN( NB, N-J+1 )** Copy current block column of L to WORK and replace with* zeros.*DO 40 JJ = J, J + JB - 1DO 30 I = JJ + 1, NWORK( I+( JJ-J )*LDWORK ) = A( I, JJ )A( I, JJ ) = ZERO30 CONTINUE40 CONTINUE** Compute current block column of inv(A).*IF( J+JB.LE.N )$ CALL DGEMM( 'No transpose', 'No transpose', N, JB,$ N-J-JB+1, -ONE, A( 1, J+JB ), LDA,$ WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )CALL DTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,$ ONE, WORK( J ), LDWORK, A( 1, J ), LDA )50 CONTINUEEND IF** Apply column interchanges.*DO 60 J = N - 1, 1, -1JP = IPIV( J )IF( JP.NE.J )$ CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )60 CONTINUE*WORK( 1 ) = IWSRETURN** End of DGETRI*ENDSUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* March 31, 1993** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** Purpose* =======** DGETRS solves a system of linear equations* A * X = B or A' * X = B* with a general N-by-N matrix A using the LU factorization computed* by DGETRF.** Arguments* =========** TRANS (input) CHARACTER*1* Specifies the form of the system of equations:* = 'N': A * X = B (No transpose)* = 'T': A'* X = B (Transpose)* = 'C': A'* X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A. N >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrix B. NRHS >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The factors L and U from the factorization A = P*L*U* as computed by DGETRF.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** IPIV (input) INTEGER array, dimension (N)* The pivot indices from DGETRF; for 1<=i<=N, row i of the* matrix was interchanged with row IPIV(i).** B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)* On entry, the right hand side matrix B.* On exit, the solution matrix X.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLASWP, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( NOTRAN ) THEN** Solve A * X = B.** Apply row interchanges to the right hand sides.*CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, 1 )** Solve L*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS,$ ONE, A, LDA, B, LDB )** Solve U*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,$ NRHS, ONE, A, LDA, B, LDB )ELSE** Solve A' * X = B.** Solve U'*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,$ ONE, A, LDA, B, LDB )** Solve L'*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Unit', N, NRHS, ONE,$ A, LDA, B, LDB )** Apply row interchanges to the solution vectors.*CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, -1 )END IF*RETURN** End of DGETRS*ENDSUBROUTINE DGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,$ LDV, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER JOB, SIDEINTEGER IHI, ILO, INFO, LDV, M, N* ..* .. Array Arguments ..DOUBLE PRECISION LSCALE( * ), RSCALE( * ), V( LDV, * )* ..** Purpose* =======** DGGBAK forms the right or left eigenvectors of a real generalized* eigenvalue problem A*x = lambda*B*x, by backward transformation on* the computed eigenvectors of the balanced pair of matrices output by* DGGBAL.** Arguments* =========** JOB (input) CHARACTER*1* Specifies the type of backward transformation required:* = 'N': do nothing, return immediately;* = 'P': do backward transformation for permutation only;* = 'S': do backward transformation for scaling only;* = 'B': do backward transformations for both permutation and* scaling.* JOB must be the same as the argument JOB supplied to DGGBAL.** SIDE (input) CHARACTER*1* = 'R': V contains right eigenvectors;* = 'L': V contains left eigenvectors.** N (input) INTEGER* The number of rows of the matrix V. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* The integers ILO and IHI determined by DGGBAL.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** LSCALE (input) DOUBLE PRECISION array, dimension (N)* Details of the permutations and/or scaling factors applied* to the left side of A and B, as returned by DGGBAL.** RSCALE (input) DOUBLE PRECISION array, dimension (N)* Details of the permutations and/or scaling factors applied* to the right side of A and B, as returned by DGGBAL.** M (input) INTEGER* The number of columns of the matrix V. M >= 0.** V (input/output) DOUBLE PRECISION array, dimension (LDV,M)* On entry, the matrix of right or left eigenvectors to be* transformed, as returned by DTGEVC.* On exit, V is overwritten by the transformed eigenvectors.** LDV (input) INTEGER* The leading dimension of the matrix V. LDV >= max(1,N).** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** See R.C. Ward, Balancing the generalized eigenvalue problem,* SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.** =====================================================================** .. Local Scalars ..LOGICAL LEFTV, RIGHTVINTEGER I, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters*RIGHTV = LSAME( SIDE, 'R' )LEFTV = LSAME( SIDE, 'L' )*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 ) THENINFO = -4ELSE IF( IHI.LT.ILO .OR. IHI.GT.MAX( 1, N ) ) THENINFO = -5ELSE IF( M.LT.0 ) THENINFO = -6ELSE IF( LDV.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGBAK', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( M.EQ.0 )$ RETURNIF( LSAME( JOB, 'N' ) )$ RETURN*IF( ILO.EQ.IHI )$ GO TO 30** Backward balance*IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN** Backward transformation on right eigenvectors*IF( RIGHTV ) THENDO 10 I = ILO, IHICALL DSCAL( M, RSCALE( I ), V( I, 1 ), LDV )10 CONTINUEEND IF** Backward transformation on left eigenvectors*IF( LEFTV ) THENDO 20 I = ILO, IHICALL DSCAL( M, LSCALE( I ), V( I, 1 ), LDV )20 CONTINUEEND IFEND IF** Backward permutation*30 CONTINUEIF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN** Backward permutation on right eigenvectors*IF( RIGHTV ) THENIF( ILO.EQ.1 )$ GO TO 50*DO 40 I = ILO - 1, 1, -1K = RSCALE( I )IF( K.EQ.I )$ GO TO 40CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )40 CONTINUE*50 CONTINUEIF( IHI.EQ.N )$ GO TO 70DO 60 I = IHI + 1, NK = RSCALE( I )IF( K.EQ.I )$ GO TO 60CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )60 CONTINUEEND IF** Backward permutation on left eigenvectors*70 CONTINUEIF( LEFTV ) THENIF( ILO.EQ.1 )$ GO TO 90DO 80 I = ILO - 1, 1, -1K = LSCALE( I )IF( K.EQ.I )$ GO TO 80CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )80 CONTINUE*90 CONTINUEIF( IHI.EQ.N )$ GO TO 110DO 100 I = IHI + 1, NK = LSCALE( I )IF( K.EQ.I )$ GO TO 100CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )100 CONTINUEEND IFEND IF*110 CONTINUE*RETURN** End of DGGBAK*ENDSUBROUTINE DGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,$ RSCALE, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER JOBINTEGER IHI, ILO, INFO, LDA, LDB, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), LSCALE( * ),$ RSCALE( * ), WORK( * )* ..** Purpose* =======** DGGBAL balances a pair of general real matrices (A,B). This* involves, first, permuting A and B by similarity transformations to* isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N* elements on the diagonal; and second, applying a diagonal similarity* transformation to rows and columns ILO to IHI to make the rows* and columns as close in norm as possible. Both steps are optional.** Balancing may reduce the 1-norm of the matrices, and improve the* accuracy of the computed eigenvalues and/or eigenvectors in the* generalized eigenvalue problem A*x = lambda*B*x.** Arguments* =========** JOB (input) CHARACTER*1* Specifies the operations to be performed on A and B:* = 'N': none: simply set ILO = 1, IHI = N, LSCALE(I) = 1.0* and RSCALE(I) = 1.0 for i = 1,...,N.* = 'P': permute only;* = 'S': scale only;* = 'B': both permute and scale.** N (input) INTEGER* The order of the matrices A and B. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the input matrix A.* On exit, A is overwritten by the balanced matrix.* If JOB = 'N', A is not referenced.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** B (input/output) DOUBLE PRECISION array, dimension (LDB,N)* On entry, the input matrix B.* On exit, B is overwritten by the balanced matrix.* If JOB = 'N', B is not referenced.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** ILO (output) INTEGER* IHI (output) INTEGER* ILO and IHI are set to integers such that on exit* A(i,j) = 0 and B(i,j) = 0 if i > j and* j = 1,...,ILO-1 or i = IHI+1,...,N.* If JOB = 'N' or 'S', ILO = 1 and IHI = N.** LSCALE (output) DOUBLE PRECISION array, dimension (N)* Details of the permutations and scaling factors applied* to the left side of A and B. If P(j) is the index of the* row interchanged with row j, and D(j)* is the scaling factor applied to row j, then* LSCALE(j) = P(j) for J = 1,...,ILO-1* = D(j) for J = ILO,...,IHI* = P(j) for J = IHI+1,...,N.* The order in which the interchanges are made is N to IHI+1,* then 1 to ILO-1.** RSCALE (output) DOUBLE PRECISION array, dimension (N)* Details of the permutations and scaling factors applied* to the right side of A and B. If P(j) is the index of the* column interchanged with column j, and D(j)* is the scaling factor applied to column j, then* LSCALE(j) = P(j) for J = 1,...,ILO-1* = D(j) for J = ILO,...,IHI* = P(j) for J = IHI+1,...,N.* The order in which the interchanges are made is N to IHI+1,* then 1 to ILO-1.** WORK (workspace) DOUBLE PRECISION array, dimension (6*N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** See R.C. WARD, Balancing the generalized eigenvalue problem,* SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )DOUBLE PRECISION THREE, SCLFACPARAMETER ( THREE = 3.0D+0, SCLFAC = 1.0D+1 )* ..* .. Local Scalars ..INTEGER I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,$ K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,$ M, NR, NRP2DOUBLE PRECISION ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,$ COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,$ SFMIN, SUM, T, TA, TB, TC* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG10, MAX, MIN, SIGN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGBAL', -INFO )RETURNEND IF*K = 1L = N** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( LSAME( JOB, 'N' ) ) THENILO = 1IHI = NDO 10 I = 1, NLSCALE( I ) = ONERSCALE( I ) = ONE10 CONTINUERETURNEND IF*IF( K.EQ.L ) THENILO = 1IHI = 1LSCALE( 1 ) = ONERSCALE( 1 ) = ONERETURNEND IF*IF( LSAME( JOB, 'S' ) )$ GO TO 190*GO TO 30** Permute the matrices A and B to isolate the eigenvalues.** Find row with one nonzero in columns 1 through L*20 CONTINUEL = LM1IF( L.NE.1 )$ GO TO 30*RSCALE( 1 ) = 1LSCALE( 1 ) = 1GO TO 190*30 CONTINUELM1 = L - 1DO 80 I = L, 1, -1DO 40 J = 1, LM1JP1 = J + 1IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 5040 CONTINUEJ = LGO TO 70*50 CONTINUEDO 60 J = JP1, LIF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 8060 CONTINUEJ = JP1 - 1*70 CONTINUEM = LIFLOW = 1GO TO 16080 CONTINUEGO TO 100** Find column with one nonzero in rows K through N*90 CONTINUEK = K + 1*100 CONTINUEDO 150 J = K, LDO 110 I = K, LM1IP1 = I + 1IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 120110 CONTINUEI = LGO TO 140120 CONTINUEDO 130 I = IP1, LIF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 150130 CONTINUEI = IP1 - 1140 CONTINUEM = KIFLOW = 2GO TO 160150 CONTINUEGO TO 190** Permute rows M and I*160 CONTINUELSCALE( M ) = IIF( I.EQ.M )$ GO TO 170CALL DSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )CALL DSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )** Permute columns M and J*170 CONTINUERSCALE( M ) = JIF( J.EQ.M )$ GO TO 180CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )CALL DSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )*180 CONTINUEGO TO ( 20, 90 )IFLOW*190 CONTINUEILO = KIHI = L*IF( ILO.EQ.IHI )$ RETURN*IF( LSAME( JOB, 'P' ) )$ RETURN** Balance the submatrix in rows ILO to IHI.*NR = IHI - ILO + 1DO 200 I = ILO, IHIRSCALE( I ) = ZEROLSCALE( I ) = ZERO*WORK( I ) = ZEROWORK( I+N ) = ZEROWORK( I+2*N ) = ZEROWORK( I+3*N ) = ZEROWORK( I+4*N ) = ZEROWORK( I+5*N ) = ZERO200 CONTINUE** Compute right side vector in resulting linear equations*BASL = LOG10( SCLFAC )DO 240 I = ILO, IHIDO 230 J = ILO, IHITB = B( I, J )TA = A( I, J )IF( TA.EQ.ZERO )$ GO TO 210TA = LOG10( ABS( TA ) ) / BASL210 CONTINUEIF( TB.EQ.ZERO )$ GO TO 220TB = LOG10( ABS( TB ) ) / BASL220 CONTINUEWORK( I+4*N ) = WORK( I+4*N ) - TA - TBWORK( J+5*N ) = WORK( J+5*N ) - TA - TB230 CONTINUE240 CONTINUE*COEF = ONE / DBLE( 2*NR )COEF2 = COEF*COEFCOEF5 = HALF*COEF2NRP2 = NR + 2BETA = ZEROIT = 1** Start generalized conjugate gradient iteration*250 CONTINUE*GAMMA = DDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +$ DDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )*EW = ZEROEWC = ZERODO 260 I = ILO, IHIEW = EW + WORK( I+4*N )EWC = EWC + WORK( I+5*N )260 CONTINUE*GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2IF( GAMMA.EQ.ZERO )$ GO TO 350IF( IT.NE.1 )$ BETA = GAMMA / PGAMMAT = COEF5*( EWC-THREE*EW )TC = COEF5*( EW-THREE*EWC )*CALL DSCAL( NR, BETA, WORK( ILO ), 1 )CALL DSCAL( NR, BETA, WORK( ILO+N ), 1 )*CALL DAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )CALL DAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )*DO 270 I = ILO, IHIWORK( I ) = WORK( I ) + TCWORK( I+N ) = WORK( I+N ) + T270 CONTINUE** Apply matrix to vector*DO 300 I = ILO, IHIKOUNT = 0SUM = ZERODO 290 J = ILO, IHIIF( A( I, J ).EQ.ZERO )$ GO TO 280KOUNT = KOUNT + 1SUM = SUM + WORK( J )280 CONTINUEIF( B( I, J ).EQ.ZERO )$ GO TO 290KOUNT = KOUNT + 1SUM = SUM + WORK( J )290 CONTINUEWORK( I+2*N ) = DBLE( KOUNT )*WORK( I+N ) + SUM300 CONTINUE*DO 330 J = ILO, IHIKOUNT = 0SUM = ZERODO 320 I = ILO, IHIIF( A( I, J ).EQ.ZERO )$ GO TO 310KOUNT = KOUNT + 1SUM = SUM + WORK( I+N )310 CONTINUEIF( B( I, J ).EQ.ZERO )$ GO TO 320KOUNT = KOUNT + 1SUM = SUM + WORK( I+N )320 CONTINUEWORK( J+3*N ) = DBLE( KOUNT )*WORK( J ) + SUM330 CONTINUE*SUM = DDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +$ DDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )ALPHA = GAMMA / SUM** Determine correction to current iteration*CMAX = ZERODO 340 I = ILO, IHICOR = ALPHA*WORK( I+N )IF( ABS( COR ).GT.CMAX )$ CMAX = ABS( COR )LSCALE( I ) = LSCALE( I ) + CORCOR = ALPHA*WORK( I )IF( ABS( COR ).GT.CMAX )$ CMAX = ABS( COR )RSCALE( I ) = RSCALE( I ) + COR340 CONTINUEIF( CMAX.LT.HALF )$ GO TO 350*CALL DAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )CALL DAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )*PGAMMA = GAMMAIT = IT + 1IF( IT.LE.NRP2 )$ GO TO 250** End generalized conjugate gradient iteration*350 CONTINUESFMIN = DLAMCH( 'S' )SFMAX = ONE / SFMINLSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )LSFMAX = INT( LOG10( SFMAX ) / BASL )DO 360 I = ILO, IHIIRAB = IDAMAX( N-ILO+1, A( I, ILO ), LDA )RAB = ABS( A( I, IRAB+ILO-1 ) )IRAB = IDAMAX( N-ILO+1, B( I, ILO ), LDA )RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )LSCALE( I ) = SCLFAC**IRICAB = IDAMAX( IHI, A( 1, I ), 1 )CAB = ABS( A( ICAB, I ) )ICAB = IDAMAX( IHI, B( 1, I ), 1 )CAB = MAX( CAB, ABS( B( ICAB, I ) ) )LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )RSCALE( I ) = SCLFAC**JC360 CONTINUE** Row scaling of matrices A and B*DO 370 I = ILO, IHICALL DSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )CALL DSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )370 CONTINUE** Column scaling of matrices A and B*DO 380 J = ILO, IHICALL DSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )CALL DSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )380 CONTINUE*RETURN** End of DGGBAL*ENDSUBROUTINE DGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,$ LDQ, Z, LDZ, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER COMPQ, COMPZINTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),$ Z( LDZ, * )* ..** Purpose* =======** DGGHRD reduces a pair of real matrices (A,B) to generalized upper* Hessenberg form using orthogonal transformations, where A is a* general matrix and B is upper triangular: Q' * A * Z = H and* Q' * B * Z = T, where H is upper Hessenberg, T is upper triangular,* and Q and Z are orthogonal, and ' means transpose.** The orthogonal matrices Q and Z are determined as products of Givens* rotations. They may either be formed explicitly, or they may be* postmultiplied into input matrices Q1 and Z1, so that** Q1 * A * Z1' = (Q1*Q) * H * (Z1*Z)'* Q1 * B * Z1' = (Q1*Q) * T * (Z1*Z)'** Arguments* =========** COMPQ (input) CHARACTER*1* = 'N': do not compute Q;* = 'I': Q is initialized to the unit matrix, and the* orthogonal matrix Q is returned;* = 'V': Q must contain an orthogonal matrix Q1 on entry,* and the product Q1*Q is returned.** COMPZ (input) CHARACTER*1* = 'N': do not compute Z;* = 'I': Z is initialized to the unit matrix, and the* orthogonal matrix Z is returned;* = 'V': Z must contain an orthogonal matrix Z1 on entry,* and the product Z1*Z is returned.** N (input) INTEGER* The order of the matrices A and B. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* It is assumed that A is already upper triangular in rows and* columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set* by a previous call to DGGBAL; otherwise they should be set* to 1 and N respectively.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** A (input/output) DOUBLE PRECISION array, dimension (LDA, N)* On entry, the N-by-N general matrix to be reduced.* On exit, the upper triangle and the first subdiagonal of A* are overwritten with the upper Hessenberg matrix H, and the* rest is set to zero.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** B (input/output) DOUBLE PRECISION array, dimension (LDB, N)* On entry, the N-by-N upper triangular matrix B.* On exit, the upper triangular matrix T = Q' B Z. The* elements below the diagonal are set to zero.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** Q (input/output) DOUBLE PRECISION array, dimension (LDQ, N)* If COMPQ='N': Q is not referenced.* If COMPQ='I': on entry, Q need not be set, and on exit it* contains the orthogonal matrix Q, where Q'* is the product of the Givens transformations* which are applied to A and B on the left.* If COMPQ='V': on entry, Q must contain an orthogonal matrix* Q1, and on exit this is overwritten by Q1*Q.** LDQ (input) INTEGER* The leading dimension of the array Q.* LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.** Z (input/output) DOUBLE PRECISION array, dimension (LDZ, N)* If COMPZ='N': Z is not referenced.* If COMPZ='I': on entry, Z need not be set, and on exit it* contains the orthogonal matrix Z, which is* the product of the Givens transformations* which are applied to A and B on the right.* If COMPZ='V': on entry, Z must contain an orthogonal matrix* Z1, and on exit this is overwritten by Z1*Z.** LDZ (input) INTEGER* The leading dimension of the array Z.* LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** This routine reduces A to Hessenberg and B to triangular form by* an unblocked reduction, as described in _Matrix_Computations_,* by Golub and Van Loan (Johns Hopkins Press.)** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ILQ, ILZINTEGER ICOMPQ, ICOMPZ, JCOL, JROWDOUBLE PRECISION C, S, TEMP* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARTG, DLASET, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Decode COMPQ*IF( LSAME( COMPQ, 'N' ) ) THENILQ = .FALSE.ICOMPQ = 1ELSE IF( LSAME( COMPQ, 'V' ) ) THENILQ = .TRUE.ICOMPQ = 2ELSE IF( LSAME( COMPQ, 'I' ) ) THENILQ = .TRUE.ICOMPQ = 3ELSEICOMPQ = 0END IF** Decode COMPZ*IF( LSAME( COMPZ, 'N' ) ) THENILZ = .FALSE.ICOMPZ = 1ELSE IF( LSAME( COMPZ, 'V' ) ) THENILZ = .TRUE.ICOMPZ = 2ELSE IF( LSAME( COMPZ, 'I' ) ) THENILZ = .TRUE.ICOMPZ = 3ELSEICOMPZ = 0END IF** Test the input parameters.*INFO = 0IF( ICOMPQ.LE.0 ) THENINFO = -1ELSE IF( ICOMPZ.LE.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 ) THENINFO = -4ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THENINFO = -11ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGHRD', -INFO )RETURNEND IF** Initialize Q and Z if desired.*IF( ICOMPQ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )IF( ICOMPZ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Quick return if possible*IF( N.LE.1 )$ RETURN** Zero out lower triangle of B*DO 20 JCOL = 1, N - 1DO 10 JROW = JCOL + 1, NB( JROW, JCOL ) = ZERO10 CONTINUE20 CONTINUE** Reduce A and B*DO 40 JCOL = ILO, IHI - 2*DO 30 JROW = IHI, JCOL + 2, -1** Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)*TEMP = A( JROW-1, JCOL )CALL DLARTG( TEMP, A( JROW, JCOL ), C, S,$ A( JROW-1, JCOL ) )A( JROW, JCOL ) = ZEROCALL DROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,$ A( JROW, JCOL+1 ), LDA, C, S )CALL DROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,$ B( JROW, JROW-1 ), LDB, C, S )IF( ILQ )$ CALL DROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C, S )** Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)*TEMP = B( JROW, JROW )CALL DLARTG( TEMP, B( JROW, JROW-1 ), C, S,$ B( JROW, JROW ) )B( JROW, JROW-1 ) = ZEROCALL DROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )CALL DROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,$ S )IF( ILZ )$ CALL DROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )30 CONTINUE40 CONTINUE*RETURN** End of DGGHRD*ENDSUBROUTINE DGGQRF( N, M, P, A, LDA, TAUA, B, LDB, TAUB, WORK,$ LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), TAUA( * ), TAUB( * ),$ WORK( * )* ..** Purpose* =======** DGGQRF computes a generalized QR factorization of an N-by-M matrix A* and an N-by-P matrix B:** A = Q*R, B = Q*T*Z,** where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal* matrix, and R and T assume one of the forms:** if N >= M, R = ( R11 ) M , or if N < M, R = ( R11 R12 ) N,* ( 0 ) N-M N M-N* M** where R11 is upper triangular, and** if N <= P, T = ( 0 T12 ) N, or if N > P, T = ( T11 ) N-P,* P-N N ( T21 ) P* P** where T12 or T21 is upper triangular.** In particular, if B is square and nonsingular, the GQR factorization* of A and B implicitly gives the QR factorization of inv(B)*A:** inv(B)*A = Z'*(inv(T)*R)** where inv(B) denotes the inverse of the matrix B, and Z' denotes the* transpose of the matrix Z.** Arguments* =========** N (input) INTEGER* The number of rows of the matrices A and B. N >= 0.** M (input) INTEGER* The number of columns of the matrix A. M >= 0.** P (input) INTEGER* The number of columns of the matrix B. P >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,M)* On entry, the N-by-M matrix A.* On exit, the elements on and above the diagonal of the array* contain the min(N,M)-by-M upper trapezoidal matrix R (R is* upper triangular if N >= M); the elements below the diagonal,* with the array TAUA, represent the orthogonal matrix Q as a* product of min(N,M) elementary reflectors (see Further* Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** TAUA (output) DOUBLE PRECISION array, dimension (min(N,M))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Q (see Further Details).** B (input/output) DOUBLE PRECISION array, dimension (LDB,P)* On entry, the N-by-P matrix B.* On exit, if N <= P, the upper triangle of the subarray* B(1:N,P-N+1:P) contains the N-by-N upper triangular matrix T;* if N > P, the elements on and above the (N-P)-th subdiagonal* contain the N-by-P upper trapezoidal matrix T; the remaining* elements, with the array TAUB, represent the orthogonal* matrix Z as a product of elementary reflectors (see Further* Details).** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** TAUB (output) DOUBLE PRECISION array, dimension (min(N,P))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Z (see Further Details).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N,M,P).* For optimum performance LWORK >= max(N,M,P)*max(NB1,NB2,NB3),* where NB1 is the optimal blocksize for the QR factorization* of an N-by-M matrix, NB2 is the optimal blocksize for the* RQ factorization of an N-by-P matrix, and NB3 is the optimal* blocksize for a call of DORMQR.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(n,m).** Each H(i) has the form** H(i) = I - taua * v * v'** where taua is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),* and taua in TAUA(i).* To form Q explicitly, use LAPACK subroutine DORGQR.* To use Q to update another matrix, use LAPACK subroutine DORMQR.** The matrix Z is represented as a product of elementary reflectors** Z = H(1) H(2) . . . H(k), where k = min(n,p).** Each H(i) has the form** H(i) = I - taub * v * v'** where taub is a real scalar, and v is a real vector with* v(p-k+i+1:p) = 0 and v(p-k+i) = 1; v(1:p-k+i-1) is stored on exit in* B(n-k+i,1:p-k+i-1), and taub in TAUB(i).* To form Z explicitly, use LAPACK subroutine DORGRQ.* To use Z to update another matrix, use LAPACK subroutine DORMRQ.** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER LOPT, LWKOPT, NB, NB1, NB2, NB3* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGERQF, DORMQR, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB1 = ILAENV( 1, 'DGEQRF', ' ', N, M, -1, -1 )NB2 = ILAENV( 1, 'DGERQF', ' ', N, P, -1, -1 )NB3 = ILAENV( 1, 'DORMQR', ' ', N, M, P, -1 )NB = MAX( NB1, NB2, NB3 )LWKOPT = MAX( N, M, P )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( P.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LWORK.LT.MAX( 1, N, M, P ) .AND. .NOT.LQUERY ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGQRF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** QR factorization of N-by-M matrix A: A = Q*R*CALL DGEQRF( N, M, A, LDA, TAUA, WORK, LWORK, INFO )LOPT = WORK( 1 )** Update B := Q'*B.*CALL DORMQR( 'Left', 'Transpose', N, P, MIN( N, M ), A, LDA, TAUA,$ B, LDB, WORK, LWORK, INFO )LOPT = MAX( LOPT, INT( WORK( 1 ) ) )** RQ factorization of N-by-P matrix B: B = T*Z.*CALL DGERQF( N, P, B, LDB, TAUB, WORK, LWORK, INFO )WORK( 1 ) = MAX( LOPT, INT( WORK( 1 ) ) )*RETURN** End of DGGQRF*ENDSUBROUTINE DGGRQF( M, P, N, A, LDA, TAUA, B, LDB, TAUB, WORK,$ LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), TAUA( * ), TAUB( * ),$ WORK( * )* ..** Purpose* =======** DGGRQF computes a generalized RQ factorization of an M-by-N matrix A* and a P-by-N matrix B:** A = R*Q, B = Z*T*Q,** where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal* matrix, and R and T assume one of the forms:** if M <= N, R = ( 0 R12 ) M, or if M > N, R = ( R11 ) M-N,* N-M M ( R21 ) N* N** where R12 or R21 is upper triangular, and** if P >= N, T = ( T11 ) N , or if P < N, T = ( T11 T12 ) P,* ( 0 ) P-N P N-P* N** where T11 is upper triangular.** In particular, if B is square and nonsingular, the GRQ factorization* of A and B implicitly gives the RQ factorization of A*inv(B):** A*inv(B) = (R*inv(T))*Z'** where inv(B) denotes the inverse of the matrix B, and Z' denotes the* transpose of the matrix Z.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** P (input) INTEGER* The number of rows of the matrix B. P >= 0.** N (input) INTEGER* The number of columns of the matrices A and B. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, if M <= N, the upper triangle of the subarray* A(1:M,N-M+1:N) contains the M-by-M upper triangular matrix R;* if M > N, the elements on and above the (M-N)-th subdiagonal* contain the M-by-N upper trapezoidal matrix R; the remaining* elements, with the array TAUA, represent the orthogonal* matrix Q as a product of elementary reflectors (see Further* Details).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAUA (output) DOUBLE PRECISION array, dimension (min(M,N))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Q (see Further Details).** B (input/output) DOUBLE PRECISION array, dimension (LDB,N)* On entry, the P-by-N matrix B.* On exit, the elements on and above the diagonal of the array* contain the min(P,N)-by-N upper trapezoidal matrix T (T is* upper triangular if P >= N); the elements below the diagonal,* with the array TAUB, represent the orthogonal matrix Z as a* product of elementary reflectors (see Further Details).** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,P).** TAUB (output) DOUBLE PRECISION array, dimension (min(P,N))* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Z (see Further Details).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N,M,P).* For optimum performance LWORK >= max(N,M,P)*max(NB1,NB2,NB3),* where NB1 is the optimal blocksize for the RQ factorization* of an M-by-N matrix, NB2 is the optimal blocksize for the* QR factorization of a P-by-N matrix, and NB3 is the optimal* blocksize for a call of DORMRQ.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INF0= -i, the i-th argument had an illegal value.** Further Details* ===============** The matrix Q is represented as a product of elementary reflectors** Q = H(1) H(2) . . . H(k), where k = min(m,n).** Each H(i) has the form** H(i) = I - taua * v * v'** where taua is a real scalar, and v is a real vector with* v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in* A(m-k+i,1:n-k+i-1), and taua in TAUA(i).* To form Q explicitly, use LAPACK subroutine DORGRQ.* To use Q to update another matrix, use LAPACK subroutine DORMRQ.** The matrix Z is represented as a product of elementary reflectors** Z = H(1) H(2) . . . H(k), where k = min(p,n).** Each H(i) has the form** H(i) = I - taub * v * v'** where taub is a real scalar, and v is a real vector with* v(1:i-1) = 0 and v(i) = 1; v(i+1:p) is stored on exit in B(i+1:p,i),* and taub in TAUB(i).* To form Z explicitly, use LAPACK subroutine DORGQR.* To use Z to update another matrix, use LAPACK subroutine DORMQR.** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER LOPT, LWKOPT, NB, NB1, NB2, NB3* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGERQF, DORMRQ, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB1 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )NB2 = ILAENV( 1, 'DGEQRF', ' ', P, N, -1, -1 )NB3 = ILAENV( 1, 'DORMRQ', ' ', M, N, P, -1 )NB = MAX( NB1, NB2, NB3 )LWKOPT = MAX( N, M, P )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( P.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -8ELSE IF( LWORK.LT.MAX( 1, M, P, N ) .AND. .NOT.LQUERY ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGRQF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** RQ factorization of M-by-N matrix A: A = R*Q*CALL DGERQF( M, N, A, LDA, TAUA, WORK, LWORK, INFO )LOPT = WORK( 1 )** Update B := B*Q'*CALL DORMRQ( 'Right', 'Transpose', P, N, MIN( M, N ),$ A( MAX( 1, M-N+1 ), 1 ), LDA, TAUA, B, LDB, WORK,$ LWORK, INFO )LOPT = MAX( LOPT, INT( WORK( 1 ) ) )** QR factorization of P-by-N matrix B: B = Z*T*CALL DGEQRF( P, N, B, LDB, TAUB, WORK, LWORK, INFO )WORK( 1 ) = MAX( LOPT, INT( WORK( 1 ) ) )*RETURN** End of DGGRQF*ENDSUBROUTINE DGGSVP( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,$ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,$ IWORK, TAU, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER JOBQ, JOBU, JOBVINTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, PDOUBLE PRECISION TOLA, TOLB* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),$ TAU( * ), U( LDU, * ), V( LDV, * ), WORK( * )* ..** Purpose* =======** DGGSVP computes orthogonal matrices U, V and Q such that** N-K-L K L* U'*A*Q = K ( 0 A12 A13 ) if M-K-L >= 0;* L ( 0 0 A23 )* M-K-L ( 0 0 0 )** N-K-L K L* = K ( 0 A12 A13 ) if M-K-L < 0;* M-K ( 0 0 A23 )** N-K-L K L* V'*B*Q = L ( 0 0 B13 )* P-L ( 0 0 0 )** where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular* upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0,* otherwise A23 is (M-K)-by-L upper trapezoidal. K+L = the effective* numerical rank of the (M+P)-by-N matrix (A',B')'. Z' denotes the* transpose of Z.** This decomposition is the preprocessing step for computing the* Generalized Singular Value Decomposition (GSVD), see subroutine* DGGSVD.** Arguments* =========** JOBU (input) CHARACTER*1* = 'U': Orthogonal matrix U is computed;* = 'N': U is not computed.** JOBV (input) CHARACTER*1* = 'V': Orthogonal matrix V is computed;* = 'N': V is not computed.** JOBQ (input) CHARACTER*1* = 'Q': Orthogonal matrix Q is computed;* = 'N': Q is not computed.** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** P (input) INTEGER* The number of rows of the matrix B. P >= 0.** N (input) INTEGER* The number of columns of the matrices A and B. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, A contains the triangular (or trapezoidal) matrix* described in the Purpose section.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** B (input/output) DOUBLE PRECISION array, dimension (LDB,N)* On entry, the P-by-N matrix B.* On exit, B contains the triangular matrix described in* the Purpose section.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,P).** TOLA (input) DOUBLE PRECISION* TOLB (input) DOUBLE PRECISION* TOLA and TOLB are the thresholds to determine the effective* numerical rank of matrix B and a subblock of A. Generally,* they are set to* TOLA = MAX(M,N)*norm(A)*MAZHEPS,* TOLB = MAX(P,N)*norm(B)*MAZHEPS.* The size of TOLA and TOLB may affect the size of backward* errors of the decomposition.** K (output) INTEGER* L (output) INTEGER* On exit, K and L specify the dimension of the subblocks* described in Purpose.* K + L = effective numerical rank of (A',B')'.** U (output) DOUBLE PRECISION array, dimension (LDU,M)* If JOBU = 'U', U contains the orthogonal matrix U.* If JOBU = 'N', U is not referenced.** LDU (input) INTEGER* The leading dimension of the array U. LDU >= max(1,M) if* JOBU = 'U'; LDU >= 1 otherwise.** V (output) DOUBLE PRECISION array, dimension (LDV,M)* If JOBV = 'V', V contains the orthogonal matrix V.* If JOBV = 'N', V is not referenced.** LDV (input) INTEGER* The leading dimension of the array V. LDV >= max(1,P) if* JOBV = 'V'; LDV >= 1 otherwise.** Q (output) DOUBLE PRECISION array, dimension (LDQ,N)* If JOBQ = 'Q', Q contains the orthogonal matrix Q.* If JOBQ = 'N', Q is not referenced.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N) if* JOBQ = 'Q'; LDQ >= 1 otherwise.** IWORK (workspace) INTEGER array, dimension (N)** TAU (workspace) DOUBLE PRECISION array, dimension (N)** WORK (workspace) DOUBLE PRECISION array, dimension (max(3*N,M,P))** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.*** Further Details* ===============** The subroutine uses LAPACK subroutine DGEQPF for the QR factorization* with column pivoting to detect the effective numerical rank of the* a matrix. It may be replaced by a better rank determination strategy.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL FORWRD, WANTQ, WANTU, WANTVINTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEQPF, DGEQR2, DGERQ2, DLACPY, DLAPMT, DLASET,$ DORG2R, DORM2R, DORMR2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*WANTU = LSAME( JOBU, 'U' )WANTV = LSAME( JOBV, 'V' )WANTQ = LSAME( JOBQ, 'Q' )FORWRD = .TRUE.*INFO = 0IF( .NOT.( WANTU .OR. LSAME( JOBU, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( WANTV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( P.LT.0 ) THENINFO = -5ELSE IF( N.LT.0 ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -10ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THENINFO = -16ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THENINFO = -18ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -20END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGSVP', -INFO )RETURNEND IF** QR with column pivoting of B: B*P = V*( S11 S12 )* ( 0 0 )*DO 10 I = 1, NIWORK( I ) = 010 CONTINUECALL DGEQPF( P, N, B, LDB, IWORK, TAU, WORK, INFO )** Update A := A*P*CALL DLAPMT( FORWRD, M, N, A, LDA, IWORK )** Determine the effective rank of matrix B.*L = 0DO 20 I = 1, MIN( P, N )IF( ABS( B( I, I ) ).GT.TOLB )$ L = L + 120 CONTINUE*IF( WANTV ) THEN** Copy the details of V, and form V.*CALL DLASET( 'Full', P, P, ZERO, ZERO, V, LDV )IF( P.GT.1 )$ CALL DLACPY( 'Lower', P-1, N, B( 2, 1 ), LDB, V( 2, 1 ),$ LDV )CALL DORG2R( P, P, MIN( P, N ), V, LDV, TAU, WORK, INFO )END IF** Clean up B*DO 40 J = 1, L - 1DO 30 I = J + 1, LB( I, J ) = ZERO30 CONTINUE40 CONTINUEIF( P.GT.L )$ CALL DLASET( 'Full', P-L, N, ZERO, ZERO, B( L+1, 1 ), LDB )*IF( WANTQ ) THEN** Set Q = I and Update Q := Q*P*CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )CALL DLAPMT( FORWRD, N, N, Q, LDQ, IWORK )END IF*IF( P.GE.L .AND. N.NE.L ) THEN** RQ factorization of (S11 S12): ( S11 S12 ) = ( 0 S12 )*Z*CALL DGERQ2( L, N, B, LDB, TAU, WORK, INFO )** Update A := A*Z'*CALL DORMR2( 'Right', 'Transpose', M, N, L, B, LDB, TAU, A,$ LDA, WORK, INFO )*IF( WANTQ ) THEN** Update Q := Q*Z'*CALL DORMR2( 'Right', 'Transpose', N, N, L, B, LDB, TAU, Q,$ LDQ, WORK, INFO )END IF** Clean up B*CALL DLASET( 'Full', L, N-L, ZERO, ZERO, B, LDB )DO 60 J = N - L + 1, NDO 50 I = J - N + L + 1, LB( I, J ) = ZERO50 CONTINUE60 CONTINUE*END IF** Let N-L L* A = ( A11 A12 ) M,** then the following does the complete QR decomposition of A11:** A11 = U*( 0 T12 )*P1'* ( 0 0 )*DO 70 I = 1, N - LIWORK( I ) = 070 CONTINUECALL DGEQPF( M, N-L, A, LDA, IWORK, TAU, WORK, INFO )** Determine the effective rank of A11*K = 0DO 80 I = 1, MIN( M, N-L )IF( ABS( A( I, I ) ).GT.TOLA )$ K = K + 180 CONTINUE** Update A12 := U'*A12, where A12 = A( 1:M, N-L+1:N )*CALL DORM2R( 'Left', 'Transpose', M, L, MIN( M, N-L ), A, LDA,$ TAU, A( 1, N-L+1 ), LDA, WORK, INFO )*IF( WANTU ) THEN** Copy the details of U, and form U*CALL DLASET( 'Full', M, M, ZERO, ZERO, U, LDU )IF( M.GT.1 )$ CALL DLACPY( 'Lower', M-1, N-L, A( 2, 1 ), LDA, U( 2, 1 ),$ LDU )CALL DORG2R( M, M, MIN( M, N-L ), U, LDU, TAU, WORK, INFO )END IF*IF( WANTQ ) THEN** Update Q( 1:N, 1:N-L ) = Q( 1:N, 1:N-L )*P1*CALL DLAPMT( FORWRD, N, N-L, Q, LDQ, IWORK )END IF** Clean up A: set the strictly lower triangular part of* A(1:K, 1:K) = 0, and A( K+1:M, 1:N-L ) = 0.*DO 100 J = 1, K - 1DO 90 I = J + 1, KA( I, J ) = ZERO90 CONTINUE100 CONTINUEIF( M.GT.K )$ CALL DLASET( 'Full', M-K, N-L, ZERO, ZERO, A( K+1, 1 ), LDA )*IF( N-L.GT.K ) THEN** RQ factorization of ( T11 T12 ) = ( 0 T12 )*Z1*CALL DGERQ2( K, N-L, A, LDA, TAU, WORK, INFO )*IF( WANTQ ) THEN** Update Q( 1:N,1:N-L ) = Q( 1:N,1:N-L )*Z1'*CALL DORMR2( 'Right', 'Transpose', N, N-L, K, A, LDA, TAU,$ Q, LDQ, WORK, INFO )END IF** Clean up A*CALL DLASET( 'Full', K, N-L-K, ZERO, ZERO, A, LDA )DO 120 J = N - L - K + 1, N - LDO 110 I = J - N + L + K + 1, KA( I, J ) = ZERO110 CONTINUE120 CONTINUE*END IF*IF( M.GT.K ) THEN** QR factorization of A( K+1:M,N-L+1:N )*CALL DGEQR2( M-K, L, A( K+1, N-L+1 ), LDA, TAU, WORK, INFO )*IF( WANTU ) THEN** Update U(:,K+1:M) := U(:,K+1:M)*U1*CALL DORM2R( 'Right', 'No transpose', M, M-K, MIN( M-K, L ),$ A( K+1, N-L+1 ), LDA, TAU, U( 1, K+1 ), LDU,$ WORK, INFO )END IF** Clean up*DO 140 J = N - L + 1, NDO 130 I = J - N + K + L + 1, MA( I, J ) = ZERO130 CONTINUE140 CONTINUE*END IF*RETURN** End of DGGSVP*ENDSUBROUTINE DGTCON( NORM, N, DL, D, DU, DU2, IPIV, ANORM, RCOND,$ WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER NORMINTEGER INFO, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION D( * ), DL( * ), DU( * ), DU2( * ), WORK( * )* ..** Purpose* =======** DGTCON estimates the reciprocal of the condition number of a real* tridiagonal matrix A using the LU factorization as computed by* DGTTRF.** An estimate is obtained for norm(inv(A)), and the reciprocal of the* condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).** Arguments* =========** NORM (input) CHARACTER*1* Specifies whether the 1-norm condition number or the* infinity-norm condition number is required:* = '1' or 'O': 1-norm;* = 'I': Infinity-norm.** N (input) INTEGER* The order of the matrix A. N >= 0.** DL (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) multipliers that define the matrix L from the* LU factorization of A as computed by DGTTRF.** D (input) DOUBLE PRECISION array, dimension (N)* The n diagonal elements of the upper triangular matrix U from* the LU factorization of A.** DU (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) elements of the first superdiagonal of U.** DU2 (input) DOUBLE PRECISION array, dimension (N-2)* The (n-2) elements of the second superdiagonal of U.** IPIV (input) INTEGER array, dimension (N)* The pivot indices; for 1 <= i <= n, row i of the matrix was* interchanged with row IPIV(i). IPIV(i) will always be either* i or i+1; IPIV(i) = i indicates a row interchange was not* required.** ANORM (input) DOUBLE PRECISION* If NORM = '1' or 'O', the 1-norm of the original matrix A.* If NORM = 'I', the infinity-norm of the original matrix A.** RCOND (output) DOUBLE PRECISION* The reciprocal of the condition number of the matrix A,* computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an* estimate of the 1-norm of inv(A) computed in this routine.** WORK (workspace) DOUBLE PRECISION array, dimension (2*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ONENRMINTEGER I, KASE, KASE1DOUBLE PRECISION AINVNM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGTTRS, DLACON, XERBLA* ..* .. Executable Statements ..** Test the input arguments.*INFO = 0ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ANORM.LT.ZERO ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF** Check that D(1:N) is non-zero.*DO 10 I = 1, NIF( D( I ).EQ.ZERO )$ RETURN10 CONTINUE*AINVNM = ZEROIF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 020 CONTINUECALL DLACON( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(U)*inv(L).*CALL DGTTRS( 'No transpose', N, 1, DL, D, DU, DU2, IPIV,$ WORK, N, INFO )ELSE** Multiply by inv(L')*inv(U').*CALL DGTTRS( 'Transpose', N, 1, DL, D, DU, DU2, IPIV, WORK,$ N, INFO )END IFGO TO 20END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*RETURN** End of DGTCON*ENDSUBROUTINE DGTRFS( TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF, DU2,$ IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),$ DL( * ), DLF( * ), DU( * ), DU2( * ), DUF( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** Purpose* =======** DGTRFS improves the computed solution to a system of linear* equations when the coefficient matrix is tridiagonal, and provides* error bounds and backward error estimates for the solution.** Arguments* =========** TRANS (input) CHARACTER*1* Specifies the form of the system of equations:* = 'N': A * X = B (No transpose)* = 'T': A**T * X = B (Transpose)* = 'C': A**H * X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A. N >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrix B. NRHS >= 0.** DL (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) subdiagonal elements of A.** D (input) DOUBLE PRECISION array, dimension (N)* The diagonal elements of A.** DU (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) superdiagonal elements of A.** DLF (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) multipliers that define the matrix L from the* LU factorization of A as computed by DGTTRF.** DF (input) DOUBLE PRECISION array, dimension (N)* The n diagonal elements of the upper triangular matrix U from* the LU factorization of A.** DUF (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) elements of the first superdiagonal of U.** DU2 (input) DOUBLE PRECISION array, dimension (N-2)* The (n-2) elements of the second superdiagonal of U.** IPIV (input) INTEGER array, dimension (N)* The pivot indices; for 1 <= i <= n, row i of the matrix was* interchanged with row IPIV(i). IPIV(i) will always be either* i or i+1; IPIV(i) = i indicates a row interchange was not* required.** B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)* The right hand side matrix B.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** X (input/output) DOUBLE PRECISION array, dimension (LDX,NRHS)* On entry, the solution matrix X, as computed by DGTTRS.* On exit, the improved solution matrix X.** LDX (input) INTEGER* The leading dimension of the array X. LDX >= max(1,N).** FERR (output) DOUBLE PRECISION array, dimension (NRHS)* The estimated forward error bound for each solution vector* X(j) (the j-th column of the solution matrix X).* If XTRUE is the true solution corresponding to X(j), FERR(j)* is an estimated upper bound for the magnitude of the largest* element in (X(j) - XTRUE) divided by the magnitude of the* largest element in X(j). The estimate is as reliable as* the estimate for RCOND, and is almost always a slight* overestimate of the true error.** BERR (output) DOUBLE PRECISION array, dimension (NRHS)* The componentwise relative backward error of each solution* vector X(j) (i.e., the smallest relative change in* any element of A or B that makes X(j) an exact solution).** WORK (workspace) DOUBLE PRECISION array, dimension (3*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Internal Parameters* ===================** ITMAX is the maximum number of steps of iterative refinement.** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANCHARACTER TRANSN, TRANSTINTEGER COUNT, I, J, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGTTRS, DLACON, DLAGTM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -13ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -15END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANSN = 'N'TRANST = 'T'ELSETRANSN = 'T'TRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = 4EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 110 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - op(A) * X,* where op(A) = A, A**T, or A**H, depending on TRANS.*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DLAGTM( TRANS, N, 1, -ONE, DL, D, DU, X( 1, J ), LDX, ONE,$ WORK( N+1 ), N )** Compute abs(op(A))*abs(x) + abs(b) for use in the backward* error bound.*IF( NOTRAN ) THENIF( N.EQ.1 ) THENWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) )ELSEWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) ) +$ ABS( DU( 1 )*X( 2, J ) )DO 30 I = 2, N - 1WORK( I ) = ABS( B( I, J ) ) +$ ABS( DL( I-1 )*X( I-1, J ) ) +$ ABS( D( I )*X( I, J ) ) +$ ABS( DU( I )*X( I+1, J ) )30 CONTINUEWORK( N ) = ABS( B( N, J ) ) +$ ABS( DL( N-1 )*X( N-1, J ) ) +$ ABS( D( N )*X( N, J ) )END IFELSEIF( N.EQ.1 ) THENWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) )ELSEWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) ) +$ ABS( DL( 1 )*X( 2, J ) )DO 40 I = 2, N - 1WORK( I ) = ABS( B( I, J ) ) +$ ABS( DU( I-1 )*X( I-1, J ) ) +$ ABS( D( I )*X( I, J ) ) +$ ABS( DL( I )*X( I+1, J ) )40 CONTINUEWORK( N ) = ABS( B( N, J ) ) +$ ABS( DU( N-1 )*X( N-1, J ) ) +$ ABS( D( N )*X( N, J ) )END IFEND IF** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*S = ZERODO 50 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF50 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DGTTRS( TRANS, N, 1, DLF, DF, DUF, DU2, IPIV,$ WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACON to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 60 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF60 CONTINUE*KASE = 070 CONTINUECALL DLACON( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DGTTRS( TRANST, N, 1, DLF, DF, DUF, DU2, IPIV,$ WORK( N+1 ), N, INFO )DO 80 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )80 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 90 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )90 CONTINUECALL DGTTRS( TRANSN, N, 1, DLF, DF, DUF, DU2, IPIV,$ WORK( N+1 ), N, INFO )END IFGO TO 70END IF** Normalize error.*LSTRES = ZERODO 100 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )100 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*110 CONTINUE*RETURN** End of DGTRFS*ENDSUBROUTINE DGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments ..INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * )* ..** Purpose* =======** DGTSV solves the equation** A*X = B,** where A is an n by n tridiagonal matrix, by Gaussian elimination with* partial pivoting.** Note that the equation A'*X = B may be solved by interchanging the* order of the arguments DU and DL.** Arguments* =========** N (input) INTEGER* The order of the matrix A. N >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrix B. NRHS >= 0.** DL (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, DL must contain the (n-1) sub-diagonal elements of* A.** On exit, DL is overwritten by the (n-2) elements of the* second super-diagonal of the upper triangular matrix U from* the LU factorization of A, in DL(1), ..., DL(n-2).** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, D must contain the diagonal elements of A.** On exit, D is overwritten by the n diagonal elements of U.** DU (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, DU must contain the (n-1) super-diagonal elements* of A.** On exit, DU is overwritten by the (n-1) elements of the first* super-diagonal of U.** B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)* On entry, the N by NRHS matrix of right hand side matrix B.* On exit, if INFO = 0, the N by NRHS solution matrix X.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, U(i,i) is exactly zero, and the solution* has not been computed. The factorization has not been* completed unless i = N.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION FACT, TEMP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( NRHS.LT.0 ) THENINFO = -2ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTSV ', -INFO )RETURNEND IF*IF( N.EQ.0 )$ RETURN*IF( NRHS.EQ.1 ) THENDO 10 I = 1, N - 2IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN** No row interchange required*IF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )ELSEINFO = IRETURNEND IFDL( I ) = ZEROELSE** Interchange rows I and I+1*FACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDL( I ) = DU( I+1 )DU( I+1 ) = -FACT*DL( I )DU( I ) = TEMPTEMP = B( I, 1 )B( I, 1 ) = B( I+1, 1 )B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )END IF10 CONTINUEIF( N.GT.1 ) THENI = N - 1IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THENIF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )ELSEINFO = IRETURNEND IFELSEFACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDU( I ) = TEMPTEMP = B( I, 1 )B( I, 1 ) = B( I+1, 1 )B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )END IFEND IFIF( D( N ).EQ.ZERO ) THENINFO = NRETURNEND IFELSEDO 40 I = 1, N - 2IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN** No row interchange required*IF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )DO 20 J = 1, NRHSB( I+1, J ) = B( I+1, J ) - FACT*B( I, J )20 CONTINUEELSEINFO = IRETURNEND IFDL( I ) = ZEROELSE** Interchange rows I and I+1*FACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDL( I ) = DU( I+1 )DU( I+1 ) = -FACT*DL( I )DU( I ) = TEMPDO 30 J = 1, NRHSTEMP = B( I, J )B( I, J ) = B( I+1, J )B( I+1, J ) = TEMP - FACT*B( I+1, J )30 CONTINUEEND IF40 CONTINUEIF( N.GT.1 ) THENI = N - 1IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THENIF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )DO 50 J = 1, NRHSB( I+1, J ) = B( I+1, J ) - FACT*B( I, J )50 CONTINUEELSEINFO = IRETURNEND IFELSEFACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDU( I ) = TEMPDO 60 J = 1, NRHSTEMP = B( I, J )B( I, J ) = B( I+1, J )B( I+1, J ) = TEMP - FACT*B( I+1, J )60 CONTINUEEND IFEND IFIF( D( N ).EQ.ZERO ) THENINFO = NRETURNEND IFEND IF** Back solve with the matrix U from the factorization.*IF( NRHS.LE.2 ) THENJ = 170 CONTINUEB( N, J ) = B( N, J ) / D( N )IF( N.GT.1 )$ B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) / D( N-1 )DO 80 I = N - 2, 1, -1B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*$ B( I+2, J ) ) / D( I )80 CONTINUEIF( J.LT.NRHS ) THENJ = J + 1GO TO 70END IFELSEDO 100 J = 1, NRHSB( N, J ) = B( N, J ) / D( N )IF( N.GT.1 )$ B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /$ D( N-1 )DO 90 I = N - 2, 1, -1B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*$ B( I+2, J ) ) / D( I )90 CONTINUE100 CONTINUEEND IF*RETURN** End of DGTSV*ENDSUBROUTINE DGTSVX( FACT, TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF,$ DU2, IPIV, B, LDB, X, LDX, RCOND, FERR, BERR,$ WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER FACT, TRANSINTEGER INFO, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),$ DL( * ), DLF( * ), DU( * ), DU2( * ), DUF( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** Purpose* =======** DGTSVX uses the LU factorization to compute the solution to a real* system of linear equations A * X = B or A**T * X = B,* where A is a tridiagonal matrix of order N and X and B are N-by-NRHS* matrices.** Error bounds on the solution and a condition estimate are also* provided.** Description* ===========** The following steps are performed:** 1. If FACT = 'N', the LU decomposition is used to factor the matrix A* as A = L * U, where L is a product of permutation and unit lower* bidiagonal matrices and U is upper triangular with nonzeros in* only the main diagonal and first two superdiagonals.** 2. If some U(i,i)=0, so that U is exactly singular, then the routine* returns with INFO = i. Otherwise, the factored form of A is used* to estimate the condition number of the matrix A. If the* reciprocal of the condition number is less than machine precision,* INFO = N+1 is returned as a warning, but the routine still goes on* to solve for X and compute error bounds as described below.** 3. The system of equations is solved for X using the factored form* of A.** 4. Iterative refinement is applied to improve the computed solution* matrix and calculate error bounds and backward error estimates* for it.** Arguments* =========** FACT (input) CHARACTER*1* Specifies whether or not the factored form of A has been* supplied on entry.* = 'F': DLF, DF, DUF, DU2, and IPIV contain the factored* form of A; DL, D, DU, DLF, DF, DUF, DU2 and IPIV* will not be modified.* = 'N': The matrix will be copied to DLF, DF, and DUF* and factored.** TRANS (input) CHARACTER*1* Specifies the form of the system of equations:* = 'N': A * X = B (No transpose)* = 'T': A**T * X = B (Transpose)* = 'C': A**H * X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A. N >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrix B. NRHS >= 0.** DL (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) subdiagonal elements of A.** D (input) DOUBLE PRECISION array, dimension (N)* The n diagonal elements of A.** DU (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) superdiagonal elements of A.** DLF (input or output) DOUBLE PRECISION array, dimension (N-1)* If FACT = 'F', then DLF is an input argument and on entry* contains the (n-1) multipliers that define the matrix L from* the LU factorization of A as computed by DGTTRF.** If FACT = 'N', then DLF is an output argument and on exit* contains the (n-1) multipliers that define the matrix L from* the LU factorization of A.** DF (input or output) DOUBLE PRECISION array, dimension (N)* If FACT = 'F', then DF is an input argument and on entry* contains the n diagonal elements of the upper triangular* matrix U from the LU factorization of A.** If FACT = 'N', then DF is an output argument and on exit* contains the n diagonal elements of the upper triangular* matrix U from the LU factorization of A.** DUF (input or output) DOUBLE PRECISION array, dimension (N-1)* If FACT = 'F', then DUF is an input argument and on entry* contains the (n-1) elements of the first superdiagonal of U.** If FACT = 'N', then DUF is an output argument and on exit* contains the (n-1) elements of the first superdiagonal of U.** DU2 (input or output) DOUBLE PRECISION array, dimension (N-2)* If FACT = 'F', then DU2 is an input argument and on entry* contains the (n-2) elements of the second superdiagonal of* U.** If FACT = 'N', then DU2 is an output argument and on exit* contains the (n-2) elements of the second superdiagonal of* U.** IPIV (input or output) INTEGER array, dimension (N)* If FACT = 'F', then IPIV is an input argument and on entry* contains the pivot indices from the LU factorization of A as* computed by DGTTRF.** If FACT = 'N', then IPIV is an output argument and on exit* contains the pivot indices from the LU factorization of A;* row i of the matrix was interchanged with row IPIV(i).* IPIV(i) will always be either i or i+1; IPIV(i) = i indicates* a row interchange was not required.** B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)* The N-by-NRHS right hand side matrix B.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)* If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X.** LDX (input) INTEGER* The leading dimension of the array X. LDX >= max(1,N).** RCOND (output) DOUBLE PRECISION* The estimate of the reciprocal condition number of the matrix* A. If RCOND is less than the machine precision (in* particular, if RCOND = 0), the matrix is singular to working* precision. This condition is indicated by a return code of* INFO > 0.** FERR (output) DOUBLE PRECISION array, dimension (NRHS)* The estimated forward error bound for each solution vector* X(j) (the j-th column of the solution matrix X).* If XTRUE is the true solution corresponding to X(j), FERR(j)* is an estimated upper bound for the magnitude of the largest* element in (X(j) - XTRUE) divided by the magnitude of the* largest element in X(j). The estimate is as reliable as* the estimate for RCOND, and is almost always a slight* overestimate of the true error.** BERR (output) DOUBLE PRECISION array, dimension (NRHS)* The componentwise relative backward error of each solution* vector X(j) (i.e., the smallest relative change in* any element of A or B that makes X(j) an exact solution).** WORK (workspace) DOUBLE PRECISION array, dimension (3*N)** IWORK (workspace) INTEGER array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, and i is* <= N: U(i,i) is exactly zero. The factorization* has not been completed unless i = N, but the* factor U is exactly singular, so the solution* and error bounds could not be computed.* RCOND = 0 is returned.* = N+1: U is nonsingular, but RCOND is less than machine* precision, meaning that the matrix is singular* to working precision. Nevertheless, the* solution and error bounds are computed because* there are a number of situations where the* computed solution can be more accurate than the* value of RCOND would suggest.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOFACT, NOTRANCHARACTER NORMDOUBLE PRECISION ANORM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANGTEXTERNAL LSAME, DLAMCH, DLANGT* ..* .. External Subroutines ..EXTERNAL DCOPY, DGTCON, DGTRFS, DGTTRF, DGTTRS, DLACPY,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -16END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTSVX', -INFO )RETURNEND IF*IF( NOFACT ) THEN** Compute the LU factorization of A.*CALL DCOPY( N, D, 1, DF, 1 )IF( N.GT.1 ) THENCALL DCOPY( N-1, DL, 1, DLF, 1 )CALL DCOPY( N-1, DU, 1, DUF, 1 )END IFCALL DGTTRF( N, DLF, DF, DUF, DU2, IPIV, INFO )** Return if INFO is non-zero.*IF( INFO.NE.0 ) THENIF( INFO.GT.0 )$ RCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*IF( NOTRAN ) THENNORM = '1'ELSENORM = 'I'END IFANORM = DLANGT( NORM, N, DL, D, DU )** Compute the reciprocal of the condition number of A.*CALL DGTCON( NORM, N, DLF, DF, DUF, DU2, IPIV, ANORM, RCOND, WORK,$ IWORK, INFO )** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1** Compute the solution vectors X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DGTTRS( TRANS, N, NRHS, DLF, DF, DUF, DU2, IPIV, X, LDX,$ INFO )** Use iterative refinement to improve the computed solutions and* compute error bounds and backward error estimates for them.*CALL DGTRFS( TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF, DU2, IPIV,$ B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )*RETURN** End of DGTSVX*ENDSUBROUTINE DGTTRF( N, DL, D, DU, DU2, IPIV, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION D( * ), DL( * ), DU( * ), DU2( * )* ..** Purpose* =======** DGTTRF computes an LU factorization of a real tridiagonal matrix A* using elimination with partial pivoting and row interchanges.** The factorization has the form* A = L * U* where L is a product of permutation and unit lower bidiagonal* matrices and U is upper triangular with nonzeros in only the main* diagonal and first two superdiagonals.** Arguments* =========** N (input) INTEGER* The order of the matrix A.** DL (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, DL must contain the (n-1) sub-diagonal elements of* A.** On exit, DL is overwritten by the (n-1) multipliers that* define the matrix L from the LU factorization of A.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, D must contain the diagonal elements of A.** On exit, D is overwritten by the n diagonal elements of the* upper triangular matrix U from the LU factorization of A.** DU (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, DU must contain the (n-1) super-diagonal elements* of A.** On exit, DU is overwritten by the (n-1) elements of the first* super-diagonal of U.** DU2 (output) DOUBLE PRECISION array, dimension (N-2)* On exit, DU2 is overwritten by the (n-2) elements of the* second super-diagonal of U.** IPIV (output) INTEGER array, dimension (N)* The pivot indices; for 1 <= i <= n, row i of the matrix was* interchanged with row IPIV(i). IPIV(i) will always be either* i or i+1; IPIV(i) = i indicates a row interchange was not* required.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -k, the k-th argument had an illegal value* > 0: if INFO = k, U(k,k) is exactly zero. The factorization* has been completed, but the factor U is exactly* singular, and division by zero will occur if it is used* to solve a system of equations.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION FACT, TEMP* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DGTTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Initialize IPIV(i) = i and DU2(I) = 0*DO 10 I = 1, NIPIV( I ) = I10 CONTINUEDO 20 I = 1, N - 2DU2( I ) = ZERO20 CONTINUE*DO 30 I = 1, N - 2IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN** No row interchange required, eliminate DL(I)*IF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )DL( I ) = FACTD( I+1 ) = D( I+1 ) - FACT*DU( I )END IFELSE** Interchange rows I and I+1, eliminate DL(I)*FACT = D( I ) / DL( I )D( I ) = DL( I )DL( I ) = FACTTEMP = DU( I )DU( I ) = D( I+1 )D( I+1 ) = TEMP - FACT*D( I+1 )DU2( I ) = DU( I+1 )DU( I+1 ) = -FACT*DU( I+1 )IPIV( I ) = I + 1END IF30 CONTINUEIF( N.GT.1 ) THENI = N - 1IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THENIF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )DL( I ) = FACTD( I+1 ) = D( I+1 ) - FACT*DU( I )END IFELSEFACT = D( I ) / DL( I )D( I ) = DL( I )DL( I ) = FACTTEMP = DU( I )DU( I ) = D( I+1 )D( I+1 ) = TEMP - FACT*D( I+1 )IPIV( I ) = I + 1END IFEND IF** Check for a zero on the diagonal of U.*DO 40 I = 1, NIF( D( I ).EQ.ZERO ) THENINFO = IGO TO 50END IF40 CONTINUE50 CONTINUE*RETURN** End of DGTTRF*ENDSUBROUTINE DGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )* ..** Purpose* =======** DGTTRS solves one of the systems of equations* A*X = B or A'*X = B,* with a tridiagonal matrix A using the LU factorization computed* by DGTTRF.** Arguments* =========** TRANS (input) CHARACTER* Specifies the form of the system of equations.* = 'N': A * X = B (No transpose)* = 'T': A'* X = B (Transpose)* = 'C': A'* X = B (Conjugate transpose = Transpose)** N (input) INTEGER* The order of the matrix A.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrix B. NRHS >= 0.** DL (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) multipliers that define the matrix L from the* LU factorization of A.** D (input) DOUBLE PRECISION array, dimension (N)* The n diagonal elements of the upper triangular matrix U from* the LU factorization of A.** DU (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) elements of the first super-diagonal of U.** DU2 (input) DOUBLE PRECISION array, dimension (N-2)* The (n-2) elements of the second super-diagonal of U.** IPIV (input) INTEGER array, dimension (N)* The pivot indices; for 1 <= i <= n, row i of the matrix was* interchanged with row IPIV(i). IPIV(i) will always be either* i or i+1; IPIV(i) = i indicates a row interchange was not* required.** B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)* On entry, the matrix of right hand side vectors B.* On exit, B is overwritten by the solution vectors X.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Local Scalars ..LOGICAL NOTRANINTEGER ITRANS, J, JB, NB* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. External Subroutines ..EXTERNAL DGTTS2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOTRAN = ( TRANS.EQ.'N' .OR. TRANS.EQ.'n' )IF( .NOT.NOTRAN .AND. .NOT.( TRANS.EQ.'T' .OR. TRANS.EQ.$ 't' ) .AND. .NOT.( TRANS.EQ.'C' .OR. TRANS.EQ.'c' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( N, 1 ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN** Decode TRANS*IF( NOTRAN ) THENITRANS = 0ELSEITRANS = 1END IF** Determine the number of right-hand sides to solve at a time.*IF( NRHS.EQ.1 ) THENNB = 1ELSENB = MAX( 1, ILAENV( 1, 'DGTTRS', TRANS, N, NRHS, -1, -1 ) )END IF*IF( NB.GE.NRHS ) THENCALL DGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )ELSEDO 10 J = 1, NRHS, NBJB = MIN( NRHS-J+1, NB )CALL DGTTS2( ITRANS, N, JB, DL, D, DU, DU2, IPIV, B( 1, J ),$ LDB )10 CONTINUEEND IF** End of DGTTRS*ENDSUBROUTINE DHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,$ LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER COMPQ, COMPZ, JOBINTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), Q( LDQ, * ), WORK( * ),$ Z( LDZ, * )* ..** Purpose* =======** DHGEQZ implements a single-/double-shift version of the QZ method for* finding the generalized eigenvalues** w(j)=(ALPHAR(j) + i*ALPHAI(j))/BETAR(j) of the equation** det( A - w(i) B ) = 0** In addition, the pair A,B may be reduced to generalized Schur form:* B is upper triangular, and A is block upper triangular, where the* diagonal blocks are either 1-by-1 or 2-by-2, the 2-by-2 blocks having* complex generalized eigenvalues (see the description of the argument* JOB.)** If JOB='S', then the pair (A,B) is simultaneously reduced to Schur* form by applying one orthogonal tranformation (usually called Q) on* the left and another (usually called Z) on the right. The 2-by-2* upper-triangular diagonal blocks of B corresponding to 2-by-2 blocks* of A will be reduced to positive diagonal matrices. (I.e.,* if A(j+1,j) is non-zero, then B(j+1,j)=B(j,j+1)=0 and B(j,j) and* B(j+1,j+1) will be positive.)** If JOB='E', then at each iteration, the same transformations* are computed, but they are only applied to those parts of A and B* which are needed to compute ALPHAR, ALPHAI, and BETAR.** If JOB='S' and COMPQ and COMPZ are 'V' or 'I', then the orthogonal* transformations used to reduce (A,B) are accumulated into the arrays* Q and Z s.t.:** Q(in) A(in) Z(in)* = Q(out) A(out) Z(out)** Q(in) B(in) Z(in)* = Q(out) B(out) Z(out)*** Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix* Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),* pp. 241--256.** Arguments* =========** JOB (input) CHARACTER*1* = 'E': compute only ALPHAR, ALPHAI, and BETA. A and B will* not necessarily be put into generalized Schur form.* = 'S': put A and B into generalized Schur form, as well* as computing ALPHAR, ALPHAI, and BETA.** COMPQ (input) CHARACTER*1* = 'N': do not modify Q.* = 'V': multiply the array Q on the right by the transpose of* the orthogonal tranformation that is applied to the* left side of A and B to reduce them to Schur form.* = 'I': like COMPQ='V', except that Q will be initialized to* the identity first.** COMPZ (input) CHARACTER*1* = 'N': do not modify Z.* = 'V': multiply the array Z on the right by the orthogonal* tranformation that is applied to the right side of* A and B to reduce them to Schur form.* = 'I': like COMPZ='V', except that Z will be initialized to* the identity first.** N (input) INTEGER* The order of the matrices A, B, Q, and Z. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* It is assumed that A is already upper triangular in rows and* columns 1:ILO-1 and IHI+1:N.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** A (input/output) DOUBLE PRECISION array, dimension (LDA, N)* On entry, the N-by-N upper Hessenberg matrix A. Elements* below the subdiagonal must be zero.* If JOB='S', then on exit A and B will have been* simultaneously reduced to generalized Schur form.* If JOB='E', then on exit A will have been destroyed.* The diagonal blocks will be correct, but the off-diagonal* portion will be meaningless.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max( 1, N ).** B (input/output) DOUBLE PRECISION array, dimension (LDB, N)* On entry, the N-by-N upper triangular matrix B. Elements* below the diagonal must be zero. 2-by-2 blocks in B* corresponding to 2-by-2 blocks in A will be reduced to* positive diagonal form. (I.e., if A(j+1,j) is non-zero,* then B(j+1,j)=B(j,j+1)=0 and B(j,j) and B(j+1,j+1) will be* positive.)* If JOB='S', then on exit A and B will have been* simultaneously reduced to Schur form.* If JOB='E', then on exit B will have been destroyed.* Elements corresponding to diagonal blocks of A will be* correct, but the off-diagonal portion will be meaningless.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max( 1, N ).** ALPHAR (output) DOUBLE PRECISION array, dimension (N)* ALPHAR(1:N) will be set to real parts of the diagonal* elements of A that would result from reducing A and B to* Schur form and then further reducing them both to triangular* form using unitary transformations s.t. the diagonal of B* was non-negative real. Thus, if A(j,j) is in a 1-by-1 block* (i.e., A(j+1,j)=A(j,j+1)=0), then ALPHAR(j)=A(j,j).* Note that the (real or complex) values* (ALPHAR(j) + i*ALPHAI(j))/BETA(j), j=1,...,N, are the* generalized eigenvalues of the matrix pencil A - wB.** ALPHAI (output) DOUBLE PRECISION array, dimension (N)* ALPHAI(1:N) will be set to imaginary parts of the diagonal* elements of A that would result from reducing A and B to* Schur form and then further reducing them both to triangular* form using unitary transformations s.t. the diagonal of B* was non-negative real. Thus, if A(j,j) is in a 1-by-1 block* (i.e., A(j+1,j)=A(j,j+1)=0), then ALPHAR(j)=0.* Note that the (real or complex) values* (ALPHAR(j) + i*ALPHAI(j))/BETA(j), j=1,...,N, are the* generalized eigenvalues of the matrix pencil A - wB.** BETA (output) DOUBLE PRECISION array, dimension (N)* BETA(1:N) will be set to the (real) diagonal elements of B* that would result from reducing A and B to Schur form and* then further reducing them both to triangular form using* unitary transformations s.t. the diagonal of B was* non-negative real. Thus, if A(j,j) is in a 1-by-1 block* (i.e., A(j+1,j)=A(j,j+1)=0), then BETA(j)=B(j,j).* Note that the (real or complex) values* (ALPHAR(j) + i*ALPHAI(j))/BETA(j), j=1,...,N, are the* generalized eigenvalues of the matrix pencil A - wB.* (Note that BETA(1:N) will always be non-negative, and no* BETAI is necessary.)** Q (input/output) DOUBLE PRECISION array, dimension (LDQ, N)* If COMPQ='N', then Q will not be referenced.* If COMPQ='V' or 'I', then the transpose of the orthogonal* transformations which are applied to A and B on the left* will be applied to the array Q on the right.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= 1.* If COMPQ='V' or 'I', then LDQ >= N.** Z (input/output) DOUBLE PRECISION array, dimension (LDZ, N)* If COMPZ='N', then Z will not be referenced.* If COMPZ='V' or 'I', then the orthogonal transformations* which are applied to A and B on the right will be applied* to the array Z on the right.** LDZ (input) INTEGER* The leading dimension of the array Z. LDZ >= 1.* If COMPZ='V' or 'I', then LDZ >= N.** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N).** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* = 1,...,N: the QZ iteration did not converge. (A,B) is not* in Schur form, but ALPHAR(i), ALPHAI(i), and* BETA(i), i=INFO+1,...,N should be correct.* = N+1,...,2*N: the shift calculation failed. (A,B) is not* in Schur form, but ALPHAR(i), ALPHAI(i), and* BETA(i), i=INFO-N+1,...,N should be correct.* > 2*N: various "impossible" errors.** Further Details* ===============** Iteration counters:** JITER -- counts iterations.* IITER -- counts iterations run since ILAST was last* changed. This is therefore reset only when a 1-by-1 or* 2-by-2 block deflates off the bottom.** =====================================================================** .. Parameters ..* $ SAFETY = 1.0E+0 )DOUBLE PRECISION HALF, ZERO, ONE, SAFETYPARAMETER ( HALF = 0.5D+0, ZERO = 0.0D+0, ONE = 1.0D+0,$ SAFETY = 1.0D+2 )* ..* .. Local Scalars ..LOGICAL ILAZR2, ILAZRO, ILPIVT, ILQ, ILSCHR, ILZ,$ LQUERYINTEGER ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,$ ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,$ JR, MAXITDOUBLE PRECISION A11, A12, A1I, A1R, A21, A22, A2I, A2R, AD11,$ AD11L, AD12, AD12L, AD21, AD21L, AD22, AD22L,$ AD32L, AN, ANORM, ASCALE, ATOL, B11, B1A, B1I,$ B1R, B22, B2A, B2I, B2R, BN, BNORM, BSCALE,$ BTOL, C, C11I, C11R, C12, C21, C22I, C22R, CL,$ CQ, CR, CZ, ESHIFT, S, S1, S1INV, S2, SAFMAX,$ SAFMIN, SCALE, SL, SQI, SQR, SR, SZI, SZR, T,$ TAU, TEMP, TEMP2, TEMPI, TEMPR, U1, U12, U12L,$ U2, ULP, VS, W11, W12, W21, W22, WABS, WI, WR,$ WR2* ..* .. Local Arrays ..DOUBLE PRECISION V( 3 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANHS, DLAPY2, DLAPY3EXTERNAL LSAME, DLAMCH, DLANHS, DLAPY2, DLAPY3* ..* .. External Subroutines ..EXTERNAL DLAG2, DLARFG, DLARTG, DLASET, DLASV2, DROT,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SQRT* ..* .. Executable Statements ..** Decode JOB, COMPQ, COMPZ*IF( LSAME( JOB, 'E' ) ) THENILSCHR = .FALSE.ISCHUR = 1ELSE IF( LSAME( JOB, 'S' ) ) THENILSCHR = .TRUE.ISCHUR = 2ELSEISCHUR = 0END IF*IF( LSAME( COMPQ, 'N' ) ) THENILQ = .FALSE.ICOMPQ = 1ELSE IF( LSAME( COMPQ, 'V' ) ) THENILQ = .TRUE.ICOMPQ = 2ELSE IF( LSAME( COMPQ, 'I' ) ) THENILQ = .TRUE.ICOMPQ = 3ELSEICOMPQ = 0END IF*IF( LSAME( COMPZ, 'N' ) ) THENILZ = .FALSE.ICOMPZ = 1ELSE IF( LSAME( COMPZ, 'V' ) ) THENILZ = .TRUE.ICOMPZ = 2ELSE IF( LSAME( COMPZ, 'I' ) ) THENILZ = .TRUE.ICOMPZ = 3ELSEICOMPZ = 0END IF** Check Argument Values*INFO = 0WORK( 1 ) = MAX( 1, N )LQUERY = ( LWORK.EQ.-1 )IF( ISCHUR.EQ.0 ) THENINFO = -1ELSE IF( ICOMPQ.EQ.0 ) THENINFO = -2ELSE IF( ICOMPZ.EQ.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( ILO.LT.1 ) THENINFO = -5ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THENINFO = -6ELSE IF( LDA.LT.N ) THENINFO = -8ELSE IF( LDB.LT.N ) THENINFO = -10ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THENINFO = -15ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THENINFO = -17ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -19END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DHGEQZ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.0 ) THENWORK( 1 ) = DBLE( 1 )RETURNEND IF** Initialize Q and Z*IF( ICOMPQ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )IF( ICOMPZ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Machine Constants*IN = IHI + 1 - ILOSAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINULP = DLAMCH( 'E' )*DLAMCH( 'B' )ANORM = DLANHS( 'F', IN, A( ILO, ILO ), LDA, WORK )BNORM = DLANHS( 'F', IN, B( ILO, ILO ), LDB, WORK )ATOL = MAX( SAFMIN, ULP*ANORM )BTOL = MAX( SAFMIN, ULP*BNORM )ASCALE = ONE / MAX( SAFMIN, ANORM )BSCALE = ONE / MAX( SAFMIN, BNORM )** Set Eigenvalues IHI+1:N*DO 30 J = IHI + 1, NIF( B( J, J ).LT.ZERO ) THENIF( ILSCHR ) THENDO 10 JR = 1, JA( JR, J ) = -A( JR, J )B( JR, J ) = -B( JR, J )10 CONTINUEELSEA( J, J ) = -A( J, J )B( J, J ) = -B( J, J )END IFIF( ILZ ) THENDO 20 JR = 1, NZ( JR, J ) = -Z( JR, J )20 CONTINUEEND IFEND IFALPHAR( J ) = A( J, J )ALPHAI( J ) = ZEROBETA( J ) = B( J, J )30 CONTINUE** If IHI < ILO, skip QZ steps*IF( IHI.LT.ILO )$ GO TO 380** MAIN QZ ITERATION LOOP** Initialize dynamic indices** Eigenvalues ILAST+1:N have been found.* Column operations modify rows IFRSTM:whatever.* Row operations modify columns whatever:ILASTM.** If only eigenvalues are being computed, then* IFRSTM is the row of the last splitting row above row ILAST;* this is always at least ILO.* IITER counts iterations since the last eigenvalue was found,* to tell when to use an extraordinary shift.* MAXIT is the maximum number of QZ sweeps allowed.*ILAST = IHIIF( ILSCHR ) THENIFRSTM = 1ILASTM = NELSEIFRSTM = ILOILASTM = IHIEND IFIITER = 0ESHIFT = ZEROMAXIT = 30*( IHI-ILO+1 )*DO 360 JITER = 1, MAXIT** Split the matrix if possible.** Two tests:* 1: A(j,j-1)=0 or j=ILO* 2: B(j,j)=0*IF( ILAST.EQ.ILO ) THEN** Special case: j=ILAST*GO TO 80ELSEIF( ABS( A( ILAST, ILAST-1 ) ).LE.ATOL ) THENA( ILAST, ILAST-1 ) = ZEROGO TO 80END IFEND IF*IF( ABS( B( ILAST, ILAST ) ).LE.BTOL ) THENB( ILAST, ILAST ) = ZEROGO TO 70END IF** General case: j<ILAST*DO 60 J = ILAST - 1, ILO, -1** Test 1: for A(j,j-1)=0 or j=ILO*IF( J.EQ.ILO ) THENILAZRO = .TRUE.ELSEIF( ABS( A( J, J-1 ) ).LE.ATOL ) THENA( J, J-1 ) = ZEROILAZRO = .TRUE.ELSEILAZRO = .FALSE.END IFEND IF** Test 2: for B(j,j)=0*IF( ABS( B( J, J ) ).LT.BTOL ) THENB( J, J ) = ZERO** Test 1a: Check for 2 consecutive small subdiagonals in A*ILAZR2 = .FALSE.IF( .NOT.ILAZRO ) THENTEMP = ABS( A( J, J-1 ) )TEMP2 = ABS( A( J, J ) )TEMPR = MAX( TEMP, TEMP2 )IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THENTEMP = TEMP / TEMPRTEMP2 = TEMP2 / TEMPREND IFIF( TEMP*( ASCALE*ABS( A( J+1, J ) ) ).LE.TEMP2*$ ( ASCALE*ATOL ) )ILAZR2 = .TRUE.END IF** If both tests pass (1 & 2), i.e., the leading diagonal* element of B in the block is zero, split a 1x1 block off* at the top. (I.e., at the J-th row/column) The leading* diagonal element of the remainder can also be zero, so* this may have to be done repeatedly.*IF( ILAZRO .OR. ILAZR2 ) THENDO 40 JCH = J, ILAST - 1TEMP = A( JCH, JCH )CALL DLARTG( TEMP, A( JCH+1, JCH ), C, S,$ A( JCH, JCH ) )A( JCH+1, JCH ) = ZEROCALL DROT( ILASTM-JCH, A( JCH, JCH+1 ), LDA,$ A( JCH+1, JCH+1 ), LDA, C, S )CALL DROT( ILASTM-JCH, B( JCH, JCH+1 ), LDB,$ B( JCH+1, JCH+1 ), LDB, C, S )IF( ILQ )$ CALL DROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,$ C, S )IF( ILAZR2 )$ A( JCH, JCH-1 ) = A( JCH, JCH-1 )*CILAZR2 = .FALSE.IF( ABS( B( JCH+1, JCH+1 ) ).GE.BTOL ) THENIF( JCH+1.GE.ILAST ) THENGO TO 80ELSEIFIRST = JCH + 1GO TO 110END IFEND IFB( JCH+1, JCH+1 ) = ZERO40 CONTINUEGO TO 70ELSE** Only test 2 passed -- chase the zero to B(ILAST,ILAST)* Then process as in the case B(ILAST,ILAST)=0*DO 50 JCH = J, ILAST - 1TEMP = B( JCH, JCH+1 )CALL DLARTG( TEMP, B( JCH+1, JCH+1 ), C, S,$ B( JCH, JCH+1 ) )B( JCH+1, JCH+1 ) = ZEROIF( JCH.LT.ILASTM-1 )$ CALL DROT( ILASTM-JCH-1, B( JCH, JCH+2 ), LDB,$ B( JCH+1, JCH+2 ), LDB, C, S )CALL DROT( ILASTM-JCH+2, A( JCH, JCH-1 ), LDA,$ A( JCH+1, JCH-1 ), LDA, C, S )IF( ILQ )$ CALL DROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,$ C, S )TEMP = A( JCH+1, JCH )CALL DLARTG( TEMP, A( JCH+1, JCH-1 ), C, S,$ A( JCH+1, JCH ) )A( JCH+1, JCH-1 ) = ZEROCALL DROT( JCH+1-IFRSTM, A( IFRSTM, JCH ), 1,$ A( IFRSTM, JCH-1 ), 1, C, S )CALL DROT( JCH-IFRSTM, B( IFRSTM, JCH ), 1,$ B( IFRSTM, JCH-1 ), 1, C, S )IF( ILZ )$ CALL DROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,$ C, S )50 CONTINUEGO TO 70END IFELSE IF( ILAZRO ) THEN** Only test 1 passed -- work on J:ILAST*IFIRST = JGO TO 110END IF** Neither test passed -- try next J*60 CONTINUE** (Drop-through is "impossible")*INFO = N + 1GO TO 420** B(ILAST,ILAST)=0 -- clear A(ILAST,ILAST-1) to split off a* 1x1 block.*70 CONTINUETEMP = A( ILAST, ILAST )CALL DLARTG( TEMP, A( ILAST, ILAST-1 ), C, S,$ A( ILAST, ILAST ) )A( ILAST, ILAST-1 ) = ZEROCALL DROT( ILAST-IFRSTM, A( IFRSTM, ILAST ), 1,$ A( IFRSTM, ILAST-1 ), 1, C, S )CALL DROT( ILAST-IFRSTM, B( IFRSTM, ILAST ), 1,$ B( IFRSTM, ILAST-1 ), 1, C, S )IF( ILZ )$ CALL DROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )** A(ILAST,ILAST-1)=0 -- Standardize B, set ALPHAR, ALPHAI,* and BETA*80 CONTINUEIF( B( ILAST, ILAST ).LT.ZERO ) THENIF( ILSCHR ) THENDO 90 J = IFRSTM, ILASTA( J, ILAST ) = -A( J, ILAST )B( J, ILAST ) = -B( J, ILAST )90 CONTINUEELSEA( ILAST, ILAST ) = -A( ILAST, ILAST )B( ILAST, ILAST ) = -B( ILAST, ILAST )END IFIF( ILZ ) THENDO 100 J = 1, NZ( J, ILAST ) = -Z( J, ILAST )100 CONTINUEEND IFEND IFALPHAR( ILAST ) = A( ILAST, ILAST )ALPHAI( ILAST ) = ZEROBETA( ILAST ) = B( ILAST, ILAST )** Go to next block -- exit if finished.*ILAST = ILAST - 1IF( ILAST.LT.ILO )$ GO TO 380** Reset counters*IITER = 0ESHIFT = ZEROIF( .NOT.ILSCHR ) THENILASTM = ILASTIF( IFRSTM.GT.ILAST )$ IFRSTM = ILOEND IFGO TO 350** QZ step** This iteration only involves rows/columns IFIRST:ILAST. We* assume IFIRST < ILAST, and that the diagonal of B is non-zero.*110 CONTINUEIITER = IITER + 1IF( .NOT.ILSCHR ) THENIFRSTM = IFIRSTEND IF** Compute single shifts.** At this point, IFIRST < ILAST, and the diagonal elements of* B(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in* magnitude)*IF( ( IITER / 10 )*10.EQ.IITER ) THEN** Exceptional shift. Chosen for no particularly good reason.* (Single shift only.)*IF( ( DBLE( MAXIT )*SAFMIN )*ABS( A( ILAST-1, ILAST ) ).LT.$ ABS( B( ILAST-1, ILAST-1 ) ) ) THENESHIFT = ESHIFT + A( ILAST-1, ILAST ) /$ B( ILAST-1, ILAST-1 )ELSEESHIFT = ESHIFT + ONE / ( SAFMIN*DBLE( MAXIT ) )END IFS1 = ONEWR = ESHIFT*ELSE** Shifts based on the generalized eigenvalues of the* bottom-right 2x2 block of A and B. The first eigenvalue* returned by DLAG2 is the Wilkinson shift (AEP p.512),*CALL DLAG2( A( ILAST-1, ILAST-1 ), LDA,$ B( ILAST-1, ILAST-1 ), LDB, SAFMIN*SAFETY, S1,$ S2, WR, WR2, WI )*TEMP = MAX( S1, SAFMIN*MAX( ONE, ABS( WR ), ABS( WI ) ) )IF( WI.NE.ZERO )$ GO TO 200END IF** Fiddle with shift to avoid overflow*TEMP = MIN( ASCALE, ONE )*( HALF*SAFMAX )IF( S1.GT.TEMP ) THENSCALE = TEMP / S1ELSESCALE = ONEEND IF*TEMP = MIN( BSCALE, ONE )*( HALF*SAFMAX )IF( ABS( WR ).GT.TEMP )$ SCALE = MIN( SCALE, TEMP / ABS( WR ) )S1 = SCALE*S1WR = SCALE*WR** Now check for two consecutive small subdiagonals.*DO 120 J = ILAST - 1, IFIRST + 1, -1ISTART = JTEMP = ABS( S1*A( J, J-1 ) )TEMP2 = ABS( S1*A( J, J )-WR*B( J, J ) )TEMPR = MAX( TEMP, TEMP2 )IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THENTEMP = TEMP / TEMPRTEMP2 = TEMP2 / TEMPREND IFIF( ABS( ( ASCALE*A( J+1, J ) )*TEMP ).LE.( ASCALE*ATOL )*$ TEMP2 )GO TO 130120 CONTINUE*ISTART = IFIRST130 CONTINUE** Do an implicit single-shift QZ sweep.** Initial Q*TEMP = S1*A( ISTART, ISTART ) - WR*B( ISTART, ISTART )TEMP2 = S1*A( ISTART+1, ISTART )CALL DLARTG( TEMP, TEMP2, C, S, TEMPR )** Sweep*DO 190 J = ISTART, ILAST - 1IF( J.GT.ISTART ) THENTEMP = A( J, J-1 )CALL DLARTG( TEMP, A( J+1, J-1 ), C, S, A( J, J-1 ) )A( J+1, J-1 ) = ZEROEND IF*DO 140 JC = J, ILASTMTEMP = C*A( J, JC ) + S*A( J+1, JC )A( J+1, JC ) = -S*A( J, JC ) + C*A( J+1, JC )A( J, JC ) = TEMPTEMP2 = C*B( J, JC ) + S*B( J+1, JC )B( J+1, JC ) = -S*B( J, JC ) + C*B( J+1, JC )B( J, JC ) = TEMP2140 CONTINUEIF( ILQ ) THENDO 150 JR = 1, NTEMP = C*Q( JR, J ) + S*Q( JR, J+1 )Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )Q( JR, J ) = TEMP150 CONTINUEEND IF*TEMP = B( J+1, J+1 )CALL DLARTG( TEMP, B( J+1, J ), C, S, B( J+1, J+1 ) )B( J+1, J ) = ZERO*DO 160 JR = IFRSTM, MIN( J+2, ILAST )TEMP = C*A( JR, J+1 ) + S*A( JR, J )A( JR, J ) = -S*A( JR, J+1 ) + C*A( JR, J )A( JR, J+1 ) = TEMP160 CONTINUEDO 170 JR = IFRSTM, JTEMP = C*B( JR, J+1 ) + S*B( JR, J )B( JR, J ) = -S*B( JR, J+1 ) + C*B( JR, J )B( JR, J+1 ) = TEMP170 CONTINUEIF( ILZ ) THENDO 180 JR = 1, NTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )Z( JR, J+1 ) = TEMP180 CONTINUEEND IF190 CONTINUE*GO TO 350** Use Francis double-shift** Note: the Francis double-shift should work with real shifts,* but only if the block is at least 3x3.* This code may break if this point is reached with* a 2x2 block with real eigenvalues.*200 CONTINUEIF( IFIRST+1.EQ.ILAST ) THEN** Special case -- 2x2 block with complex eigenvectors** Step 1: Standardize, that is, rotate so that** ( B11 0 )* B = ( ) with B11 non-negative.* ( 0 B22 )*CALL DLASV2( B( ILAST-1, ILAST-1 ), B( ILAST-1, ILAST ),$ B( ILAST, ILAST ), B22, B11, SR, CR, SL, CL )*IF( B11.LT.ZERO ) THENCR = -CRSR = -SRB11 = -B11B22 = -B22END IF*CALL DROT( ILASTM+1-IFIRST, A( ILAST-1, ILAST-1 ), LDA,$ A( ILAST, ILAST-1 ), LDA, CL, SL )CALL DROT( ILAST+1-IFRSTM, A( IFRSTM, ILAST-1 ), 1,$ A( IFRSTM, ILAST ), 1, CR, SR )*IF( ILAST.LT.ILASTM )$ CALL DROT( ILASTM-ILAST, B( ILAST-1, ILAST+1 ), LDB,$ B( ILAST, ILAST+1 ), LDA, CL, SL )IF( IFRSTM.LT.ILAST-1 )$ CALL DROT( IFIRST-IFRSTM, B( IFRSTM, ILAST-1 ), 1,$ B( IFRSTM, ILAST ), 1, CR, SR )*IF( ILQ )$ CALL DROT( N, Q( 1, ILAST-1 ), 1, Q( 1, ILAST ), 1, CL,$ SL )IF( ILZ )$ CALL DROT( N, Z( 1, ILAST-1 ), 1, Z( 1, ILAST ), 1, CR,$ SR )*B( ILAST-1, ILAST-1 ) = B11B( ILAST-1, ILAST ) = ZEROB( ILAST, ILAST-1 ) = ZEROB( ILAST, ILAST ) = B22** If B22 is negative, negate column ILAST*IF( B22.LT.ZERO ) THENDO 210 J = IFRSTM, ILASTA( J, ILAST ) = -A( J, ILAST )B( J, ILAST ) = -B( J, ILAST )210 CONTINUE*IF( ILZ ) THENDO 220 J = 1, NZ( J, ILAST ) = -Z( J, ILAST )220 CONTINUEEND IFEND IF** Step 2: Compute ALPHAR, ALPHAI, and BETA (see refs.)** Recompute shift*CALL DLAG2( A( ILAST-1, ILAST-1 ), LDA,$ B( ILAST-1, ILAST-1 ), LDB, SAFMIN*SAFETY, S1,$ TEMP, WR, TEMP2, WI )** If standardization has perturbed the shift onto real line,* do another (real single-shift) QR step.*IF( WI.EQ.ZERO )$ GO TO 350S1INV = ONE / S1** Do EISPACK (QZVAL) computation of alpha and beta*A11 = A( ILAST-1, ILAST-1 )A21 = A( ILAST, ILAST-1 )A12 = A( ILAST-1, ILAST )A22 = A( ILAST, ILAST )** Compute complex Givens rotation on right* (Assume some element of C = (sA - wB) > unfl )* __* (sA - wB) ( CZ -SZ )* ( SZ CZ )*C11R = S1*A11 - WR*B11C11I = -WI*B11C12 = S1*A12C21 = S1*A21C22R = S1*A22 - WR*B22C22I = -WI*B22*IF( ABS( C11R )+ABS( C11I )+ABS( C12 ).GT.ABS( C21 )+$ ABS( C22R )+ABS( C22I ) ) THENT = DLAPY3( C12, C11R, C11I )CZ = C12 / TSZR = -C11R / TSZI = -C11I / TELSECZ = DLAPY2( C22R, C22I )IF( CZ.LE.SAFMIN ) THENCZ = ZEROSZR = ONESZI = ZEROELSETEMPR = C22R / CZTEMPI = C22I / CZT = DLAPY2( CZ, C21 )CZ = CZ / TSZR = -C21*TEMPR / TSZI = C21*TEMPI / TEND IFEND IF** Compute Givens rotation on left** ( CQ SQ )* ( __ ) A or B* ( -SQ CQ )*AN = ABS( A11 ) + ABS( A12 ) + ABS( A21 ) + ABS( A22 )BN = ABS( B11 ) + ABS( B22 )WABS = ABS( WR ) + ABS( WI )IF( S1*AN.GT.WABS*BN ) THENCQ = CZ*B11SQR = SZR*B22SQI = -SZI*B22ELSEA1R = CZ*A11 + SZR*A12A1I = SZI*A12A2R = CZ*A21 + SZR*A22A2I = SZI*A22CQ = DLAPY2( A1R, A1I )IF( CQ.LE.SAFMIN ) THENCQ = ZEROSQR = ONESQI = ZEROELSETEMPR = A1R / CQTEMPI = A1I / CQSQR = TEMPR*A2R + TEMPI*A2ISQI = TEMPI*A2R - TEMPR*A2IEND IFEND IFT = DLAPY3( CQ, SQR, SQI )CQ = CQ / TSQR = SQR / TSQI = SQI / T** Compute diagonal elements of QBZ*TEMPR = SQR*SZR - SQI*SZITEMPI = SQR*SZI + SQI*SZRB1R = CQ*CZ*B11 + TEMPR*B22B1I = TEMPI*B22B1A = DLAPY2( B1R, B1I )B2R = CQ*CZ*B22 + TEMPR*B11B2I = -TEMPI*B11B2A = DLAPY2( B2R, B2I )** Normalize so beta > 0, and Im( alpha1 ) > 0*BETA( ILAST-1 ) = B1ABETA( ILAST ) = B2AALPHAR( ILAST-1 ) = ( WR*B1A )*S1INVALPHAI( ILAST-1 ) = ( WI*B1A )*S1INVALPHAR( ILAST ) = ( WR*B2A )*S1INVALPHAI( ILAST ) = -( WI*B2A )*S1INV** Step 3: Go to next block -- exit if finished.*ILAST = IFIRST - 1IF( ILAST.LT.ILO )$ GO TO 380** Reset counters*IITER = 0ESHIFT = ZEROIF( .NOT.ILSCHR ) THENILASTM = ILASTIF( IFRSTM.GT.ILAST )$ IFRSTM = ILOEND IFGO TO 350ELSE** Usual case: 3x3 or larger block, using Francis implicit* double-shift** 2* Eigenvalue equation is w - c w + d = 0,** -1 2 -1* so compute 1st column of (A B ) - c A B + d* using the formula in QZIT (from EISPACK)** We assume that the block is at least 3x3*AD11 = ( ASCALE*A( ILAST-1, ILAST-1 ) ) /$ ( BSCALE*B( ILAST-1, ILAST-1 ) )AD21 = ( ASCALE*A( ILAST, ILAST-1 ) ) /$ ( BSCALE*B( ILAST-1, ILAST-1 ) )AD12 = ( ASCALE*A( ILAST-1, ILAST ) ) /$ ( BSCALE*B( ILAST, ILAST ) )AD22 = ( ASCALE*A( ILAST, ILAST ) ) /$ ( BSCALE*B( ILAST, ILAST ) )U12 = B( ILAST-1, ILAST ) / B( ILAST, ILAST )AD11L = ( ASCALE*A( IFIRST, IFIRST ) ) /$ ( BSCALE*B( IFIRST, IFIRST ) )AD21L = ( ASCALE*A( IFIRST+1, IFIRST ) ) /$ ( BSCALE*B( IFIRST, IFIRST ) )AD12L = ( ASCALE*A( IFIRST, IFIRST+1 ) ) /$ ( BSCALE*B( IFIRST+1, IFIRST+1 ) )AD22L = ( ASCALE*A( IFIRST+1, IFIRST+1 ) ) /$ ( BSCALE*B( IFIRST+1, IFIRST+1 ) )AD32L = ( ASCALE*A( IFIRST+2, IFIRST+1 ) ) /$ ( BSCALE*B( IFIRST+1, IFIRST+1 ) )U12L = B( IFIRST, IFIRST+1 ) / B( IFIRST+1, IFIRST+1 )*V( 1 ) = ( AD11-AD11L )*( AD22-AD11L ) - AD12*AD21 +$ AD21*U12*AD11L + ( AD12L-AD11L*U12L )*AD21LV( 2 ) = ( ( AD22L-AD11L )-AD21L*U12L-( AD11-AD11L )-$ ( AD22-AD11L )+AD21*U12 )*AD21LV( 3 ) = AD32L*AD21L*ISTART = IFIRST*CALL DLARFG( 3, V( 1 ), V( 2 ), 1, TAU )V( 1 ) = ONE** Sweep*DO 290 J = ISTART, ILAST - 2** All but last elements: use 3x3 Householder transforms.** Zero (j-1)st column of A*IF( J.GT.ISTART ) THENV( 1 ) = A( J, J-1 )V( 2 ) = A( J+1, J-1 )V( 3 ) = A( J+2, J-1 )*CALL DLARFG( 3, A( J, J-1 ), V( 2 ), 1, TAU )V( 1 ) = ONEA( J+1, J-1 ) = ZEROA( J+2, J-1 ) = ZEROEND IF*DO 230 JC = J, ILASTMTEMP = TAU*( A( J, JC )+V( 2 )*A( J+1, JC )+V( 3 )*$ A( J+2, JC ) )A( J, JC ) = A( J, JC ) - TEMPA( J+1, JC ) = A( J+1, JC ) - TEMP*V( 2 )A( J+2, JC ) = A( J+2, JC ) - TEMP*V( 3 )TEMP2 = TAU*( B( J, JC )+V( 2 )*B( J+1, JC )+V( 3 )*$ B( J+2, JC ) )B( J, JC ) = B( J, JC ) - TEMP2B( J+1, JC ) = B( J+1, JC ) - TEMP2*V( 2 )B( J+2, JC ) = B( J+2, JC ) - TEMP2*V( 3 )230 CONTINUEIF( ILQ ) THENDO 240 JR = 1, NTEMP = TAU*( Q( JR, J )+V( 2 )*Q( JR, J+1 )+V( 3 )*$ Q( JR, J+2 ) )Q( JR, J ) = Q( JR, J ) - TEMPQ( JR, J+1 ) = Q( JR, J+1 ) - TEMP*V( 2 )Q( JR, J+2 ) = Q( JR, J+2 ) - TEMP*V( 3 )240 CONTINUEEND IF** Zero j-th column of B (see DLAGBC for details)** Swap rows to pivot*ILPIVT = .FALSE.TEMP = MAX( ABS( B( J+1, J+1 ) ), ABS( B( J+1, J+2 ) ) )TEMP2 = MAX( ABS( B( J+2, J+1 ) ), ABS( B( J+2, J+2 ) ) )IF( MAX( TEMP, TEMP2 ).LT.SAFMIN ) THENSCALE = ZEROU1 = ONEU2 = ZEROGO TO 250ELSE IF( TEMP.GE.TEMP2 ) THENW11 = B( J+1, J+1 )W21 = B( J+2, J+1 )W12 = B( J+1, J+2 )W22 = B( J+2, J+2 )U1 = B( J+1, J )U2 = B( J+2, J )ELSEW21 = B( J+1, J+1 )W11 = B( J+2, J+1 )W22 = B( J+1, J+2 )W12 = B( J+2, J+2 )U2 = B( J+1, J )U1 = B( J+2, J )END IF** Swap columns if nec.*IF( ABS( W12 ).GT.ABS( W11 ) ) THENILPIVT = .TRUE.TEMP = W12TEMP2 = W22W12 = W11W22 = W21W11 = TEMPW21 = TEMP2END IF** LU-factor*TEMP = W21 / W11U2 = U2 - TEMP*U1W22 = W22 - TEMP*W12W21 = ZERO** Compute SCALE*SCALE = ONEIF( ABS( W22 ).LT.SAFMIN ) THENSCALE = ZEROU2 = ONEU1 = -W12 / W11GO TO 250END IFIF( ABS( W22 ).LT.ABS( U2 ) )$ SCALE = ABS( W22 / U2 )IF( ABS( W11 ).LT.ABS( U1 ) )$ SCALE = MIN( SCALE, ABS( W11 / U1 ) )** Solve*U2 = ( SCALE*U2 ) / W22U1 = ( SCALE*U1-W12*U2 ) / W11*250 CONTINUEIF( ILPIVT ) THENTEMP = U2U2 = U1U1 = TEMPEND IF** Compute Householder Vector*T = SQRT( SCALE**2+U1**2+U2**2 )TAU = ONE + SCALE / TVS = -ONE / ( SCALE+T )V( 1 ) = ONEV( 2 ) = VS*U1V( 3 ) = VS*U2** Apply transformations from the right.*DO 260 JR = IFRSTM, MIN( J+3, ILAST )TEMP = TAU*( A( JR, J )+V( 2 )*A( JR, J+1 )+V( 3 )*$ A( JR, J+2 ) )A( JR, J ) = A( JR, J ) - TEMPA( JR, J+1 ) = A( JR, J+1 ) - TEMP*V( 2 )A( JR, J+2 ) = A( JR, J+2 ) - TEMP*V( 3 )260 CONTINUEDO 270 JR = IFRSTM, J + 2TEMP = TAU*( B( JR, J )+V( 2 )*B( JR, J+1 )+V( 3 )*$ B( JR, J+2 ) )B( JR, J ) = B( JR, J ) - TEMPB( JR, J+1 ) = B( JR, J+1 ) - TEMP*V( 2 )B( JR, J+2 ) = B( JR, J+2 ) - TEMP*V( 3 )270 CONTINUEIF( ILZ ) THENDO 280 JR = 1, NTEMP = TAU*( Z( JR, J )+V( 2 )*Z( JR, J+1 )+V( 3 )*$ Z( JR, J+2 ) )Z( JR, J ) = Z( JR, J ) - TEMPZ( JR, J+1 ) = Z( JR, J+1 ) - TEMP*V( 2 )Z( JR, J+2 ) = Z( JR, J+2 ) - TEMP*V( 3 )280 CONTINUEEND IFB( J+1, J ) = ZEROB( J+2, J ) = ZERO290 CONTINUE** Last elements: Use Givens rotations** Rotations from the left*J = ILAST - 1TEMP = A( J, J-1 )CALL DLARTG( TEMP, A( J+1, J-1 ), C, S, A( J, J-1 ) )A( J+1, J-1 ) = ZERO*DO 300 JC = J, ILASTMTEMP = C*A( J, JC ) + S*A( J+1, JC )A( J+1, JC ) = -S*A( J, JC ) + C*A( J+1, JC )A( J, JC ) = TEMPTEMP2 = C*B( J, JC ) + S*B( J+1, JC )B( J+1, JC ) = -S*B( J, JC ) + C*B( J+1, JC )B( J, JC ) = TEMP2300 CONTINUEIF( ILQ ) THENDO 310 JR = 1, NTEMP = C*Q( JR, J ) + S*Q( JR, J+1 )Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )Q( JR, J ) = TEMP310 CONTINUEEND IF** Rotations from the right.*TEMP = B( J+1, J+1 )CALL DLARTG( TEMP, B( J+1, J ), C, S, B( J+1, J+1 ) )B( J+1, J ) = ZERO*DO 320 JR = IFRSTM, ILASTTEMP = C*A( JR, J+1 ) + S*A( JR, J )A( JR, J ) = -S*A( JR, J+1 ) + C*A( JR, J )A( JR, J+1 ) = TEMP320 CONTINUEDO 330 JR = IFRSTM, ILAST - 1TEMP = C*B( JR, J+1 ) + S*B( JR, J )B( JR, J ) = -S*B( JR, J+1 ) + C*B( JR, J )B( JR, J+1 ) = TEMP330 CONTINUEIF( ILZ ) THENDO 340 JR = 1, NTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )Z( JR, J+1 ) = TEMP340 CONTINUEEND IF** End of Double-Shift code*END IF*GO TO 350** End of iteration loop*350 CONTINUE360 CONTINUE** Drop-through = non-convergence*370 CONTINUEINFO = ILASTGO TO 420** Successful completion of all QZ steps*380 CONTINUE** Set Eigenvalues 1:ILO-1*DO 410 J = 1, ILO - 1IF( B( J, J ).LT.ZERO ) THENIF( ILSCHR ) THENDO 390 JR = 1, JA( JR, J ) = -A( JR, J )B( JR, J ) = -B( JR, J )390 CONTINUEELSEA( J, J ) = -A( J, J )B( J, J ) = -B( J, J )END IFIF( ILZ ) THENDO 400 JR = 1, NZ( JR, J ) = -Z( JR, J )400 CONTINUEEND IFEND IFALPHAR( J ) = A( J, J )ALPHAI( J ) = ZEROBETA( J ) = B( J, J )410 CONTINUE** Normal Termination*INFO = 0** Exit (other than argument error) -- return optimal workspace size*420 CONTINUEWORK( 1 ) = DBLE( N )RETURN** End of DHGEQZ*ENDSUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI,$ VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL,$ IFAILR, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER EIGSRC, INITV, SIDEINTEGER INFO, LDH, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IFAILL( * ), IFAILR( * )DOUBLE PRECISION H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ),$ WI( * ), WORK( * ), WR( * )* ..** Purpose* =======** DHSEIN uses inverse iteration to find specified right and/or left* eigenvectors of a real upper Hessenberg matrix H.** The right eigenvector x and the left eigenvector y of the matrix H* corresponding to an eigenvalue w are defined by:** H * x = w * x, y**h * H = w * y**h** where y**h denotes the conjugate transpose of the vector y.** Arguments* =========** SIDE (input) CHARACTER*1* = 'R': compute right eigenvectors only;* = 'L': compute left eigenvectors only;* = 'B': compute both right and left eigenvectors.** EIGSRC (input) CHARACTER*1* Specifies the source of eigenvalues supplied in (WR,WI):* = 'Q': the eigenvalues were found using DHSEQR; thus, if* H has zero subdiagonal elements, and so is* block-triangular, then the j-th eigenvalue can be* assumed to be an eigenvalue of the block containing* the j-th row/column. This property allows DHSEIN to* perform inverse iteration on just one diagonal block.* = 'N': no assumptions are made on the correspondence* between eigenvalues and diagonal blocks. In this* case, DHSEIN must always perform inverse iteration* using the whole matrix H.** INITV (input) CHARACTER*1* = 'N': no initial vectors are supplied;* = 'U': user-supplied initial vectors are stored in the arrays* VL and/or VR.** SELECT (input/output) LOGICAL array, dimension (N)* Specifies the eigenvectors to be computed. To select the* real eigenvector corresponding to a real eigenvalue WR(j),* SELECT(j) must be set to .TRUE.. To select the complex* eigenvector corresponding to a complex eigenvalue* (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)),* either SELECT(j) or SELECT(j+1) or both must be set to* .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is* .FALSE..** N (input) INTEGER* The order of the matrix H. N >= 0.** H (input) DOUBLE PRECISION array, dimension (LDH,N)* The upper Hessenberg matrix H.** LDH (input) INTEGER* The leading dimension of the array H. LDH >= max(1,N).** WR (input/output) DOUBLE PRECISION array, dimension (N)* WI (input) DOUBLE PRECISION array, dimension (N)* On entry, the real and imaginary parts of the eigenvalues of* H; a complex conjugate pair of eigenvalues must be stored in* consecutive elements of WR and WI.* On exit, WR may have been altered since close eigenvalues* are perturbed slightly in searching for independent* eigenvectors.** VL (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)* On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must* contain starting vectors for the inverse iteration for the* left eigenvectors; the starting vector for each eigenvector* must be in the same column(s) in which the eigenvector will* be stored.* On exit, if SIDE = 'L' or 'B', the left eigenvectors* specified by SELECT will be stored consecutively in the* columns of VL, in the same order as their eigenvalues. A* complex eigenvector corresponding to a complex eigenvalue is* stored in two consecutive columns, the first holding the real* part and the second the imaginary part.* If SIDE = 'R', VL is not referenced.** LDVL (input) INTEGER* The leading dimension of the array VL.* LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.** VR (input/output) DOUBLE PRECISION array, dimension (LDVR,MM)* On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must* contain starting vectors for the inverse iteration for the* right eigenvectors; the starting vector for each eigenvector* must be in the same column(s) in which the eigenvector will* be stored.* On exit, if SIDE = 'R' or 'B', the right eigenvectors* specified by SELECT will be stored consecutively in the* columns of VR, in the same order as their eigenvalues. A* complex eigenvector corresponding to a complex eigenvalue is* stored in two consecutive columns, the first holding the real* part and the second the imaginary part.* If SIDE = 'L', VR is not referenced.** LDVR (input) INTEGER* The leading dimension of the array VR.* LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.** MM (input) INTEGER* The number of columns in the arrays VL and/or VR. MM >= M.** M (output) INTEGER* The number of columns in the arrays VL and/or VR required to* store the eigenvectors; each selected real eigenvector* occupies one column and each selected complex eigenvector* occupies two columns.** WORK (workspace) DOUBLE PRECISION array, dimension ((N+2)*N)** IFAILL (output) INTEGER array, dimension (MM)* If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left* eigenvector in the i-th column of VL (corresponding to the* eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the* eigenvector converged satisfactorily. If the i-th and (i+1)th* columns of VL hold a complex eigenvector, then IFAILL(i) and* IFAILL(i+1) are set to the same value.* If SIDE = 'R', IFAILL is not referenced.** IFAILR (output) INTEGER array, dimension (MM)* If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right* eigenvector in the i-th column of VR (corresponding to the* eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the* eigenvector converged satisfactorily. If the i-th and (i+1)th* columns of VR hold a complex eigenvector, then IFAILR(i) and* IFAILR(i+1) are set to the same value.* If SIDE = 'L', IFAILR is not referenced.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, i is the number of eigenvectors which* failed to converge; see IFAILL and IFAILR for further* details.** Further Details* ===============** Each eigenvector is normalized so that the element of largest* magnitude has magnitude 1; here the magnitude of a complex number* (x,y) is taken to be |x|+|y|.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL BOTHV, FROMQR, LEFTV, NOINIT, PAIR, RIGHTVINTEGER I, IINFO, K, KL, KLN, KR, KSI, KSR, LDWORKDOUBLE PRECISION BIGNUM, EPS3, HNORM, SMLNUM, ULP, UNFL, WKI,$ WKR* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANHSEXTERNAL LSAME, DLAMCH, DLANHS* ..* .. External Subroutines ..EXTERNAL DLAEIN, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Decode and test the input parameters.*BOTHV = LSAME( SIDE, 'B' )RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHVLEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV*FROMQR = LSAME( EIGSRC, 'Q' )*NOINIT = LSAME( INITV, 'N' )** Set M to the number of columns required to store the selected* eigenvectors, and standardize the array SELECT.*M = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.SELECT( K ) = .FALSE.ELSEIF( WI( K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) ) THENSELECT( K ) = .TRUE.M = M + 2END IFEND IFEND IF10 CONTINUE*INFO = 0IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -1ELSE IF( .NOT.FROMQR .AND. .NOT.LSAME( EIGSRC, 'N' ) ) THENINFO = -2ELSE IF( .NOT.NOINIT .AND. .NOT.LSAME( INITV, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDH.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THENINFO = -11ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THENINFO = -13ELSE IF( MM.LT.M ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DHSEIN', -INFO )RETURNEND IF** Quick return if possible.*IF( N.EQ.0 )$ RETURN** Set machine-dependent constants.*UNFL = DLAMCH( 'Safe minimum' )ULP = DLAMCH( 'Precision' )SMLNUM = UNFL*( N / ULP )BIGNUM = ( ONE-ULP ) / SMLNUM*LDWORK = N + 1*KL = 1KLN = 0IF( FROMQR ) THENKR = 0ELSEKR = NEND IFKSR = 1*DO 120 K = 1, NIF( SELECT( K ) ) THEN** Compute eigenvector(s) corresponding to W(K).*IF( FROMQR ) THEN** If affiliation of eigenvalues is known, check whether* the matrix splits.** Determine KL and KR such that 1 <= KL <= K <= KR <= N* and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or* KR = N).** Then inverse iteration can be performed with the* submatrix H(KL:N,KL:N) for a left eigenvector, and with* the submatrix H(1:KR,1:KR) for a right eigenvector.*DO 20 I = K, KL + 1, -1IF( H( I, I-1 ).EQ.ZERO )$ GO TO 3020 CONTINUE30 CONTINUEKL = IIF( K.GT.KR ) THENDO 40 I = K, N - 1IF( H( I+1, I ).EQ.ZERO )$ GO TO 5040 CONTINUE50 CONTINUEKR = IEND IFEND IF*IF( KL.NE.KLN ) THENKLN = KL** Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it* has not ben computed before.*HNORM = DLANHS( 'I', KR-KL+1, H( KL, KL ), LDH, WORK )IF( HNORM.GT.ZERO ) THENEPS3 = HNORM*ULPELSEEPS3 = SMLNUMEND IFEND IF** Perturb eigenvalue if it is close to any previous* selected eigenvalues affiliated to the submatrix* H(KL:KR,KL:KR). Close roots are modified by EPS3.*WKR = WR( K )WKI = WI( K )60 CONTINUEDO 70 I = K - 1, KL, -1IF( SELECT( I ) .AND. ABS( WR( I )-WKR )+$ ABS( WI( I )-WKI ).LT.EPS3 ) THENWKR = WKR + EPS3GO TO 60END IF70 CONTINUEWR( K ) = WKR*PAIR = WKI.NE.ZEROIF( PAIR ) THENKSI = KSR + 1ELSEKSI = KSREND IFIF( LEFTV ) THEN** Compute left eigenvector.*CALL DLAEIN( .FALSE., NOINIT, N-KL+1, H( KL, KL ), LDH,$ WKR, WKI, VL( KL, KSR ), VL( KL, KSI ),$ WORK, LDWORK, WORK( N*N+N+1 ), EPS3, SMLNUM,$ BIGNUM, IINFO )IF( IINFO.GT.0 ) THENIF( PAIR ) THENINFO = INFO + 2ELSEINFO = INFO + 1END IFIFAILL( KSR ) = KIFAILL( KSI ) = KELSEIFAILL( KSR ) = 0IFAILL( KSI ) = 0END IFDO 80 I = 1, KL - 1VL( I, KSR ) = ZERO80 CONTINUEIF( PAIR ) THENDO 90 I = 1, KL - 1VL( I, KSI ) = ZERO90 CONTINUEEND IFEND IFIF( RIGHTV ) THEN** Compute right eigenvector.*CALL DLAEIN( .TRUE., NOINIT, KR, H, LDH, WKR, WKI,$ VR( 1, KSR ), VR( 1, KSI ), WORK, LDWORK,$ WORK( N*N+N+1 ), EPS3, SMLNUM, BIGNUM,$ IINFO )IF( IINFO.GT.0 ) THENIF( PAIR ) THENINFO = INFO + 2ELSEINFO = INFO + 1END IFIFAILR( KSR ) = KIFAILR( KSI ) = KELSEIFAILR( KSR ) = 0IFAILR( KSI ) = 0END IFDO 100 I = KR + 1, NVR( I, KSR ) = ZERO100 CONTINUEIF( PAIR ) THENDO 110 I = KR + 1, NVR( I, KSI ) = ZERO110 CONTINUEEND IFEND IF*IF( PAIR ) THENKSR = KSR + 2ELSEKSR = KSR + 1END IFEND IF120 CONTINUE*RETURN** End of DHSEIN*ENDSUBROUTINE DHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,$ LDZ, WORK, LWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER COMPZ, JOBINTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),$ Z( LDZ, * )* ..** Purpose* =======** DHSEQR computes the eigenvalues of a real upper Hessenberg matrix H* and, optionally, the matrices T and Z from the Schur decomposition* H = Z T Z**T, where T is an upper quasi-triangular matrix (the Schur* form), and Z is the orthogonal matrix of Schur vectors.** Optionally Z may be postmultiplied into an input orthogonal matrix Q,* so that this routine can give the Schur factorization of a matrix A* which has been reduced to the Hessenberg form H by the orthogonal* matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T.** Arguments* =========** JOB (input) CHARACTER*1* = 'E': compute eigenvalues only;* = 'S': compute eigenvalues and the Schur form T.** COMPZ (input) CHARACTER*1* = 'N': no Schur vectors are computed;* = 'I': Z is initialized to the unit matrix and the matrix Z* of Schur vectors of H is returned;* = 'V': Z must contain an orthogonal matrix Q on entry, and* the product Q*Z is returned.** N (input) INTEGER* The order of the matrix H. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* It is assumed that H is already upper triangular in rows* and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally* set by a previous call to DGEBAL, and then passed to SGEHRD* when the matrix output by DGEBAL is reduced to Hessenberg* form. Otherwise ILO and IHI should be set to 1 and N* respectively.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** H (input/output) DOUBLE PRECISION array, dimension (LDH,N)* On entry, the upper Hessenberg matrix H.* On exit, if JOB = 'S', H contains the upper quasi-triangular* matrix T from the Schur decomposition (the Schur form);* 2-by-2 diagonal blocks (corresponding to complex conjugate* pairs of eigenvalues) are returned in standard form, with* H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0. If JOB = 'E',* the contents of H are unspecified on exit.** LDH (input) INTEGER* The leading dimension of the array H. LDH >= max(1,N).** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* The real and imaginary parts, respectively, of the computed* eigenvalues. If two eigenvalues are computed as a complex* conjugate pair, they are stored in consecutive elements of* WR and WI, say the i-th and (i+1)th, with WI(i) > 0 and* WI(i+1) < 0. If JOB = 'S', the eigenvalues are stored in the* same order as on the diagonal of the Schur form returned in* H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2* diagonal block, WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and* WI(i+1) = -WI(i).** Z (input/output) DOUBLE PRECISION array, dimension (LDZ,N)* If COMPZ = 'N': Z is not referenced.* If COMPZ = 'I': on entry, Z need not be set, and on exit, Z* contains the orthogonal matrix Z of the Schur vectors of H.* If COMPZ = 'V': on entry Z must contain an N-by-N matrix Q,* which is assumed to be equal to the unit matrix except for* the submatrix Z(ILO:IHI,ILO:IHI); on exit Z contains Q*Z.* Normally Q is the orthogonal matrix generated by DORGHR after* the call to DGEHRD which formed the Hessenberg matrix H.** LDZ (input) INTEGER* The leading dimension of the array Z.* LDZ >= max(1,N) if COMPZ = 'I' or 'V'; LDZ >= 1 otherwise.** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N).** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, DHSEQR failed to compute all of the* eigenvalues in a total of 30*(IHI-ILO+1) iterations;* elements 1:ilo-1 and i+1:n of WR and WI contain those* eigenvalues which have been successfully computed.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )DOUBLE PRECISION CONSTPARAMETER ( CONST = 1.5D+0 )INTEGER NSMAX, LDSPARAMETER ( NSMAX = 15, LDS = NSMAX )* ..* .. Local Scalars ..LOGICAL INITZ, LQUERY, WANTT, WANTZINTEGER I, I1, I2, IERR, II, ITEMP, ITN, ITS, J, K, L,$ MAXB, NH, NR, NS, NVDOUBLE PRECISION ABSW, OVFL, SMLNUM, TAU, TEMP, TST1, ULP, UNFL* ..* .. Local Arrays ..DOUBLE PRECISION S( LDS, NSMAX ), V( NSMAX+1 ), VV( NSMAX+1 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAX, ILAENVDOUBLE PRECISION DLAMCH, DLANHS, DLAPY2EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANHS, DLAPY2* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DLACPY, DLAHQR, DLARFG, DLARFX,$ DLASET, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Decode and test the input parameters*WANTT = LSAME( JOB, 'S' )INITZ = LSAME( COMPZ, 'I' )WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )*INFO = 0WORK( 1 ) = MAX( 1, N )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THENINFO = -1ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -4ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -5ELSE IF( LDH.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDZ.LT.1 .OR. WANTZ .AND. LDZ.LT.MAX( 1, N ) ) THENINFO = -11ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DHSEQR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Initialize Z, if necessary*IF( INITZ )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Store the eigenvalues isolated by DGEBAL.*DO 10 I = 1, ILO - 1WR( I ) = H( I, I )WI( I ) = ZERO10 CONTINUEDO 20 I = IHI + 1, NWR( I ) = H( I, I )WI( I ) = ZERO20 CONTINUE** Quick return if possible.*IF( N.EQ.0 )$ RETURNIF( ILO.EQ.IHI ) THENWR( ILO ) = H( ILO, ILO )WI( ILO ) = ZERORETURNEND IF** Set rows and columns ILO to IHI to zero below the first* subdiagonal.*DO 40 J = ILO, IHI - 2DO 30 I = J + 2, NH( I, J ) = ZERO30 CONTINUE40 CONTINUENH = IHI - ILO + 1** Determine the order of the multi-shift QR algorithm to be used.*NS = ILAENV( 4, 'DHSEQR', JOB // COMPZ, N, ILO, IHI, -1 )MAXB = ILAENV( 8, 'DHSEQR', JOB // COMPZ, N, ILO, IHI, -1 )IF( NS.LE.2 .OR. NS.GT.NH .OR. MAXB.GE.NH ) THEN** Use the standard double-shift algorithm*CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,$ IHI, Z, LDZ, INFO )RETURNEND IFMAXB = MAX( 3, MAXB )NS = MIN( NS, MAXB, NSMAX )** Now 2 < NS <= MAXB < NH.** Set machine-dependent constants for the stopping criterion.* If norm(H) <= sqrt(OVFL), overflow should not occur.*UNFL = DLAMCH( 'Safe minimum' )OVFL = ONE / UNFLCALL DLABAD( UNFL, OVFL )ULP = DLAMCH( 'Precision' )SMLNUM = UNFL*( NH / ULP )** I1 and I2 are the indices of the first row and last column of H* to which transformations must be applied. If eigenvalues only are* being computed, I1 and I2 are set inside the main loop.*IF( WANTT ) THENI1 = 1I2 = NEND IF** ITN is the total number of multiple-shift QR iterations allowed.*ITN = 30*NH** The main loop begins here. I is the loop index and decreases from* IHI to ILO in steps of at most MAXB. Each iteration of the loop* works with the active submatrix in rows and columns L to I.* Eigenvalues I+1 to IHI have already converged. Either L = ILO or* H(L,L-1) is negligible so that the matrix splits.*I = IHI50 CONTINUEL = ILOIF( I.LT.ILO )$ GO TO 170** Perform multiple-shift QR iterations on rows and columns ILO to I* until a submatrix of order at most MAXB splits off at the bottom* because a subdiagonal element has become negligible.*DO 150 ITS = 0, ITN** Look for a single small subdiagonal element.*DO 60 K = I, L + 1, -1TST1 = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) )IF( TST1.EQ.ZERO )$ TST1 = DLANHS( '1', I-L+1, H( L, L ), LDH, WORK )IF( ABS( H( K, K-1 ) ).LE.MAX( ULP*TST1, SMLNUM ) )$ GO TO 7060 CONTINUE70 CONTINUEL = KIF( L.GT.ILO ) THEN** H(L,L-1) is negligible.*H( L, L-1 ) = ZEROEND IF** Exit from loop if a submatrix of order <= MAXB has split off.*IF( L.GE.I-MAXB+1 )$ GO TO 160** Now the active submatrix is in rows and columns L to I. If* eigenvalues only are being computed, only the active submatrix* need be transformed.*IF( .NOT.WANTT ) THENI1 = LI2 = IEND IF*IF( ITS.EQ.20 .OR. ITS.EQ.30 ) THEN** Exceptional shifts.*DO 80 II = I - NS + 1, IWR( II ) = CONST*( ABS( H( II, II-1 ) )+$ ABS( H( II, II ) ) )WI( II ) = ZERO80 CONTINUEELSE** Use eigenvalues of trailing submatrix of order NS as shifts.*CALL DLACPY( 'Full', NS, NS, H( I-NS+1, I-NS+1 ), LDH, S,$ LDS )CALL DLAHQR( .FALSE., .FALSE., NS, 1, NS, S, LDS,$ WR( I-NS+1 ), WI( I-NS+1 ), 1, NS, Z, LDZ,$ IERR )IF( IERR.GT.0 ) THEN** If DLAHQR failed to compute all NS eigenvalues, use the* unconverged diagonal elements as the remaining shifts.*DO 90 II = 1, IERRWR( I-NS+II ) = S( II, II )WI( I-NS+II ) = ZERO90 CONTINUEEND IFEND IF** Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns))* where G is the Hessenberg submatrix H(L:I,L:I) and w is* the vector of shifts (stored in WR and WI). The result is* stored in the local array V.*V( 1 ) = ONEDO 100 II = 2, NS + 1V( II ) = ZERO100 CONTINUENV = 1DO 120 J = I - NS + 1, IIF( WI( J ).GE.ZERO ) THENIF( WI( J ).EQ.ZERO ) THEN** real shift*CALL DCOPY( NV+1, V, 1, VV, 1 )CALL DGEMV( 'No transpose', NV+1, NV, ONE, H( L, L ),$ LDH, VV, 1, -WR( J ), V, 1 )NV = NV + 1ELSE IF( WI( J ).GT.ZERO ) THEN** complex conjugate pair of shifts*CALL DCOPY( NV+1, V, 1, VV, 1 )CALL DGEMV( 'No transpose', NV+1, NV, ONE, H( L, L ),$ LDH, V, 1, -TWO*WR( J ), VV, 1 )ITEMP = IDAMAX( NV+1, VV, 1 )TEMP = ONE / MAX( ABS( VV( ITEMP ) ), SMLNUM )CALL DSCAL( NV+1, TEMP, VV, 1 )ABSW = DLAPY2( WR( J ), WI( J ) )TEMP = ( TEMP*ABSW )*ABSWCALL DGEMV( 'No transpose', NV+2, NV+1, ONE,$ H( L, L ), LDH, VV, 1, TEMP, V, 1 )NV = NV + 2END IF** Scale V(1:NV) so that max(abs(V(i))) = 1. If V is zero,* reset it to the unit vector.*ITEMP = IDAMAX( NV, V, 1 )TEMP = ABS( V( ITEMP ) )IF( TEMP.EQ.ZERO ) THENV( 1 ) = ONEDO 110 II = 2, NVV( II ) = ZERO110 CONTINUEELSETEMP = MAX( TEMP, SMLNUM )CALL DSCAL( NV, ONE / TEMP, V, 1 )END IFEND IF120 CONTINUE** Multiple-shift QR step*DO 140 K = L, I - 1** The first iteration of this loop determines a reflection G* from the vector V and applies it from left and right to H,* thus creating a nonzero bulge below the subdiagonal.** Each subsequent iteration determines a reflection G to* restore the Hessenberg form in the (K-1)th column, and thus* chases the bulge one step toward the bottom of the active* submatrix. NR is the order of G.*NR = MIN( NS+1, I-K+1 )IF( K.GT.L )$ CALL DCOPY( NR, H( K, K-1 ), 1, V, 1 )CALL DLARFG( NR, V( 1 ), V( 2 ), 1, TAU )IF( K.GT.L ) THENH( K, K-1 ) = V( 1 )DO 130 II = K + 1, IH( II, K-1 ) = ZERO130 CONTINUEEND IFV( 1 ) = ONE** Apply G from the left to transform the rows of the matrix in* columns K to I2.*CALL DLARFX( 'Left', NR, I2-K+1, V, TAU, H( K, K ), LDH,$ WORK )** Apply G from the right to transform the columns of the* matrix in rows I1 to min(K+NR,I).*CALL DLARFX( 'Right', MIN( K+NR, I )-I1+1, NR, V, TAU,$ H( I1, K ), LDH, WORK )*IF( WANTZ ) THEN** Accumulate transformations in the matrix Z*CALL DLARFX( 'Right', NH, NR, V, TAU, Z( ILO, K ), LDZ,$ WORK )END IF140 CONTINUE*150 CONTINUE** Failure to converge in remaining number of iterations*INFO = IRETURN*160 CONTINUE** A submatrix of order <= MAXB in rows and columns L to I has split* off. Use the double-shift QR algorithm to handle it.*CALL DLAHQR( WANTT, WANTZ, N, L, I, H, LDH, WR, WI, ILO, IHI, Z,$ LDZ, INFO )IF( INFO.GT.0 )$ RETURN** Decrement number of remaining iterations, and return to start of* the main loop with a new value of I.*ITN = ITN - ITSI = L - 1GO TO 50*170 CONTINUEWORK( 1 ) = MAX( 1, N )RETURN** End of DHSEQR*ENDSUBROUTINE DLAED0( ICOMPQ, QSIZ, N, D, E, Q, LDQ, QSTORE, LDQS,$ WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER ICOMPQ, INFO, LDQ, LDQS, N, QSIZ* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), E( * ), Q( LDQ, * ), QSTORE( LDQS, * ),$ WORK( * )* ..** Purpose* =======** DLAED0 computes all eigenvalues and corresponding eigenvectors of a* symmetric tridiagonal matrix using the divide and conquer method.** Arguments* =========** ICOMPQ (input) INTEGER* = 0: Compute eigenvalues only.* = 1: Compute eigenvectors of original dense symmetric matrix* also. On entry, Q contains the orthogonal matrix used* to reduce the original matrix to tridiagonal form.* = 2: Compute eigenvalues and eigenvectors of tridiagonal* matrix.** QSIZ (input) INTEGER* The dimension of the orthogonal matrix used to reduce* the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1.** N (input) INTEGER* The dimension of the symmetric tridiagonal matrix. N >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the main diagonal of the tridiagonal matrix.* On exit, its eigenvalues.** E (input) DOUBLE PRECISION array, dimension (N-1)* The off-diagonal elements of the tridiagonal matrix.* On exit, E has been destroyed.** Q (input/output) DOUBLE PRECISION array, dimension (LDQ, N)* On entry, Q must contain an N-by-N orthogonal matrix.* If ICOMPQ = 0 Q is not referenced.* If ICOMPQ = 1 On entry, Q is a subset of the columns of the* orthogonal matrix used to reduce the full* matrix to tridiagonal form corresponding to* the subset of the full matrix which is being* decomposed at this time.* If ICOMPQ = 2 On entry, Q will be the identity matrix.* On exit, Q contains the eigenvectors of the* tridiagonal matrix.** LDQ (input) INTEGER* The leading dimension of the array Q. If eigenvectors are* desired, then LDQ >= max(1,N). In any case, LDQ >= 1.** QSTORE (workspace) DOUBLE PRECISION array, dimension (LDQS, N)* Referenced only when ICOMPQ = 1. Used to store parts of* the eigenvector matrix when the updating matrix multiplies* take place.** LDQS (input) INTEGER* The leading dimension of the array QSTORE. If ICOMPQ = 1,* then LDQS >= max(1,N). In any case, LDQS >= 1.** WORK (workspace) DOUBLE PRECISION array,* If ICOMPQ = 0 or 1, the dimension of WORK must be at least* 1 + 3*N + 2*N*lg N + 2*N**2* ( lg( N ) = smallest integer k* such that 2^k >= N )* If ICOMPQ = 2, the dimension of WORK must be at least* 4*N + N**2.** IWORK (workspace) INTEGER array,* If ICOMPQ = 0 or 1, the dimension of IWORK must be at least* 6 + 6*N + 5*N*lg N.* ( lg( N ) = smallest integer k* such that 2^k >= N )* If ICOMPQ = 2, the dimension of IWORK must be at least* 3 + 5*N.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: The algorithm failed to compute an eigenvalue while* working on the submatrix lying in rows and columns* INFO/(N+1) through mod(INFO,N+1).** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.D0, ONE = 1.D0, TWO = 2.D0 )* ..* .. Local Scalars ..INTEGER CURLVL, CURPRB, CURR, I, IGIVCL, IGIVNM,$ IGIVPT, INDXQ, IPERM, IPRMPT, IQ, IQPTR, IWREM,$ J, K, LGN, MATSIZ, MSD2, SMLSIZ, SMM1, SPM1,$ SPM2, SUBMAT, SUBPBS, TLVLSDOUBLE PRECISION TEMP* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLAED1, DLAED7, DSTEQR,$ XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ICOMPQ.LT.0 .OR. ICOMPQ.GT.2 ) THENINFO = -1ELSE IF( ( ICOMPQ.EQ.1 ) .AND. ( QSIZ.LT.MAX( 0, N ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDQS.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED0', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*SMLSIZ = ILAENV( 9, 'DLAED0', ' ', 0, 0, 0, 0 )** Determine the size and placement of the submatrices, and save in* the leading elements of IWORK.*IWORK( 1 ) = NSUBPBS = 1TLVLS = 010 CONTINUEIF( IWORK( SUBPBS ).GT.SMLSIZ ) THENDO 20 J = SUBPBS, 1, -1IWORK( 2*J ) = ( IWORK( J )+1 ) / 2IWORK( 2*J-1 ) = IWORK( J ) / 220 CONTINUETLVLS = TLVLS + 1SUBPBS = 2*SUBPBSGO TO 10END IFDO 30 J = 2, SUBPBSIWORK( J ) = IWORK( J ) + IWORK( J-1 )30 CONTINUE** Divide the matrix into SUBPBS submatrices of size at most SMLSIZ+1* using rank-1 modifications (cuts).*SPM1 = SUBPBS - 1DO 40 I = 1, SPM1SUBMAT = IWORK( I ) + 1SMM1 = SUBMAT - 1D( SMM1 ) = D( SMM1 ) - ABS( E( SMM1 ) )D( SUBMAT ) = D( SUBMAT ) - ABS( E( SMM1 ) )40 CONTINUE*INDXQ = 4*N + 3IF( ICOMPQ.NE.2 ) THEN** Set up workspaces for eigenvalues only/accumulate new vectors* routine*TEMP = LOG( DBLE( N ) ) / LOG( TWO )LGN = INT( TEMP )IF( 2**LGN.LT.N )$ LGN = LGN + 1IF( 2**LGN.LT.N )$ LGN = LGN + 1IPRMPT = INDXQ + N + 1IPERM = IPRMPT + N*LGNIQPTR = IPERM + N*LGNIGIVPT = IQPTR + N + 2IGIVCL = IGIVPT + N*LGN*IGIVNM = 1IQ = IGIVNM + 2*N*LGNIWREM = IQ + N**2 + 1** Initialize pointers*DO 50 I = 0, SUBPBSIWORK( IPRMPT+I ) = 1IWORK( IGIVPT+I ) = 150 CONTINUEIWORK( IQPTR ) = 1END IF** Solve each submatrix eigenproblem at the bottom of the divide and* conquer tree.*CURR = 0DO 70 I = 0, SPM1IF( I.EQ.0 ) THENSUBMAT = 1MATSIZ = IWORK( 1 )ELSESUBMAT = IWORK( I ) + 1MATSIZ = IWORK( I+1 ) - IWORK( I )END IFIF( ICOMPQ.EQ.2 ) THENCALL DSTEQR( 'I', MATSIZ, D( SUBMAT ), E( SUBMAT ),$ Q( SUBMAT, SUBMAT ), LDQ, WORK, INFO )IF( INFO.NE.0 )$ GO TO 130ELSECALL DSTEQR( 'I', MATSIZ, D( SUBMAT ), E( SUBMAT ),$ WORK( IQ-1+IWORK( IQPTR+CURR ) ), MATSIZ, WORK,$ INFO )IF( INFO.NE.0 )$ GO TO 130IF( ICOMPQ.EQ.1 ) THENCALL DGEMM( 'N', 'N', QSIZ, MATSIZ, MATSIZ, ONE,$ Q( 1, SUBMAT ), LDQ, WORK( IQ-1+IWORK( IQPTR+$ CURR ) ), MATSIZ, ZERO, QSTORE( 1, SUBMAT ),$ LDQS )END IFIWORK( IQPTR+CURR+1 ) = IWORK( IQPTR+CURR ) + MATSIZ**2CURR = CURR + 1END IFK = 1DO 60 J = SUBMAT, IWORK( I+1 )IWORK( INDXQ+J ) = KK = K + 160 CONTINUE70 CONTINUE** Successively merge eigensystems of adjacent submatrices* into eigensystem for the corresponding larger matrix.** while ( SUBPBS > 1 )*CURLVL = 180 CONTINUEIF( SUBPBS.GT.1 ) THENSPM2 = SUBPBS - 2DO 90 I = 0, SPM2, 2IF( I.EQ.0 ) THENSUBMAT = 1MATSIZ = IWORK( 2 )MSD2 = IWORK( 1 )CURPRB = 0ELSESUBMAT = IWORK( I ) + 1MATSIZ = IWORK( I+2 ) - IWORK( I )MSD2 = MATSIZ / 2CURPRB = CURPRB + 1END IF** Merge lower order eigensystems (of size MSD2 and MATSIZ - MSD2)* into an eigensystem of size MATSIZ.* DLAED1 is used only for the full eigensystem of a tridiagonal* matrix.* DLAED7 handles the cases in which eigenvalues only or eigenvalues* and eigenvectors of a full symmetric matrix (which was reduced to* tridiagonal form) are desired.*IF( ICOMPQ.EQ.2 ) THENCALL DLAED1( MATSIZ, D( SUBMAT ), Q( SUBMAT, SUBMAT ),$ LDQ, IWORK( INDXQ+SUBMAT ),$ E( SUBMAT+MSD2-1 ), MSD2, WORK,$ IWORK( SUBPBS+1 ), INFO )ELSECALL DLAED7( ICOMPQ, MATSIZ, QSIZ, TLVLS, CURLVL, CURPRB,$ D( SUBMAT ), QSTORE( 1, SUBMAT ), LDQS,$ IWORK( INDXQ+SUBMAT ), E( SUBMAT+MSD2-1 ),$ MSD2, WORK( IQ ), IWORK( IQPTR ),$ IWORK( IPRMPT ), IWORK( IPERM ),$ IWORK( IGIVPT ), IWORK( IGIVCL ),$ WORK( IGIVNM ), WORK( IWREM ),$ IWORK( SUBPBS+1 ), INFO )END IFIF( INFO.NE.0 )$ GO TO 130IWORK( I / 2+1 ) = IWORK( I+2 )90 CONTINUESUBPBS = SUBPBS / 2CURLVL = CURLVL + 1GO TO 80END IF** end while** Re-merge the eigenvalues/vectors which were deflated at the final* merge step.*IF( ICOMPQ.EQ.1 ) THENDO 100 I = 1, NJ = IWORK( INDXQ+I )WORK( I ) = D( J )CALL DCOPY( QSIZ, QSTORE( 1, J ), 1, Q( 1, I ), 1 )100 CONTINUECALL DCOPY( N, WORK, 1, D, 1 )ELSE IF( ICOMPQ.EQ.2 ) THENDO 110 I = 1, NJ = IWORK( INDXQ+I )WORK( I ) = D( J )CALL DCOPY( N, Q( 1, J ), 1, WORK( N*I+1 ), 1 )110 CONTINUECALL DCOPY( N, WORK, 1, D, 1 )CALL DLACPY( 'A', N, N, WORK( N+1 ), N, Q, LDQ )ELSEDO 120 I = 1, NJ = IWORK( INDXQ+I )WORK( I ) = D( J )120 CONTINUECALL DCOPY( N, WORK, 1, D, 1 )END IFGO TO 140*130 CONTINUEINFO = SUBMAT*( N+1 ) + SUBMAT + MATSIZ - 1*140 CONTINUERETURN** End of DLAED0*ENDSUBROUTINE DLAED1( N, D, Q, LDQ, INDXQ, RHO, CUTPNT, WORK, IWORK,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER CUTPNT, INFO, LDQ, NDOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER INDXQ( * ), IWORK( * )DOUBLE PRECISION D( * ), Q( LDQ, * ), WORK( * )* ..** Purpose* =======** DLAED1 computes the updated eigensystem of a diagonal* matrix after modification by a rank-one symmetric matrix. This* routine is used only for the eigenproblem which requires all* eigenvalues and eigenvectors of a tridiagonal matrix. DLAED7 handles* the case in which eigenvalues only or eigenvalues and eigenvectors* of a full symmetric matrix (which was reduced to tridiagonal form)* are desired.** T = Q(in) ( D(in) + RHO * Z*Z' ) Q'(in) = Q(out) * D(out) * Q'(out)** where Z = Q'u, u is a vector of length N with ones in the* CUTPNT and CUTPNT + 1 th elements and zeros elsewhere.** The eigenvectors of the original matrix are stored in Q, and the* eigenvalues are in D. The algorithm consists of three stages:** The first stage consists of deflating the size of the problem* when there are multiple eigenvalues or if there is a zero in* the Z vector. For each such occurence the dimension of the* secular equation problem is reduced by one. This stage is* performed by the routine DLAED2.** The second stage consists of calculating the updated* eigenvalues. This is done by finding the roots of the secular* equation via the routine DLAED4 (as called by DLAED3).* This routine also calculates the eigenvectors of the current* problem.** The final stage consists of computing the updated eigenvectors* directly using the updated eigenvalues. The eigenvectors for* the current problem are multiplied with the eigenvectors from* the overall problem.** Arguments* =========** N (input) INTEGER* The dimension of the symmetric tridiagonal matrix. N >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the eigenvalues of the rank-1-perturbed matrix.* On exit, the eigenvalues of the repaired matrix.** Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N)* On entry, the eigenvectors of the rank-1-perturbed matrix.* On exit, the eigenvectors of the repaired tridiagonal matrix.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N).** INDXQ (input/output) INTEGER array, dimension (N)* On entry, the permutation which separately sorts the two* subproblems in D into ascending order.* On exit, the permutation which will reintegrate the* subproblems back into sorted order,* i.e. D( INDXQ( I = 1, N ) ) will be in ascending order.** RHO (input) DOUBLE PRECISION* The subdiagonal entry used to create the rank-1 modification.** CUTPNT (input) INTEGER* The location of the last eigenvalue in the leading sub-matrix.* min(1,N) <= CUTPNT <= N/2.** WORK (workspace) DOUBLE PRECISION array, dimension (4*N + N**2)** IWORK (workspace) INTEGER array, dimension (4*N)** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: if INFO = 1, an eigenvalue did not converge** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA* Modified by Francoise Tisseur, University of Tennessee.** =====================================================================** .. Local Scalars ..INTEGER COLTYP, I, IDLMDA, INDX, INDXC, INDXP, IQ2, IS,$ IW, IZ, K, N1, N2, ZPP1* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAED2, DLAED3, DLAMRG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -1ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( MIN( 1, N / 2 ).GT.CUTPNT .OR. ( N / 2 ).LT.CUTPNT ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED1', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** The following values are integer pointers which indicate* the portion of the workspace* used by a particular array in DLAED2 and DLAED3.*IZ = 1IDLMDA = IZ + NIW = IDLMDA + NIQ2 = IW + N*INDX = 1INDXC = INDX + NCOLTYP = INDXC + NINDXP = COLTYP + N*** Form the z-vector which consists of the last row of Q_1 and the* first row of Q_2.*CALL DCOPY( CUTPNT, Q( CUTPNT, 1 ), LDQ, WORK( IZ ), 1 )ZPP1 = CUTPNT + 1CALL DCOPY( N-CUTPNT, Q( ZPP1, ZPP1 ), LDQ, WORK( IZ+CUTPNT ), 1 )** Deflate eigenvalues.*CALL DLAED2( K, N, CUTPNT, D, Q, LDQ, INDXQ, RHO, WORK( IZ ),$ WORK( IDLMDA ), WORK( IW ), WORK( IQ2 ),$ IWORK( INDX ), IWORK( INDXC ), IWORK( INDXP ),$ IWORK( COLTYP ), INFO )*IF( INFO.NE.0 )$ GO TO 20** Solve Secular Equation.*IF( K.NE.0 ) THENIS = ( IWORK( COLTYP )+IWORK( COLTYP+1 ) )*CUTPNT +$ ( IWORK( COLTYP+1 )+IWORK( COLTYP+2 ) )*( N-CUTPNT ) + IQ2CALL DLAED3( K, N, CUTPNT, D, Q, LDQ, RHO, WORK( IDLMDA ),$ WORK( IQ2 ), IWORK( INDXC ), IWORK( COLTYP ),$ WORK( IW ), WORK( IS ), INFO )IF( INFO.NE.0 )$ GO TO 20** Prepare the INDXQ sorting permutation.*N1 = KN2 = N - KCALL DLAMRG( N1, N2, D, 1, -1, INDXQ )ELSEDO 10 I = 1, NINDXQ( I ) = I10 CONTINUEEND IF*20 CONTINUERETURN** End of DLAED1*ENDSUBROUTINE DLAED2( K, N, N1, D, Q, LDQ, INDXQ, RHO, Z, DLAMDA, W,$ Q2, INDX, INDXC, INDXP, COLTYP, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments ..INTEGER INFO, K, LDQ, N, N1DOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER COLTYP( * ), INDX( * ), INDXC( * ), INDXP( * ),$ INDXQ( * )DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), Q2( * ),$ W( * ), Z( * )* ..** Purpose* =======** DLAED2 merges the two sets of eigenvalues together into a single* sorted set. Then it tries to deflate the size of the problem.* There are two ways in which deflation can occur: when two or more* eigenvalues are close together or if there is a tiny entry in the* Z vector. For each such occurrence the order of the related secular* equation problem is reduced by one.** Arguments* =========** K (output) INTEGER* The number of non-deflated eigenvalues, and the order of the* related secular equation. 0 <= K <=N.** N (input) INTEGER* The dimension of the symmetric tridiagonal matrix. N >= 0.** N1 (input) INTEGER* The location of the last eigenvalue in the leading sub-matrix.* min(1,N) <= N1 <= N/2.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, D contains the eigenvalues of the two submatrices to* be combined.* On exit, D contains the trailing (N-K) updated eigenvalues* (those which were deflated) sorted into increasing order.** Q (input/output) DOUBLE PRECISION array, dimension (LDQ, N)* On entry, Q contains the eigenvectors of two submatrices in* the two square blocks with corners at (1,1), (N1,N1)* and (N1+1, N1+1), (N,N).* On exit, Q contains the trailing (N-K) updated eigenvectors* (those which were deflated) in its last N-K columns.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N).** INDXQ (input/output) INTEGER array, dimension (N)* The permutation which separately sorts the two sub-problems* in D into ascending order. Note that elements in the second* half of this permutation must first have N1 added to their* values. Destroyed on exit.** RHO (input/output) DOUBLE PRECISION* On entry, the off-diagonal element associated with the rank-1* cut which originally split the two submatrices which are now* being recombined.* On exit, RHO has been modified to the value required by* DLAED3.** Z (input) DOUBLE PRECISION array, dimension (N)* On entry, Z contains the updating vector (the last* row of the first sub-eigenvector matrix and the first row of* the second sub-eigenvector matrix).* On exit, the contents of Z have been destroyed by the updating* process.** DLAMDA (output) DOUBLE PRECISION array, dimension (N)* A copy of the first K eigenvalues which will be used by* DLAED3 to form the secular equation.** W (output) DOUBLE PRECISION array, dimension (N)* The first k values of the final deflation-altered z-vector* which will be passed to DLAED3.** Q2 (output) DOUBLE PRECISION array, dimension (N1**2+(N-N1)**2)* A copy of the first K eigenvectors which will be used by* DLAED3 in a matrix multiply (DGEMM) to solve for the new* eigenvectors.** INDX (workspace) INTEGER array, dimension (N)* The permutation used to sort the contents of DLAMDA into* ascending order.** INDXC (output) INTEGER array, dimension (N)* The permutation used to arrange the columns of the deflated* Q matrix into three groups: the first group contains non-zero* elements only at and above N1, the second contains* non-zero elements only below N1, and the third is dense.** INDXP (workspace) INTEGER array, dimension (N)* The permutation used to place deflated values of D at the end* of the array. INDXP(1:K) points to the nondeflated D-values* and INDXP(K+1:N) points to the deflated eigenvalues.** COLTYP (workspace/output) INTEGER array, dimension (N)* During execution, a label which will indicate which of the* following types a column in the Q2 matrix is:* 1 : non-zero in the upper half only;* 2 : dense;* 3 : non-zero in the lower half only;* 4 : deflated.* On exit, COLTYP(i) is the number of columns of type i,* for i=1 to 4 only.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA* Modified by Francoise Tisseur, University of Tennessee.** =====================================================================** .. Parameters ..DOUBLE PRECISION MONE, ZERO, ONE, TWO, EIGHTPARAMETER ( MONE = -1.0D0, ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, EIGHT = 8.0D0 )* ..* .. Local Arrays ..INTEGER CTOT( 4 ), PSM( 4 )* ..* .. Local Scalars ..INTEGER CT, I, IMAX, IQ1, IQ2, J, JMAX, JS, K2, N1P1,$ N2, NJ, PJDOUBLE PRECISION C, EPS, S, T, TAU, TOL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL IDAMAX, DLAMCH, DLAPY2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAMRG, DROT, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -2ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( MIN( 1, ( N / 2 ) ).GT.N1 .OR. ( N / 2 ).LT.N1 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*N2 = N - N1N1P1 = N1 + 1*IF( RHO.LT.ZERO ) THENCALL DSCAL( N2, MONE, Z( N1P1 ), 1 )END IF** Normalize z so that norm(z) = 1. Since z is the concatenation of* two normalized vectors, norm2(z) = sqrt(2).*T = ONE / SQRT( TWO )CALL DSCAL( N, T, Z, 1 )** RHO = ABS( norm(z)**2 * RHO )*RHO = ABS( TWO*RHO )** Sort the eigenvalues into increasing order*DO 10 I = N1P1, NINDXQ( I ) = INDXQ( I ) + N110 CONTINUE** re-integrate the deflated parts from the last pass*DO 20 I = 1, NDLAMDA( I ) = D( INDXQ( I ) )20 CONTINUECALL DLAMRG( N1, N2, DLAMDA, 1, 1, INDXC )DO 30 I = 1, NINDX( I ) = INDXQ( INDXC( I ) )30 CONTINUE** Calculate the allowable deflation tolerance*IMAX = IDAMAX( N, Z, 1 )JMAX = IDAMAX( N, D, 1 )EPS = DLAMCH( 'Epsilon' )TOL = EIGHT*EPS*MAX( ABS( D( JMAX ) ), ABS( Z( IMAX ) ) )** If the rank-1 modifier is small enough, no more needs to be done* except to reorganize Q so that its columns correspond with the* elements in D.*IF( RHO*ABS( Z( IMAX ) ).LE.TOL ) THENK = 0IQ2 = 1DO 40 J = 1, NI = INDX( J )CALL DCOPY( N, Q( 1, I ), 1, Q2( IQ2 ), 1 )DLAMDA( J ) = D( I )IQ2 = IQ2 + N40 CONTINUECALL DLACPY( 'A', N, N, Q2, N, Q, LDQ )CALL DCOPY( N, DLAMDA, 1, D, 1 )GO TO 190END IF** If there are multiple eigenvalues then the problem deflates. Here* the number of equal eigenvalues are found. As each equal* eigenvalue is found, an elementary reflector is computed to rotate* the corresponding eigensubspace so that the corresponding* components of Z are zero in this new basis.*DO 50 I = 1, N1COLTYP( I ) = 150 CONTINUEDO 60 I = N1P1, NCOLTYP( I ) = 360 CONTINUE**K = 0K2 = N + 1DO 70 J = 1, NNJ = INDX( J )IF( RHO*ABS( Z( NJ ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1COLTYP( NJ ) = 4INDXP( K2 ) = NJIF( J.EQ.N )$ GO TO 100ELSEPJ = NJGO TO 80END IF70 CONTINUE80 CONTINUEJ = J + 1NJ = INDX( J )IF( J.GT.N )$ GO TO 100IF( RHO*ABS( Z( NJ ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1COLTYP( NJ ) = 4INDXP( K2 ) = NJELSE** Check if eigenvalues are close enough to allow deflation.*S = Z( PJ )C = Z( NJ )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.*TAU = DLAPY2( C, S )T = D( NJ ) - D( PJ )C = C / TAUS = -S / TAUIF( ABS( T*C*S ).LE.TOL ) THEN** Deflation is possible.*Z( NJ ) = TAUZ( PJ ) = ZEROIF( COLTYP( NJ ).NE.COLTYP( PJ ) )$ COLTYP( NJ ) = 2COLTYP( PJ ) = 4CALL DROT( N, Q( 1, PJ ), 1, Q( 1, NJ ), 1, C, S )T = D( PJ )*C**2 + D( NJ )*S**2D( NJ ) = D( PJ )*S**2 + D( NJ )*C**2D( PJ ) = TK2 = K2 - 1I = 190 CONTINUEIF( K2+I.LE.N ) THENIF( D( PJ ).LT.D( INDXP( K2+I ) ) ) THENINDXP( K2+I-1 ) = INDXP( K2+I )INDXP( K2+I ) = PJI = I + 1GO TO 90ELSEINDXP( K2+I-1 ) = PJEND IFELSEINDXP( K2+I-1 ) = PJEND IFPJ = NJELSEK = K + 1DLAMDA( K ) = D( PJ )W( K ) = Z( PJ )INDXP( K ) = PJPJ = NJEND IFEND IFGO TO 80100 CONTINUE** Record the last eigenvalue.*K = K + 1DLAMDA( K ) = D( PJ )W( K ) = Z( PJ )INDXP( K ) = PJ** Count up the total number of the various types of columns, then* form a permutation which positions the four column types into* four uniform groups (although one or more of these groups may be* empty).*DO 110 J = 1, 4CTOT( J ) = 0110 CONTINUEDO 120 J = 1, NCT = COLTYP( J )CTOT( CT ) = CTOT( CT ) + 1120 CONTINUE** PSM(*) = Position in SubMatrix (of types 1 through 4)*PSM( 1 ) = 1PSM( 2 ) = 1 + CTOT( 1 )PSM( 3 ) = PSM( 2 ) + CTOT( 2 )PSM( 4 ) = PSM( 3 ) + CTOT( 3 )K = N - CTOT( 4 )** Fill out the INDXC array so that the permutation which it induces* will place all type-1 columns first, all type-2 columns next,* then all type-3's, and finally all type-4's.*DO 130 J = 1, NJS = INDXP( J )CT = COLTYP( JS )INDX( PSM( CT ) ) = JSINDXC( PSM( CT ) ) = JPSM( CT ) = PSM( CT ) + 1130 CONTINUE** Sort the eigenvalues and corresponding eigenvectors into DLAMDA* and Q2 respectively. The eigenvalues/vectors which were not* deflated go into the first K slots of DLAMDA and Q2 respectively,* while those which were deflated go into the last N - K slots.*I = 1IQ1 = 1IQ2 = 1 + ( CTOT( 1 )+CTOT( 2 ) )*N1DO 140 J = 1, CTOT( 1 )JS = INDX( I )CALL DCOPY( N1, Q( 1, JS ), 1, Q2( IQ1 ), 1 )Z( I ) = D( JS )I = I + 1IQ1 = IQ1 + N1140 CONTINUE*DO 150 J = 1, CTOT( 2 )JS = INDX( I )CALL DCOPY( N1, Q( 1, JS ), 1, Q2( IQ1 ), 1 )CALL DCOPY( N2, Q( N1+1, JS ), 1, Q2( IQ2 ), 1 )Z( I ) = D( JS )I = I + 1IQ1 = IQ1 + N1IQ2 = IQ2 + N2150 CONTINUE*DO 160 J = 1, CTOT( 3 )JS = INDX( I )CALL DCOPY( N2, Q( N1+1, JS ), 1, Q2( IQ2 ), 1 )Z( I ) = D( JS )I = I + 1IQ2 = IQ2 + N2160 CONTINUE*IQ1 = IQ2DO 170 J = 1, CTOT( 4 )JS = INDX( I )CALL DCOPY( N, Q( 1, JS ), 1, Q2( IQ2 ), 1 )IQ2 = IQ2 + NZ( I ) = D( JS )I = I + 1170 CONTINUE** The deflated eigenvalues and their corresponding vectors go back* into the last N - K slots of D and Q respectively.*CALL DLACPY( 'A', N, CTOT( 4 ), Q2( IQ1 ), N, Q( 1, K+1 ), LDQ )CALL DCOPY( N-K, Z( K+1 ), 1, D( K+1 ), 1 )** Copy CTOT into COLTYP for referencing in DLAED3.*DO 180 J = 1, 4COLTYP( J ) = CTOT( J )180 CONTINUE*190 CONTINUERETURN** End of DLAED2*ENDSUBROUTINE DLAED3( K, N, N1, D, Q, LDQ, RHO, DLAMDA, Q2, INDX,$ CTOT, W, S, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Oak Ridge National Lab, Argonne National Lab,* Courant Institute, NAG Ltd., and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, K, LDQ, N, N1DOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER CTOT( * ), INDX( * )DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), Q2( * ),$ S( * ), W( * )* ..** Purpose* =======** DLAED3 finds the roots of the secular equation, as defined by the* values in D, W, and RHO, between 1 and K. It makes the* appropriate calls to DLAED4 and then updates the eigenvectors by* multiplying the matrix of eigenvectors of the pair of eigensystems* being combined by the matrix of eigenvectors of the K-by-K system* which is solved here.** This code makes very mild assumptions about floating point* arithmetic. It will work on machines with a guard digit in* add/subtract, or on those binary machines without guard digits* which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.* It could conceivably fail on hexadecimal or decimal machines* without guard digits, but we know of none.** Arguments* =========** K (input) INTEGER* The number of terms in the rational function to be solved by* DLAED4. K >= 0.** N (input) INTEGER* The number of rows and columns in the Q matrix.* N >= K (deflation may result in N>K).** N1 (input) INTEGER* The location of the last eigenvalue in the leading submatrix.* min(1,N) <= N1 <= N/2.** D (output) DOUBLE PRECISION array, dimension (N)* D(I) contains the updated eigenvalues for* 1 <= I <= K.** Q (output) DOUBLE PRECISION array, dimension (LDQ,N)* Initially the first K columns are used as workspace.* On output the columns 1 to K contain* the updated eigenvectors.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N).** RHO (input) DOUBLE PRECISION* The value of the parameter in the rank one update equation.* RHO >= 0 required.** DLAMDA (input/output) DOUBLE PRECISION array, dimension (K)* The first K elements of this array contain the old roots* of the deflated updating problem. These are the poles* of the secular equation. May be changed on output by* having lowest order bit set to zero on Cray X-MP, Cray Y-MP,* Cray-2, or Cray C-90, as described above.** Q2 (input) DOUBLE PRECISION array, dimension (LDQ2, N)* The first K columns of this matrix contain the non-deflated* eigenvectors for the split problem.** INDX (input) INTEGER array, dimension (N)* The permutation used to arrange the columns of the deflated* Q matrix into three groups (see DLAED2).* The rows of the eigenvectors found by DLAED4 must be likewise* permuted before the matrix multiply can take place.** CTOT (input) INTEGER array, dimension (4)* A count of the total number of the various types of columns* in Q, as described in INDX. The fourth column type is any* column which has been deflated.** W (input/output) DOUBLE PRECISION array, dimension (K)* The first K elements of this array contain the components* of the deflation-adjusted updating vector. Destroyed on* output.** S (workspace) DOUBLE PRECISION array, dimension (N1 + 1)*K* Will contain the eigenvectors of the repaired matrix which* will be multiplied by the previously accumulated eigenvectors* to update the system.** LDS (input) INTEGER* The leading dimension of S. LDS >= max(1,K).** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: if INFO = 1, an eigenvalue did not converge** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA* Modified by Francoise Tisseur, University of Tennessee.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER I, II, IQ2, J, N12, N2, N23DOUBLE PRECISION TEMP* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLAED4, DLASET, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( K.LT.0 ) THENINFO = -1ELSE IF( N.LT.K ) THENINFO = -2ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED3', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.0 )$ RETURN** Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can* be computed with high relative accuracy (barring over/underflow).* This is a problem on machines without a guard digit in* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).* The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I),* which on any of these machines zeros out the bottommost* bit of DLAMDA(I) if it is 1; this makes the subsequent* subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation* occurs. On binary machines with a guard digit (almost all* machines) it does not change DLAMDA(I) at all. On hexadecimal* and decimal machines with a guard digit, it slightly* changes the bottommost bits of DLAMDA(I). It does not account* for hexadecimal or decimal machines without guard digits* (we know of none). We use a subroutine call to compute* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating* this code.*DO 10 I = 1, KDLAMDA( I ) = DLAMC3( DLAMDA( I ), DLAMDA( I ) ) - DLAMDA( I )10 CONTINUE*DO 20 J = 1, KCALL DLAED4( K, J, DLAMDA, W, Q( 1, J ), RHO, D( J ), INFO )** If the zero finder fails, the computation is terminated.*IF( INFO.NE.0 )$ GO TO 12020 CONTINUE*IF( K.EQ.1 )$ GO TO 110IF( K.EQ.2 ) THENDO 30 J = 1, KW( 1 ) = Q( 1, J )W( 2 ) = Q( 2, J )II = INDX( 1 )Q( 1, J ) = W( II )II = INDX( 2 )Q( 2, J ) = W( II )30 CONTINUEGO TO 110END IF** Compute updated W.*CALL DCOPY( K, W, 1, S, 1 )** Initialize W(I) = Q(I,I)*CALL DCOPY( K, Q, LDQ+1, W, 1 )DO 60 J = 1, KDO 40 I = 1, J - 1W( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )40 CONTINUEDO 50 I = J + 1, KW( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )50 CONTINUE60 CONTINUEDO 70 I = 1, KW( I ) = SIGN( SQRT( -W( I ) ), S( I ) )70 CONTINUE** Compute eigenvectors of the modified rank-1 modification.*DO 100 J = 1, KDO 80 I = 1, KS( I ) = W( I ) / Q( I, J )80 CONTINUETEMP = DNRM2( K, S, 1 )DO 90 I = 1, KII = INDX( I )Q( I, J ) = S( II ) / TEMP90 CONTINUE100 CONTINUE** Compute the updated eigenvectors.*110 CONTINUE*N2 = N - N1N12 = CTOT( 1 ) + CTOT( 2 )N23 = CTOT( 2 ) + CTOT( 3 )*CALL DLACPY( 'A', N23, K, Q( CTOT( 1 )+1, 1 ), LDQ, S, N23 )IQ2 = N1*N12 + 1IF( N23.NE.0 ) THENCALL DGEMM( 'N', 'N', N2, K, N23, ONE, Q2( IQ2 ), N2, S, N23,$ ZERO, Q( N1+1, 1 ), LDQ )ELSECALL DLASET( 'A', N2, K, ZERO, ZERO, Q( N1+1, 1 ), LDQ )END IF*CALL DLACPY( 'A', N12, K, Q, LDQ, S, N12 )IF( N12.NE.0 ) THENCALL DGEMM( 'N', 'N', N1, K, N12, ONE, Q2, N1, S, N12, ZERO, Q,$ LDQ )ELSECALL DLASET( 'A', N1, K, ZERO, ZERO, Q( 1, 1 ), LDQ )END IF**120 CONTINUERETURN** End of DLAED3*ENDSUBROUTINE DLAED4( N, I, D, Z, DELTA, RHO, DLAM, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Oak Ridge National Lab, Argonne National Lab,* Courant Institute, NAG Ltd., and Rice University* December 23, 1999** .. Scalar Arguments ..INTEGER I, INFO, NDOUBLE PRECISION DLAM, RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DELTA( * ), Z( * )* ..** Purpose* =======** This subroutine computes the I-th updated eigenvalue of a symmetric* rank-one modification to a diagonal matrix whose elements are* given in the array d, and that** D(i) < D(j) for i < j** and that RHO > 0. This is arranged by the calling routine, and is* no loss in generality. The rank-one modified system is thus** diag( D ) + RHO * Z * Z_transpose.** where we assume the Euclidean norm of Z is 1.** The method consists of approximating the rational functions in the* secular equation by simpler interpolating rational functions.** Arguments* =========** N (input) INTEGER* The length of all arrays.** I (input) INTEGER* The index of the eigenvalue to be computed. 1 <= I <= N.** D (input) DOUBLE PRECISION array, dimension (N)* The original eigenvalues. It is assumed that they are in* order, D(I) < D(J) for I < J.** Z (input) DOUBLE PRECISION array, dimension (N)* The components of the updating vector.** DELTA (output) DOUBLE PRECISION array, dimension (N)* If N .ne. 1, DELTA contains (D(j) - lambda_I) in its j-th* component. If N = 1, then DELTA(1) = 1. The vector DELTA* contains the information necessary to construct the* eigenvectors.** RHO (input) DOUBLE PRECISION* The scalar in the symmetric updating formula.** DLAM (output) DOUBLE PRECISION* The computed lambda_I, the I-th updated eigenvalue.** INFO (output) INTEGER* = 0: successful exit* > 0: if INFO = 1, the updating process failed.** Internal Parameters* ===================** Logical variable ORGATI (origin-at-i?) is used for distinguishing* whether D(i) or D(i+1) is treated as the origin.** ORGATI = .true. origin at i* ORGATI = .false. origin at i+1** Logical variable SWTCH3 (switch-for-3-poles?) is for noting* if we are working with THREE poles!** MAXIT is the maximum number of iterations allowed for each* eigenvalue.** Further Details* ===============** Based on contributions by* Ren-Cang Li, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..INTEGER MAXITPARAMETER ( MAXIT = 30 )DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHT, TENPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0,$ TEN = 10.0D0 )* ..* .. Local Scalars ..LOGICAL ORGATI, SWTCH, SWTCH3INTEGER II, IIM1, IIP1, IP1, ITER, J, NITERDOUBLE PRECISION A, B, C, DEL, DLTLB, DLTUB, DPHI, DPSI, DW,$ EPS, ERRETM, ETA, MIDPT, PHI, PREW, PSI,$ RHOINV, TAU, TEMP, TEMP1, W* ..* .. Local Arrays ..DOUBLE PRECISION ZZ( 3 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DLAED5, DLAED6* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Since this routine is called in an inner loop, we do no argument* checking.** Quick return for N=1 and 2.*INFO = 0IF( N.EQ.1 ) THEN** Presumably, I=1 upon entry*DLAM = D( 1 ) + RHO*Z( 1 )*Z( 1 )DELTA( 1 ) = ONERETURNEND IFIF( N.EQ.2 ) THENCALL DLAED5( I, D, Z, DELTA, RHO, DLAM )RETURNEND IF** Compute machine epsilon*EPS = DLAMCH( 'Epsilon' )RHOINV = ONE / RHO** The case I = N*IF( I.EQ.N ) THEN** Initialize some basic variables*II = N - 1NITER = 1** Calculate initial guess*MIDPT = RHO / TWO** If ||Z||_2 is not one, then TEMP should be set to* RHO * ||Z||_2^2 / TWO*DO 10 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - MIDPT10 CONTINUE*PSI = ZERODO 20 J = 1, N - 2PSI = PSI + Z( J )*Z( J ) / DELTA( J )20 CONTINUE*C = RHOINV + PSIW = C + Z( II )*Z( II ) / DELTA( II ) +$ Z( N )*Z( N ) / DELTA( N )*IF( W.LE.ZERO ) THENTEMP = Z( N-1 )*Z( N-1 ) / ( D( N )-D( N-1 )+RHO ) +$ Z( N )*Z( N ) / RHOIF( C.LE.TEMP ) THENTAU = RHOELSEDEL = D( N ) - D( N-1 )A = -C*DEL + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )B = Z( N )*Z( N )*DELIF( A.LT.ZERO ) THENTAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )ELSETAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )END IFEND IF** It can be proved that* D(N)+RHO/2 <= LAMBDA(N) < D(N)+TAU <= D(N)+RHO*DLTLB = MIDPTDLTUB = RHOELSEDEL = D( N ) - D( N-1 )A = -C*DEL + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )B = Z( N )*Z( N )*DELIF( A.LT.ZERO ) THENTAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )ELSETAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )END IF** It can be proved that* D(N) < D(N)+TAU < LAMBDA(N) < D(N)+RHO/2*DLTLB = ZERODLTUB = MIDPTEND IF*DO 30 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - TAU30 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 40 J = 1, IITEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI40 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / DELTA( N )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +$ ABS( TAU )*( DPSI+DPHI )*W = RHOINV + PHI + PSI** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENDLAM = D( I ) + TAUGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*NITER = NITER + 1C = W - DELTA( N-1 )*DPSI - DELTA( N )*DPHIA = ( DELTA( N-1 )+DELTA( N ) )*W -$ DELTA( N-1 )*DELTA( N )*( DPSI+DPHI )B = DELTA( N-1 )*DELTA( N )*WIF( C.LT.ZERO )$ C = ABS( C )IF( C.EQ.ZERO ) THEN* ETA = B/A* ETA = RHO - TAUETA = DLTUB - TAUELSE IF( A.GE.ZERO ) THENETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GT.ZERO )$ ETA = -W / ( DPSI+DPHI )TEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IFDO 50 J = 1, NDELTA( J ) = DELTA( J ) - ETA50 CONTINUE*TAU = TAU + ETA** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 60 J = 1, IITEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI60 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / DELTA( N )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +$ ABS( TAU )*( DPSI+DPHI )*W = RHOINV + PHI + PSI** Main loop to update the values of the array DELTA*ITER = NITER + 1*DO 90 NITER = ITER, MAXIT** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENDLAM = D( I ) + TAUGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*C = W - DELTA( N-1 )*DPSI - DELTA( N )*DPHIA = ( DELTA( N-1 )+DELTA( N ) )*W -$ DELTA( N-1 )*DELTA( N )*( DPSI+DPHI )B = DELTA( N-1 )*DELTA( N )*WIF( A.GE.ZERO ) THENETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GT.ZERO )$ ETA = -W / ( DPSI+DPHI )TEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IFDO 70 J = 1, NDELTA( J ) = DELTA( J ) - ETA70 CONTINUE*TAU = TAU + ETA** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 80 J = 1, IITEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI80 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / DELTA( N )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +$ ABS( TAU )*( DPSI+DPHI )*W = RHOINV + PHI + PSI90 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged*INFO = 1DLAM = D( I ) + TAUGO TO 250** End for the case I = N*ELSE** The case for I < N*NITER = 1IP1 = I + 1** Calculate initial guess*DEL = D( IP1 ) - D( I )MIDPT = DEL / TWODO 100 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - MIDPT100 CONTINUE*PSI = ZERODO 110 J = 1, I - 1PSI = PSI + Z( J )*Z( J ) / DELTA( J )110 CONTINUE*PHI = ZERODO 120 J = N, I + 2, -1PHI = PHI + Z( J )*Z( J ) / DELTA( J )120 CONTINUEC = RHOINV + PSI + PHIW = C + Z( I )*Z( I ) / DELTA( I ) +$ Z( IP1 )*Z( IP1 ) / DELTA( IP1 )*IF( W.GT.ZERO ) THEN** d(i)< the ith eigenvalue < (d(i)+d(i+1))/2** We choose d(i) as origin.*ORGATI = .TRUE.A = C*DEL + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )B = Z( I )*Z( I )*DELIF( A.GT.ZERO ) THENTAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )ELSETAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )END IFDLTLB = ZERODLTUB = MIDPTELSE** (d(i)+d(i+1))/2 <= the ith eigenvalue < d(i+1)** We choose d(i+1) as origin.*ORGATI = .FALSE.A = C*DEL - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )B = Z( IP1 )*Z( IP1 )*DELIF( A.LT.ZERO ) THENTAU = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )ELSETAU = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )END IFDLTLB = -MIDPTDLTUB = ZEROEND IF*IF( ORGATI ) THENDO 130 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - TAU130 CONTINUEELSEDO 140 J = 1, NDELTA( J ) = ( D( J )-D( IP1 ) ) - TAU140 CONTINUEEND IFIF( ORGATI ) THENII = IELSEII = I + 1END IFIIM1 = II - 1IIP1 = II + 1** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 150 J = 1, IIM1TEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI150 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 160 J = N, IIP1, -1TEMP = Z( J ) / DELTA( J )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI160 CONTINUE*W = RHOINV + PHI + PSI** W is the value of the secular function with* its ii-th element removed.*SWTCH3 = .FALSE.IF( ORGATI ) THENIF( W.LT.ZERO )$ SWTCH3 = .TRUE.ELSEIF( W.GT.ZERO )$ SWTCH3 = .TRUE.END IFIF( II.EQ.1 .OR. II.EQ.N )$ SWTCH3 = .FALSE.*TEMP = Z( II ) / DELTA( II )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = W + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +$ THREE*ABS( TEMP ) + ABS( TAU )*DW** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENIF( ORGATI ) THENDLAM = D( I ) + TAUELSEDLAM = D( IP1 ) + TAUEND IFGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*NITER = NITER + 1IF( .NOT.SWTCH3 ) THENIF( ORGATI ) THENC = W - DELTA( IP1 )*DW - ( D( I )-D( IP1 ) )*$ ( Z( I ) / DELTA( I ) )**2ELSEC = W - DELTA( I )*DW - ( D( IP1 )-D( I ) )*$ ( Z( IP1 ) / DELTA( IP1 ) )**2END IFA = ( DELTA( I )+DELTA( IP1 ) )*W -$ DELTA( I )*DELTA( IP1 )*DWB = DELTA( I )*DELTA( IP1 )*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DELTA( IP1 )*DELTA( IP1 )*$ ( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) + DELTA( I )*DELTA( I )*$ ( DPSI+DPHI )END IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFELSE** Interpolation using THREE most relevant poles*TEMP = RHOINV + PSI + PHIIF( ORGATI ) THENTEMP1 = Z( IIM1 ) / DELTA( IIM1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIP1 )*( DPSI+DPHI ) -$ ( D( IIM1 )-D( IIP1 ) )*TEMP1ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )ZZ( 3 ) = DELTA( IIP1 )*DELTA( IIP1 )*$ ( ( DPSI-TEMP1 )+DPHI )ELSETEMP1 = Z( IIP1 ) / DELTA( IIP1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIM1 )*( DPSI+DPHI ) -$ ( D( IIP1 )-D( IIM1 ) )*TEMP1ZZ( 1 ) = DELTA( IIM1 )*DELTA( IIM1 )*$ ( DPSI+( DPHI-TEMP1 ) )ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )END IFZZ( 2 ) = Z( II )*Z( II )CALL DLAED6( NITER, ORGATI, C, DELTA( IIM1 ), ZZ, W, ETA,$ INFO )IF( INFO.NE.0 )$ GO TO 250END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GE.ZERO )$ ETA = -W / DWTEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IF*PREW = W*170 CONTINUEDO 180 J = 1, NDELTA( J ) = DELTA( J ) - ETA180 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 190 J = 1, IIM1TEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI190 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 200 J = N, IIP1, -1TEMP = Z( J ) / DELTA( J )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI200 CONTINUE*TEMP = Z( II ) / DELTA( II )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = RHOINV + PHI + PSI + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +$ THREE*ABS( TEMP ) + ABS( TAU+ETA )*DW*SWTCH = .FALSE.IF( ORGATI ) THENIF( -W.GT.ABS( PREW ) / TEN )$ SWTCH = .TRUE.ELSEIF( W.GT.ABS( PREW ) / TEN )$ SWTCH = .TRUE.END IF*TAU = TAU + ETA** Main loop to update the values of the array DELTA*ITER = NITER + 1*DO 240 NITER = ITER, MAXIT** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENIF( ORGATI ) THENDLAM = D( I ) + TAUELSEDLAM = D( IP1 ) + TAUEND IFGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*IF( .NOT.SWTCH3 ) THENIF( .NOT.SWTCH ) THENIF( ORGATI ) THENC = W - DELTA( IP1 )*DW -$ ( D( I )-D( IP1 ) )*( Z( I ) / DELTA( I ) )**2ELSEC = W - DELTA( I )*DW - ( D( IP1 )-D( I ) )*$ ( Z( IP1 ) / DELTA( IP1 ) )**2END IFELSETEMP = Z( II ) / DELTA( II )IF( ORGATI ) THENDPSI = DPSI + TEMP*TEMPELSEDPHI = DPHI + TEMP*TEMPEND IFC = W - DELTA( I )*DPSI - DELTA( IP1 )*DPHIEND IFA = ( DELTA( I )+DELTA( IP1 ) )*W -$ DELTA( I )*DELTA( IP1 )*DWB = DELTA( I )*DELTA( IP1 )*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( .NOT.SWTCH ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DELTA( IP1 )*$ DELTA( IP1 )*( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) +$ DELTA( I )*DELTA( I )*( DPSI+DPHI )END IFELSEA = DELTA( I )*DELTA( I )*DPSI +$ DELTA( IP1 )*DELTA( IP1 )*DPHIEND IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFELSE** Interpolation using THREE most relevant poles*TEMP = RHOINV + PSI + PHIIF( SWTCH ) THENC = TEMP - DELTA( IIM1 )*DPSI - DELTA( IIP1 )*DPHIZZ( 1 ) = DELTA( IIM1 )*DELTA( IIM1 )*DPSIZZ( 3 ) = DELTA( IIP1 )*DELTA( IIP1 )*DPHIELSEIF( ORGATI ) THENTEMP1 = Z( IIM1 ) / DELTA( IIM1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIP1 )*( DPSI+DPHI ) -$ ( D( IIM1 )-D( IIP1 ) )*TEMP1ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )ZZ( 3 ) = DELTA( IIP1 )*DELTA( IIP1 )*$ ( ( DPSI-TEMP1 )+DPHI )ELSETEMP1 = Z( IIP1 ) / DELTA( IIP1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIM1 )*( DPSI+DPHI ) -$ ( D( IIP1 )-D( IIM1 ) )*TEMP1ZZ( 1 ) = DELTA( IIM1 )*DELTA( IIM1 )*$ ( DPSI+( DPHI-TEMP1 ) )ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )END IFEND IFCALL DLAED6( NITER, ORGATI, C, DELTA( IIM1 ), ZZ, W, ETA,$ INFO )IF( INFO.NE.0 )$ GO TO 250END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GE.ZERO )$ ETA = -W / DWTEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IF*DO 210 J = 1, NDELTA( J ) = DELTA( J ) - ETA210 CONTINUE*TAU = TAU + ETAPREW = W** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 220 J = 1, IIM1TEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI220 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 230 J = N, IIP1, -1TEMP = Z( J ) / DELTA( J )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI230 CONTINUE*TEMP = Z( II ) / DELTA( II )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = RHOINV + PHI + PSI + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +$ THREE*ABS( TEMP ) + ABS( TAU )*DWIF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )$ SWTCH = .NOT.SWTCH*240 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged*INFO = 1IF( ORGATI ) THENDLAM = D( I ) + TAUELSEDLAM = D( IP1 ) + TAUEND IF*END IF*250 CONTINUE*RETURN** End of DLAED4*ENDSUBROUTINE DLAED5( I, D, Z, DELTA, RHO, DLAM )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Oak Ridge National Lab, Argonne National Lab,* Courant Institute, NAG Ltd., and Rice University* September 30, 1994** .. Scalar Arguments ..INTEGER IDOUBLE PRECISION DLAM, RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( 2 ), DELTA( 2 ), Z( 2 )* ..** Purpose* =======** This subroutine computes the I-th eigenvalue of a symmetric rank-one* modification of a 2-by-2 diagonal matrix** diag( D ) + RHO * Z * transpose(Z) .** The diagonal elements in the array D are assumed to satisfy** D(i) < D(j) for i < j .** We also assume RHO > 0 and that the Euclidean norm of the vector* Z is one.** Arguments* =========** I (input) INTEGER* The index of the eigenvalue to be computed. I = 1 or I = 2.** D (input) DOUBLE PRECISION array, dimension (2)* The original eigenvalues. We assume D(1) < D(2).** Z (input) DOUBLE PRECISION array, dimension (2)* The components of the updating vector.** DELTA (output) DOUBLE PRECISION array, dimension (2)* The vector DELTA contains the information necessary* to construct the eigenvectors.** RHO (input) DOUBLE PRECISION* The scalar in the symmetric updating formula.** DLAM (output) DOUBLE PRECISION* The computed lambda_I, the I-th updated eigenvalue.** Further Details* ===============** Based on contributions by* Ren-Cang Li, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, FOURPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ FOUR = 4.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION B, C, DEL, TAU, TEMP, W* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*DEL = D( 2 ) - D( 1 )IF( I.EQ.1 ) THENW = ONE + TWO*RHO*( Z( 2 )*Z( 2 )-Z( 1 )*Z( 1 ) ) / DELIF( W.GT.ZERO ) THENB = DEL + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 1 )*Z( 1 )*DEL** B > ZERO, always*TAU = TWO*C / ( B+SQRT( ABS( B*B-FOUR*C ) ) )DLAM = D( 1 ) + TAUDELTA( 1 ) = -Z( 1 ) / TAUDELTA( 2 ) = Z( 2 ) / ( DEL-TAU )ELSEB = -DEL + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 2 )*Z( 2 )*DELIF( B.GT.ZERO ) THENTAU = -TWO*C / ( B+SQRT( B*B+FOUR*C ) )ELSETAU = ( B-SQRT( B*B+FOUR*C ) ) / TWOEND IFDLAM = D( 2 ) + TAUDELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )DELTA( 2 ) = -Z( 2 ) / TAUEND IFTEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )DELTA( 1 ) = DELTA( 1 ) / TEMPDELTA( 2 ) = DELTA( 2 ) / TEMPELSE** Now I=2*B = -DEL + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 2 )*Z( 2 )*DELIF( B.GT.ZERO ) THENTAU = ( B+SQRT( B*B+FOUR*C ) ) / TWOELSETAU = TWO*C / ( -B+SQRT( B*B+FOUR*C ) )END IFDLAM = D( 2 ) + TAUDELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )DELTA( 2 ) = -Z( 2 ) / TAUTEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )DELTA( 1 ) = DELTA( 1 ) / TEMPDELTA( 2 ) = DELTA( 2 ) / TEMPEND IFRETURN** End OF DLAED5*ENDSUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Oak Ridge National Lab, Argonne National Lab,* Courant Institute, NAG Ltd., and Rice University* June 30, 1999** .. Scalar Arguments ..LOGICAL ORGATIINTEGER INFO, KNITERDOUBLE PRECISION FINIT, RHO, TAU* ..* .. Array Arguments ..DOUBLE PRECISION D( 3 ), Z( 3 )* ..** Purpose* =======** DLAED6 computes the positive or negative root (closest to the origin)* of* z(1) z(2) z(3)* f(x) = rho + --------- + ---------- + ---------* d(1)-x d(2)-x d(3)-x** It is assumed that** if ORGATI = .true. the root is between d(2) and d(3);* otherwise it is between d(1) and d(2)** This routine will be called by DLAED4 when necessary. In most cases,* the root sought is the smallest in magnitude, though it might not be* in some extremely rare situations.** Arguments* =========** KNITER (input) INTEGER* Refer to DLAED4 for its significance.** ORGATI (input) LOGICAL* If ORGATI is true, the needed root is between d(2) and* d(3); otherwise it is between d(1) and d(2). See* DLAED4 for further details.** RHO (input) DOUBLE PRECISION* Refer to the equation f(x) above.** D (input) DOUBLE PRECISION array, dimension (3)* D satisfies d(1) < d(2) < d(3).** Z (input) DOUBLE PRECISION array, dimension (3)* Each of the elements in z must be positive.** FINIT (input) DOUBLE PRECISION* The value of f at 0. It is more accurate than the one* evaluated inside this routine (if someone wants to do* so).** TAU (output) DOUBLE PRECISION* The root of the equation f(x).** INFO (output) INTEGER* = 0: successful exit* > 0: if INFO = 1, failure to converge** Further Details* ===============** Based on contributions by* Ren-Cang Li, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..INTEGER MAXITPARAMETER ( MAXIT = 20 )DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHTPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Local Arrays ..DOUBLE PRECISION DSCALE( 3 ), ZSCALE( 3 )* ..* .. Local Scalars ..LOGICAL FIRST, SCALEINTEGER I, ITER, NITERDOUBLE PRECISION A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,$ FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,$ SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4* ..* .. Save statement ..SAVE FIRST, SMALL1, SMINV1, SMALL2, SMINV2, EPS* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT* ..* .. Data statements ..DATA FIRST / .TRUE. /* ..* .. Executable Statements ..*INFO = 0*NITER = 1TAU = ZEROIF( KNITER.EQ.2 ) THENIF( ORGATI ) THENTEMP = ( D( 3 )-D( 2 ) ) / TWOC = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )ELSETEMP = ( D( 1 )-D( 2 ) ) / TWOC = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )END IFTEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )A = A / TEMPB = B / TEMPC = C / TEMPIF( C.EQ.ZERO ) THENTAU = B / AELSE IF( A.LE.ZERO ) THENTAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSETAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFTEMP = RHO + Z( 1 ) / ( D( 1 )-TAU ) +$ Z( 2 ) / ( D( 2 )-TAU ) + Z( 3 ) / ( D( 3 )-TAU )IF( ABS( FINIT ).LE.ABS( TEMP ) )$ TAU = ZEROEND IF** On first call to routine, get machine parameters for* possible scaling to avoid overflow*IF( FIRST ) THENEPS = DLAMCH( 'Epsilon' )BASE = DLAMCH( 'Base' )SMALL1 = BASE**( INT( LOG( DLAMCH( 'SafMin' ) ) / LOG( BASE ) /$ THREE ) )SMINV1 = ONE / SMALL1SMALL2 = SMALL1*SMALL1SMINV2 = SMINV1*SMINV1FIRST = .FALSE.END IF** Determine if scaling of inputs necessary to avoid overflow* when computing 1/TEMP**3*IF( ORGATI ) THENTEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )ELSETEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )END IFSCALE = .FALSE.IF( TEMP.LE.SMALL1 ) THENSCALE = .TRUE.IF( TEMP.LE.SMALL2 ) THEN** Scale up by power of radix nearest 1/SAFMIN**(2/3)*SCLFAC = SMINV2SCLINV = SMALL2ELSE** Scale up by power of radix nearest 1/SAFMIN**(1/3)*SCLFAC = SMINV1SCLINV = SMALL1END IF** Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)*DO 10 I = 1, 3DSCALE( I ) = D( I )*SCLFACZSCALE( I ) = Z( I )*SCLFAC10 CONTINUETAU = TAU*SCLFACELSE** Copy D and Z to DSCALE and ZSCALE*DO 20 I = 1, 3DSCALE( I ) = D( I )ZSCALE( I ) = Z( I )20 CONTINUEEND IF*FC = ZERODF = ZERODDF = ZERODO 30 I = 1, 3TEMP = ONE / ( DSCALE( I )-TAU )TEMP1 = ZSCALE( I )*TEMPTEMP2 = TEMP1*TEMPTEMP3 = TEMP2*TEMPFC = FC + TEMP1 / DSCALE( I )DF = DF + TEMP2DDF = DDF + TEMP330 CONTINUEF = FINIT + TAU*FC*IF( ABS( F ).LE.ZERO )$ GO TO 60** Iteration begins** It is not hard to see that** 1) Iterations will go up monotonically* if FINIT < 0;** 2) Iterations will go down monotonically* if FINIT > 0.*ITER = NITER + 1*DO 50 NITER = ITER, MAXIT*IF( ORGATI ) THENTEMP1 = DSCALE( 2 ) - TAUTEMP2 = DSCALE( 3 ) - TAUELSETEMP1 = DSCALE( 1 ) - TAUTEMP2 = DSCALE( 2 ) - TAUEND IFA = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DFB = TEMP1*TEMP2*FC = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDFTEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )A = A / TEMPB = B / TEMPC = C / TEMPIF( C.EQ.ZERO ) THENETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFIF( F*ETA.GE.ZERO ) THENETA = -F / DFEND IF*TEMP = ETA + TAUIF( ORGATI ) THENIF( ETA.GT.ZERO .AND. TEMP.GE.DSCALE( 3 ) )$ ETA = ( DSCALE( 3 )-TAU ) / TWOIF( ETA.LT.ZERO .AND. TEMP.LE.DSCALE( 2 ) )$ ETA = ( DSCALE( 2 )-TAU ) / TWOELSEIF( ETA.GT.ZERO .AND. TEMP.GE.DSCALE( 2 ) )$ ETA = ( DSCALE( 2 )-TAU ) / TWOIF( ETA.LT.ZERO .AND. TEMP.LE.DSCALE( 1 ) )$ ETA = ( DSCALE( 1 )-TAU ) / TWOEND IFTAU = TAU + ETA*FC = ZEROERRETM = ZERODF = ZERODDF = ZERODO 40 I = 1, 3TEMP = ONE / ( DSCALE( I )-TAU )TEMP1 = ZSCALE( I )*TEMPTEMP2 = TEMP1*TEMPTEMP3 = TEMP2*TEMPTEMP4 = TEMP1 / DSCALE( I )FC = FC + TEMP4ERRETM = ERRETM + ABS( TEMP4 )DF = DF + TEMP2DDF = DDF + TEMP340 CONTINUEF = FINIT + TAU*FCERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +$ ABS( TAU )*DFIF( ABS( F ).LE.EPS*ERRETM )$ GO TO 6050 CONTINUEINFO = 160 CONTINUE** Undo scaling*IF( SCALE )$ TAU = TAU*SCLINVRETURN** End of DLAED6*ENDSUBROUTINE DLAED7( ICOMPQ, N, QSIZ, TLVLS, CURLVL, CURPBM, D, Q,$ LDQ, INDXQ, RHO, CUTPNT, QSTORE, QPTR, PRMPTR,$ PERM, GIVPTR, GIVCOL, GIVNUM, WORK, IWORK,$ INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..INTEGER CURLVL, CURPBM, CUTPNT, ICOMPQ, INFO, LDQ, N,$ QSIZ, TLVLSDOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER GIVCOL( 2, * ), GIVPTR( * ), INDXQ( * ),$ IWORK( * ), PERM( * ), PRMPTR( * ), QPTR( * )DOUBLE PRECISION D( * ), GIVNUM( 2, * ), Q( LDQ, * ),$ QSTORE( * ), WORK( * )* ..** Purpose* =======** DLAED7 computes the updated eigensystem of a diagonal* matrix after modification by a rank-one symmetric matrix. This* routine is used only for the eigenproblem which requires all* eigenvalues and optionally eigenvectors of a dense symmetric matrix* that has been reduced to tridiagonal form. DLAED1 handles* the case in which all eigenvalues and eigenvectors of a symmetric* tridiagonal matrix are desired.** T = Q(in) ( D(in) + RHO * Z*Z' ) Q'(in) = Q(out) * D(out) * Q'(out)** where Z = Q'u, u is a vector of length N with ones in the* CUTPNT and CUTPNT + 1 th elements and zeros elsewhere.** The eigenvectors of the original matrix are stored in Q, and the* eigenvalues are in D. The algorithm consists of three stages:** The first stage consists of deflating the size of the problem* when there are multiple eigenvalues or if there is a zero in* the Z vector. For each such occurence the dimension of the* secular equation problem is reduced by one. This stage is* performed by the routine DLAED8.** The second stage consists of calculating the updated* eigenvalues. This is done by finding the roots of the secular* equation via the routine DLAED4 (as called by DLAED9).* This routine also calculates the eigenvectors of the current* problem.** The final stage consists of computing the updated eigenvectors* directly using the updated eigenvalues. The eigenvectors for* the current problem are multiplied with the eigenvectors from* the overall problem.** Arguments* =========** ICOMPQ (input) INTEGER* = 0: Compute eigenvalues only.* = 1: Compute eigenvectors of original dense symmetric matrix* also. On entry, Q contains the orthogonal matrix used* to reduce the original matrix to tridiagonal form.** N (input) INTEGER* The dimension of the symmetric tridiagonal matrix. N >= 0.** QSIZ (input) INTEGER* The dimension of the orthogonal matrix used to reduce* the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1.** TLVLS (input) INTEGER* The total number of merging levels in the overall divide and* conquer tree.** CURLVL (input) INTEGER* The current level in the overall merge routine,* 0 <= CURLVL <= TLVLS.** CURPBM (input) INTEGER* The current problem in the current level in the overall* merge routine (counting from upper left to lower right).** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the eigenvalues of the rank-1-perturbed matrix.* On exit, the eigenvalues of the repaired matrix.** Q (input/output) DOUBLE PRECISION array, dimension (LDQ, N)* On entry, the eigenvectors of the rank-1-perturbed matrix.* On exit, the eigenvectors of the repaired tridiagonal matrix.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N).** INDXQ (output) INTEGER array, dimension (N)* The permutation which will reintegrate the subproblem just* solved back into sorted order, i.e., D( INDXQ( I = 1, N ) )* will be in ascending order.** RHO (input) DOUBLE PRECISION* The subdiagonal element used to create the rank-1* modification.** CUTPNT (input) INTEGER* Contains the location of the last eigenvalue in the leading* sub-matrix. min(1,N) <= CUTPNT <= N.** QSTORE (input/output) DOUBLE PRECISION array, dimension (N**2+1)* Stores eigenvectors of submatrices encountered during* divide and conquer, packed together. QPTR points to* beginning of the submatrices.** QPTR (input/output) INTEGER array, dimension (N+2)* List of indices pointing to beginning of submatrices stored* in QSTORE. The submatrices are numbered starting at the* bottom left of the divide and conquer tree, from left to* right and bottom to top.** PRMPTR (input) INTEGER array, dimension (N lg N)* Contains a list of pointers which indicate where in PERM a* level's permutation is stored. PRMPTR(i+1) - PRMPTR(i)* indicates the size of the permutation and also the size of* the full, non-deflated problem.** PERM (input) INTEGER array, dimension (N lg N)* Contains the permutations (from deflation and sorting) to be* applied to each eigenblock.** GIVPTR (input) INTEGER array, dimension (N lg N)* Contains a list of pointers which indicate where in GIVCOL a* level's Givens rotations are stored. GIVPTR(i+1) - GIVPTR(i)* indicates the number of Givens rotations.** GIVCOL (input) INTEGER array, dimension (2, N lg N)* Each pair of numbers indicates a pair of columns to take place* in a Givens rotation.** GIVNUM (input) DOUBLE PRECISION array, dimension (2, N lg N)* Each number indicates the S value to be used in the* corresponding Givens rotation.** WORK (workspace) DOUBLE PRECISION array, dimension (3*N+QSIZ*N)** IWORK (workspace) INTEGER array, dimension (4*N)** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: if INFO = 1, an eigenvalue did not converge** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER COLTYP, CURR, I, IDLMDA, INDX, INDXC, INDXP,$ IQ2, IS, IW, IZ, K, LDQ2, N1, N2, PTR* ..* .. External Subroutines ..EXTERNAL DGEMM, DLAED8, DLAED9, DLAEDA, DLAMRG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ICOMPQ.LT.0 .OR. ICOMPQ.GT.1 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ICOMPQ.EQ.1 .AND. QSIZ.LT.N ) THENINFO = -4ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( MIN( 1, N ).GT.CUTPNT .OR. N.LT.CUTPNT ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED7', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** The following values are for bookkeeping purposes only. They are* integer pointers which indicate the portion of the workspace* used by a particular array in DLAED8 and DLAED9.*IF( ICOMPQ.EQ.1 ) THENLDQ2 = QSIZELSELDQ2 = NEND IF*IZ = 1IDLMDA = IZ + NIW = IDLMDA + NIQ2 = IW + NIS = IQ2 + N*LDQ2*INDX = 1INDXC = INDX + NCOLTYP = INDXC + NINDXP = COLTYP + N** Form the z-vector which consists of the last row of Q_1 and the* first row of Q_2.*PTR = 1 + 2**TLVLSDO 10 I = 1, CURLVL - 1PTR = PTR + 2**( TLVLS-I )10 CONTINUECURR = PTR + CURPBMCALL DLAEDA( N, TLVLS, CURLVL, CURPBM, PRMPTR, PERM, GIVPTR,$ GIVCOL, GIVNUM, QSTORE, QPTR, WORK( IZ ),$ WORK( IZ+N ), INFO )** When solving the final problem, we no longer need the stored data,* so we will overwrite the data from this level onto the previously* used storage space.*IF( CURLVL.EQ.TLVLS ) THENQPTR( CURR ) = 1PRMPTR( CURR ) = 1GIVPTR( CURR ) = 1END IF** Sort and Deflate eigenvalues.*CALL DLAED8( ICOMPQ, K, N, QSIZ, D, Q, LDQ, INDXQ, RHO, CUTPNT,$ WORK( IZ ), WORK( IDLMDA ), WORK( IQ2 ), LDQ2,$ WORK( IW ), PERM( PRMPTR( CURR ) ), GIVPTR( CURR+1 ),$ GIVCOL( 1, GIVPTR( CURR ) ),$ GIVNUM( 1, GIVPTR( CURR ) ), IWORK( INDXP ),$ IWORK( INDX ), INFO )PRMPTR( CURR+1 ) = PRMPTR( CURR ) + NGIVPTR( CURR+1 ) = GIVPTR( CURR+1 ) + GIVPTR( CURR )** Solve Secular Equation.*IF( K.NE.0 ) THENCALL DLAED9( K, 1, K, N, D, WORK( IS ), K, RHO, WORK( IDLMDA ),$ WORK( IW ), QSTORE( QPTR( CURR ) ), K, INFO )IF( INFO.NE.0 )$ GO TO 30IF( ICOMPQ.EQ.1 ) THENCALL DGEMM( 'N', 'N', QSIZ, K, K, ONE, WORK( IQ2 ), LDQ2,$ QSTORE( QPTR( CURR ) ), K, ZERO, Q, LDQ )END IFQPTR( CURR+1 ) = QPTR( CURR ) + K**2** Prepare the INDXQ sorting permutation.*N1 = KN2 = N - KCALL DLAMRG( N1, N2, D, 1, -1, INDXQ )ELSEQPTR( CURR+1 ) = QPTR( CURR )DO 20 I = 1, NINDXQ( I ) = I20 CONTINUEEND IF*30 CONTINUERETURN** End of DLAED7*ENDSUBROUTINE DLAED8( ICOMPQ, K, N, QSIZ, D, Q, LDQ, INDXQ, RHO,$ CUTPNT, Z, DLAMDA, Q2, LDQ2, W, PERM, GIVPTR,$ GIVCOL, GIVNUM, INDXP, INDX, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Oak Ridge National Lab, Argonne National Lab,* Courant Institute, NAG Ltd., and Rice University* September 30, 1994** .. Scalar Arguments ..INTEGER CUTPNT, GIVPTR, ICOMPQ, INFO, K, LDQ, LDQ2, N,$ QSIZDOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER GIVCOL( 2, * ), INDX( * ), INDXP( * ),$ INDXQ( * ), PERM( * )DOUBLE PRECISION D( * ), DLAMDA( * ), GIVNUM( 2, * ),$ Q( LDQ, * ), Q2( LDQ2, * ), W( * ), Z( * )* ..** Purpose* =======** DLAED8 merges the two sets of eigenvalues together into a single* sorted set. Then it tries to deflate the size of the problem.* There are two ways in which deflation can occur: when two or more* eigenvalues are close together or if there is a tiny element in the* Z vector. For each such occurrence the order of the related secular* equation problem is reduced by one.** Arguments* =========** ICOMPQ (input) INTEGER* = 0: Compute eigenvalues only.* = 1: Compute eigenvectors of original dense symmetric matrix* also. On entry, Q contains the orthogonal matrix used* to reduce the original matrix to tridiagonal form.** K (output) INTEGER* The number of non-deflated eigenvalues, and the order of the* related secular equation.** N (input) INTEGER* The dimension of the symmetric tridiagonal matrix. N >= 0.** QSIZ (input) INTEGER* The dimension of the orthogonal matrix used to reduce* the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the eigenvalues of the two submatrices to be* combined. On exit, the trailing (N-K) updated eigenvalues* (those which were deflated) sorted into increasing order.** Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N)* If ICOMPQ = 0, Q is not referenced. Otherwise,* on entry, Q contains the eigenvectors of the partially solved* system which has been previously updated in matrix* multiplies with other partially solved eigensystems.* On exit, Q contains the trailing (N-K) updated eigenvectors* (those which were deflated) in its last N-K columns.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N).** INDXQ (input) INTEGER array, dimension (N)* The permutation which separately sorts the two sub-problems* in D into ascending order. Note that elements in the second* half of this permutation must first have CUTPNT added to* their values in order to be accurate.** RHO (input/output) DOUBLE PRECISION* On entry, the off-diagonal element associated with the rank-1* cut which originally split the two submatrices which are now* being recombined.* On exit, RHO has been modified to the value required by* DLAED3.** CUTPNT (input) INTEGER* The location of the last eigenvalue in the leading* sub-matrix. min(1,N) <= CUTPNT <= N.** Z (input) DOUBLE PRECISION array, dimension (N)* On entry, Z contains the updating vector (the last row of* the first sub-eigenvector matrix and the first row of the* second sub-eigenvector matrix).* On exit, the contents of Z are destroyed by the updating* process.** DLAMDA (output) DOUBLE PRECISION array, dimension (N)* A copy of the first K eigenvalues which will be used by* DLAED3 to form the secular equation.** Q2 (output) DOUBLE PRECISION array, dimension (LDQ2,N)* If ICOMPQ = 0, Q2 is not referenced. Otherwise,* a copy of the first K eigenvectors which will be used by* DLAED7 in a matrix multiply (DGEMM) to update the new* eigenvectors.** LDQ2 (input) INTEGER* The leading dimension of the array Q2. LDQ2 >= max(1,N).** W (output) DOUBLE PRECISION array, dimension (N)* The first k values of the final deflation-altered z-vector and* will be passed to DLAED3.** PERM (output) INTEGER array, dimension (N)* The permutations (from deflation and sorting) to be applied* to each eigenblock.** GIVPTR (output) INTEGER* The number of Givens rotations which took place in this* subproblem.** GIVCOL (output) INTEGER array, dimension (2, N)* Each pair of numbers indicates a pair of columns to take place* in a Givens rotation.** GIVNUM (output) DOUBLE PRECISION array, dimension (2, N)* Each number indicates the S value to be used in the* corresponding Givens rotation.** INDXP (workspace) INTEGER array, dimension (N)* The permutation used to place deflated values of D at the end* of the array. INDXP(1:K) points to the nondeflated D-values* and INDXP(K+1:N) points to the deflated eigenvalues.** INDX (workspace) INTEGER array, dimension (N)* The permutation used to sort the contents of D into ascending* order.** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION MONE, ZERO, ONE, TWO, EIGHTPARAMETER ( MONE = -1.0D0, ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, EIGHT = 8.0D0 )* ..* .. Local Scalars ..*INTEGER I, IMAX, J, JLAM, JMAX, JP, K2, N1, N1P1, N2DOUBLE PRECISION C, EPS, S, T, TAU, TOL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL IDAMAX, DLAMCH, DLAPY2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAMRG, DROT, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ICOMPQ.LT.0 .OR. ICOMPQ.GT.1 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ICOMPQ.EQ.1 .AND. QSIZ.LT.N ) THENINFO = -4ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( CUTPNT.LT.MIN( 1, N ) .OR. CUTPNT.GT.N ) THENINFO = -10ELSE IF( LDQ2.LT.MAX( 1, N ) ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED8', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*N1 = CUTPNTN2 = N - N1N1P1 = N1 + 1*IF( RHO.LT.ZERO ) THENCALL DSCAL( N2, MONE, Z( N1P1 ), 1 )END IF** Normalize z so that norm(z) = 1*T = ONE / SQRT( TWO )DO 10 J = 1, NINDX( J ) = J10 CONTINUECALL DSCAL( N, T, Z, 1 )RHO = ABS( TWO*RHO )** Sort the eigenvalues into increasing order*DO 20 I = CUTPNT + 1, NINDXQ( I ) = INDXQ( I ) + CUTPNT20 CONTINUEDO 30 I = 1, NDLAMDA( I ) = D( INDXQ( I ) )W( I ) = Z( INDXQ( I ) )30 CONTINUEI = 1J = CUTPNT + 1CALL DLAMRG( N1, N2, DLAMDA, 1, 1, INDX )DO 40 I = 1, ND( I ) = DLAMDA( INDX( I ) )Z( I ) = W( INDX( I ) )40 CONTINUE** Calculate the allowable deflation tolerence*IMAX = IDAMAX( N, Z, 1 )JMAX = IDAMAX( N, D, 1 )EPS = DLAMCH( 'Epsilon' )TOL = EIGHT*EPS*ABS( D( JMAX ) )** If the rank-1 modifier is small enough, no more needs to be done* except to reorganize Q so that its columns correspond with the* elements in D.*IF( RHO*ABS( Z( IMAX ) ).LE.TOL ) THENK = 0IF( ICOMPQ.EQ.0 ) THENDO 50 J = 1, NPERM( J ) = INDXQ( INDX( J ) )50 CONTINUEELSEDO 60 J = 1, NPERM( J ) = INDXQ( INDX( J ) )CALL DCOPY( QSIZ, Q( 1, PERM( J ) ), 1, Q2( 1, J ), 1 )60 CONTINUECALL DLACPY( 'A', QSIZ, N, Q2( 1, 1 ), LDQ2, Q( 1, 1 ),$ LDQ )END IFRETURNEND IF** If there are multiple eigenvalues then the problem deflates. Here* the number of equal eigenvalues are found. As each equal* eigenvalue is found, an elementary reflector is computed to rotate* the corresponding eigensubspace so that the corresponding* components of Z are zero in this new basis.*K = 0GIVPTR = 0K2 = N + 1DO 70 J = 1, NIF( RHO*ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1INDXP( K2 ) = JIF( J.EQ.N )$ GO TO 110ELSEJLAM = JGO TO 80END IF70 CONTINUE80 CONTINUEJ = J + 1IF( J.GT.N )$ GO TO 100IF( RHO*ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1INDXP( K2 ) = JELSE** Check if eigenvalues are close enough to allow deflation.*S = Z( JLAM )C = Z( J )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.*TAU = DLAPY2( C, S )T = D( J ) - D( JLAM )C = C / TAUS = -S / TAUIF( ABS( T*C*S ).LE.TOL ) THEN** Deflation is possible.*Z( J ) = TAUZ( JLAM ) = ZERO** Record the appropriate Givens rotation*GIVPTR = GIVPTR + 1GIVCOL( 1, GIVPTR ) = INDXQ( INDX( JLAM ) )GIVCOL( 2, GIVPTR ) = INDXQ( INDX( J ) )GIVNUM( 1, GIVPTR ) = CGIVNUM( 2, GIVPTR ) = SIF( ICOMPQ.EQ.1 ) THENCALL DROT( QSIZ, Q( 1, INDXQ( INDX( JLAM ) ) ), 1,$ Q( 1, INDXQ( INDX( J ) ) ), 1, C, S )END IFT = D( JLAM )*C*C + D( J )*S*SD( J ) = D( JLAM )*S*S + D( J )*C*CD( JLAM ) = TK2 = K2 - 1I = 190 CONTINUEIF( K2+I.LE.N ) THENIF( D( JLAM ).LT.D( INDXP( K2+I ) ) ) THENINDXP( K2+I-1 ) = INDXP( K2+I )INDXP( K2+I ) = JLAMI = I + 1GO TO 90ELSEINDXP( K2+I-1 ) = JLAMEND IFELSEINDXP( K2+I-1 ) = JLAMEND IFJLAM = JELSEK = K + 1W( K ) = Z( JLAM )DLAMDA( K ) = D( JLAM )INDXP( K ) = JLAMJLAM = JEND IFEND IFGO TO 80100 CONTINUE** Record the last eigenvalue.*K = K + 1W( K ) = Z( JLAM )DLAMDA( K ) = D( JLAM )INDXP( K ) = JLAM*110 CONTINUE** Sort the eigenvalues and corresponding eigenvectors into DLAMDA* and Q2 respectively. The eigenvalues/vectors which were not* deflated go into the first K slots of DLAMDA and Q2 respectively,* while those which were deflated go into the last N - K slots.*IF( ICOMPQ.EQ.0 ) THENDO 120 J = 1, NJP = INDXP( J )DLAMDA( J ) = D( JP )PERM( J ) = INDXQ( INDX( JP ) )120 CONTINUEELSEDO 130 J = 1, NJP = INDXP( J )DLAMDA( J ) = D( JP )PERM( J ) = INDXQ( INDX( JP ) )CALL DCOPY( QSIZ, Q( 1, PERM( J ) ), 1, Q2( 1, J ), 1 )130 CONTINUEEND IF** The deflated eigenvalues and their corresponding vectors go back* into the last N - K slots of D and Q respectively.*IF( K.LT.N ) THENIF( ICOMPQ.EQ.0 ) THENCALL DCOPY( N-K, DLAMDA( K+1 ), 1, D( K+1 ), 1 )ELSECALL DCOPY( N-K, DLAMDA( K+1 ), 1, D( K+1 ), 1 )CALL DLACPY( 'A', QSIZ, N-K, Q2( 1, K+1 ), LDQ2,$ Q( 1, K+1 ), LDQ )END IFEND IF*RETURN** End of DLAED8*ENDSUBROUTINE DLAED9( K, KSTART, KSTOP, N, D, Q, LDQ, RHO, DLAMDA, W,$ S, LDS, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Oak Ridge National Lab, Argonne National Lab,* Courant Institute, NAG Ltd., and Rice University* September 30, 1994** .. Scalar Arguments ..INTEGER INFO, K, KSTART, KSTOP, LDQ, LDS, NDOUBLE PRECISION RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), S( LDS, * ),$ W( * )* ..** Purpose* =======** DLAED9 finds the roots of the secular equation, as defined by the* values in D, Z, and RHO, between KSTART and KSTOP. It makes the* appropriate calls to DLAED4 and then stores the new matrix of* eigenvectors for use in calculating the next level of Z vectors.** Arguments* =========** K (input) INTEGER* The number of terms in the rational function to be solved by* DLAED4. K >= 0.** KSTART (input) INTEGER* KSTOP (input) INTEGER* The updated eigenvalues Lambda(I), KSTART <= I <= KSTOP* are to be computed. 1 <= KSTART <= KSTOP <= K.** N (input) INTEGER* The number of rows and columns in the Q matrix.* N >= K (delation may result in N > K).** D (output) DOUBLE PRECISION array, dimension (N)* D(I) contains the updated eigenvalues* for KSTART <= I <= KSTOP.** Q (workspace) DOUBLE PRECISION array, dimension (LDQ,N)** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max( 1, N ).** RHO (input) DOUBLE PRECISION* The value of the parameter in the rank one update equation.* RHO >= 0 required.** DLAMDA (input) DOUBLE PRECISION array, dimension (K)* The first K elements of this array contain the old roots* of the deflated updating problem. These are the poles* of the secular equation.** W (input) DOUBLE PRECISION array, dimension (K)* The first K elements of this array contain the components* of the deflation-adjusted updating vector.** S (output) DOUBLE PRECISION array, dimension (LDS, K)* Will contain the eigenvectors of the repaired matrix which* will be stored for subsequent Z vector calculation and* multiplied by the previously accumulated eigenvectors* to update the system.** LDS (input) INTEGER* The leading dimension of S. LDS >= max( 1, K ).** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: if INFO = 1, an eigenvalue did not converge** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Local Scalars ..INTEGER I, JDOUBLE PRECISION TEMP* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAED4, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( K.LT.0 ) THENINFO = -1ELSE IF( KSTART.LT.1 .OR. KSTART.GT.MAX( 1, K ) ) THENINFO = -2ELSE IF( MAX( 1, KSTOP ).LT.KSTART .OR. KSTOP.GT.MAX( 1, K ) )$ THENINFO = -3ELSE IF( N.LT.K ) THENINFO = -4ELSE IF( LDQ.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDS.LT.MAX( 1, K ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED9', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.0 )$ RETURN** Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can* be computed with high relative accuracy (barring over/underflow).* This is a problem on machines without a guard digit in* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).* The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I),* which on any of these machines zeros out the bottommost* bit of DLAMDA(I) if it is 1; this makes the subsequent* subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation* occurs. On binary machines with a guard digit (almost all* machines) it does not change DLAMDA(I) at all. On hexadecimal* and decimal machines with a guard digit, it slightly* changes the bottommost bits of DLAMDA(I). It does not account* for hexadecimal or decimal machines without guard digits* (we know of none). We use a subroutine call to compute* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating* this code.*DO 10 I = 1, NDLAMDA( I ) = DLAMC3( DLAMDA( I ), DLAMDA( I ) ) - DLAMDA( I )10 CONTINUE*DO 20 J = KSTART, KSTOPCALL DLAED4( K, J, DLAMDA, W, Q( 1, J ), RHO, D( J ), INFO )** If the zero finder fails, the computation is terminated.*IF( INFO.NE.0 )$ GO TO 12020 CONTINUE*IF( K.EQ.1 .OR. K.EQ.2 ) THENDO 40 I = 1, KDO 30 J = 1, KS( J, I ) = Q( J, I )30 CONTINUE40 CONTINUEGO TO 120END IF** Compute updated W.*CALL DCOPY( K, W, 1, S, 1 )** Initialize W(I) = Q(I,I)*CALL DCOPY( K, Q, LDQ+1, W, 1 )DO 70 J = 1, KDO 50 I = 1, J - 1W( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )50 CONTINUEDO 60 I = J + 1, KW( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )60 CONTINUE70 CONTINUEDO 80 I = 1, KW( I ) = SIGN( SQRT( -W( I ) ), S( I, 1 ) )80 CONTINUE** Compute eigenvectors of the modified rank-1 modification.*DO 110 J = 1, KDO 90 I = 1, KQ( I, J ) = W( I ) / Q( I, J )90 CONTINUETEMP = DNRM2( K, Q( 1, J ), 1 )DO 100 I = 1, KS( I, J ) = Q( I, J ) / TEMP100 CONTINUE110 CONTINUE*120 CONTINUERETURN** End of DLAED9*ENDSUBROUTINE DLAEDA( N, TLVLS, CURLVL, CURPBM, PRMPTR, PERM, GIVPTR,$ GIVCOL, GIVNUM, Q, QPTR, Z, ZTEMP, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..INTEGER CURLVL, CURPBM, INFO, N, TLVLS* ..* .. Array Arguments ..INTEGER GIVCOL( 2, * ), GIVPTR( * ), PERM( * ),$ PRMPTR( * ), QPTR( * )DOUBLE PRECISION GIVNUM( 2, * ), Q( * ), Z( * ), ZTEMP( * )* ..** Purpose* =======** DLAEDA computes the Z vector corresponding to the merge step in the* CURLVLth step of the merge process with TLVLS steps for the CURPBMth* problem.** Arguments* =========** N (input) INTEGER* The dimension of the symmetric tridiagonal matrix. N >= 0.** TLVLS (input) INTEGER* The total number of merging levels in the overall divide and* conquer tree.** CURLVL (input) INTEGER* The current level in the overall merge routine,* 0 <= curlvl <= tlvls.** CURPBM (input) INTEGER* The current problem in the current level in the overall* merge routine (counting from upper left to lower right).** PRMPTR (input) INTEGER array, dimension (N lg N)* Contains a list of pointers which indicate where in PERM a* level's permutation is stored. PRMPTR(i+1) - PRMPTR(i)* indicates the size of the permutation and incidentally the* size of the full, non-deflated problem.** PERM (input) INTEGER array, dimension (N lg N)* Contains the permutations (from deflation and sorting) to be* applied to each eigenblock.** GIVPTR (input) INTEGER array, dimension (N lg N)* Contains a list of pointers which indicate where in GIVCOL a* level's Givens rotations are stored. GIVPTR(i+1) - GIVPTR(i)* indicates the number of Givens rotations.** GIVCOL (input) INTEGER array, dimension (2, N lg N)* Each pair of numbers indicates a pair of columns to take place* in a Givens rotation.** GIVNUM (input) DOUBLE PRECISION array, dimension (2, N lg N)* Each number indicates the S value to be used in the* corresponding Givens rotation.** Q (input) DOUBLE PRECISION array, dimension (N**2)* Contains the square eigenblocks from previous levels, the* starting positions for blocks are given by QPTR.** QPTR (input) INTEGER array, dimension (N+2)* Contains a list of pointers which indicate where in Q an* eigenblock is stored. SQRT( QPTR(i+1) - QPTR(i) ) indicates* the size of the block.** Z (output) DOUBLE PRECISION array, dimension (N)* On output this vector contains the updating vector (the last* row of the first sub-eigenvector matrix and the first row of* the second sub-eigenvector matrix).** ZTEMP (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** Based on contributions by* Jeff Rutter, Computer Science Division, University of California* at Berkeley, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER BSIZ1, BSIZ2, CURR, I, K, MID, PSIZ1, PSIZ2,$ PTR, ZPTR1* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, INT, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -1END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAEDA', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine location of first number in second half.*MID = N / 2 + 1** Gather last/first rows of appropriate eigenblocks into center of Z*PTR = 1** Determine location of lowest level subproblem in the full storage* scheme*CURR = PTR + CURPBM*2**CURLVL + 2**( CURLVL-1 ) - 1** Determine size of these matrices. We add HALF to the value of* the SQRT in case the machine underestimates one of these square* roots.*BSIZ1 = INT( HALF+SQRT( DBLE( QPTR( CURR+1 )-QPTR( CURR ) ) ) )BSIZ2 = INT( HALF+SQRT( DBLE( QPTR( CURR+2 )-QPTR( CURR+1 ) ) ) )DO 10 K = 1, MID - BSIZ1 - 1Z( K ) = ZERO10 CONTINUECALL DCOPY( BSIZ1, Q( QPTR( CURR )+BSIZ1-1 ), BSIZ1,$ Z( MID-BSIZ1 ), 1 )CALL DCOPY( BSIZ2, Q( QPTR( CURR+1 ) ), BSIZ2, Z( MID ), 1 )DO 20 K = MID + BSIZ2, NZ( K ) = ZERO20 CONTINUE** Loop thru remaining levels 1 -> CURLVL applying the Givens* rotations and permutation and then multiplying the center matrices* against the current Z.*PTR = 2**TLVLS + 1DO 70 K = 1, CURLVL - 1CURR = PTR + CURPBM*2**( CURLVL-K ) + 2**( CURLVL-K-1 ) - 1PSIZ1 = PRMPTR( CURR+1 ) - PRMPTR( CURR )PSIZ2 = PRMPTR( CURR+2 ) - PRMPTR( CURR+1 )ZPTR1 = MID - PSIZ1** Apply Givens at CURR and CURR+1*DO 30 I = GIVPTR( CURR ), GIVPTR( CURR+1 ) - 1CALL DROT( 1, Z( ZPTR1+GIVCOL( 1, I )-1 ), 1,$ Z( ZPTR1+GIVCOL( 2, I )-1 ), 1, GIVNUM( 1, I ),$ GIVNUM( 2, I ) )30 CONTINUEDO 40 I = GIVPTR( CURR+1 ), GIVPTR( CURR+2 ) - 1CALL DROT( 1, Z( MID-1+GIVCOL( 1, I ) ), 1,$ Z( MID-1+GIVCOL( 2, I ) ), 1, GIVNUM( 1, I ),$ GIVNUM( 2, I ) )40 CONTINUEPSIZ1 = PRMPTR( CURR+1 ) - PRMPTR( CURR )PSIZ2 = PRMPTR( CURR+2 ) - PRMPTR( CURR+1 )DO 50 I = 0, PSIZ1 - 1ZTEMP( I+1 ) = Z( ZPTR1+PERM( PRMPTR( CURR )+I )-1 )50 CONTINUEDO 60 I = 0, PSIZ2 - 1ZTEMP( PSIZ1+I+1 ) = Z( MID+PERM( PRMPTR( CURR+1 )+I )-1 )60 CONTINUE** Multiply Blocks at CURR and CURR+1** Determine size of these matrices. We add HALF to the value of* the SQRT in case the machine underestimates one of these* square roots.*BSIZ1 = INT( HALF+SQRT( DBLE( QPTR( CURR+1 )-QPTR( CURR ) ) ) )BSIZ2 = INT( HALF+SQRT( DBLE( QPTR( CURR+2 )-QPTR( CURR+$ 1 ) ) ) )IF( BSIZ1.GT.0 ) THENCALL DGEMV( 'T', BSIZ1, BSIZ1, ONE, Q( QPTR( CURR ) ),$ BSIZ1, ZTEMP( 1 ), 1, ZERO, Z( ZPTR1 ), 1 )END IFCALL DCOPY( PSIZ1-BSIZ1, ZTEMP( BSIZ1+1 ), 1, Z( ZPTR1+BSIZ1 ),$ 1 )IF( BSIZ2.GT.0 ) THENCALL DGEMV( 'T', BSIZ2, BSIZ2, ONE, Q( QPTR( CURR+1 ) ),$ BSIZ2, ZTEMP( PSIZ1+1 ), 1, ZERO, Z( MID ), 1 )END IFCALL DCOPY( PSIZ2-BSIZ2, ZTEMP( PSIZ1+BSIZ2+1 ), 1,$ Z( MID+BSIZ2 ), 1 )*PTR = PTR + 2**( TLVLS-K )70 CONTINUE*RETURN** End of DLAEDA*ENDSUBROUTINE DLAGTF( N, A, LAMBDA, B, C, TOL, D, IN, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, NDOUBLE PRECISION LAMBDA, TOL* ..* .. Array Arguments ..INTEGER IN( * )DOUBLE PRECISION A( * ), B( * ), C( * ), D( * )* ..** Purpose* =======** DLAGTF factorizes the matrix (T - lambda*I), where T is an n by n* tridiagonal matrix and lambda is a scalar, as** T - lambda*I = PLU,** where P is a permutation matrix, L is a unit lower tridiagonal matrix* with at most one non-zero sub-diagonal elements per column and U is* an upper triangular matrix with at most two non-zero super-diagonal* elements per column.** The factorization is obtained by Gaussian elimination with partial* pivoting and implicit row scaling.** The parameter LAMBDA is included in the routine so that DLAGTF may* be used, in conjunction with DLAGTS, to obtain eigenvectors of T by* inverse iteration.** Arguments* =========** N (input) INTEGER* The order of the matrix T.** A (input/output) DOUBLE PRECISION array, dimension (N)* On entry, A must contain the diagonal elements of T.** On exit, A is overwritten by the n diagonal elements of the* upper triangular matrix U of the factorization of T.** LAMBDA (input) DOUBLE PRECISION* On entry, the scalar lambda.** B (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, B must contain the (n-1) super-diagonal elements of* T.** On exit, B is overwritten by the (n-1) super-diagonal* elements of the matrix U of the factorization of T.** C (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, C must contain the (n-1) sub-diagonal elements of* T.** On exit, C is overwritten by the (n-1) sub-diagonal elements* of the matrix L of the factorization of T.** TOL (input) DOUBLE PRECISION* On entry, a relative tolerance used to indicate whether or* not the matrix (T - lambda*I) is nearly singular. TOL should* normally be chose as approximately the largest relative error* in the elements of T. For example, if the elements of T are* correct to about 4 significant figures, then TOL should be* set to about 5*10**(-4). If TOL is supplied as less than eps,* where eps is the relative machine precision, then the value* eps is used in place of TOL.** D (output) DOUBLE PRECISION array, dimension (N-2)* On exit, D is overwritten by the (n-2) second super-diagonal* elements of the matrix U of the factorization of T.** IN (output) INTEGER array, dimension (N)* On exit, IN contains details of the permutation matrix P. If* an interchange occurred at the kth step of the elimination,* then IN(k) = 1, otherwise IN(k) = 0. The element IN(n)* returns the smallest positive integer j such that** abs( u(j,j) ).le. norm( (T - lambda*I)(j) )*TOL,** where norm( A(j) ) denotes the sum of the absolute values of* the jth row of the matrix A. If no such j exists then IN(n)* is returned as zero. If IN(n) is returned as positive, then a* diagonal element of U is small, indicating that* (T - lambda*I) is singular or nearly singular,** INFO (output) INTEGER* = 0 : successful exit* .lt. 0: if INFO = -k, the kth argument had an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER KDOUBLE PRECISION EPS, MULT, PIV1, PIV2, SCALE1, SCALE2, TEMP, TL* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DLAGTF', -INFO )RETURNEND IF*IF( N.EQ.0 )$ RETURN*A( 1 ) = A( 1 ) - LAMBDAIN( N ) = 0IF( N.EQ.1 ) THENIF( A( 1 ).EQ.ZERO )$ IN( 1 ) = 1RETURNEND IF*EPS = DLAMCH( 'Epsilon' )*TL = MAX( TOL, EPS )SCALE1 = ABS( A( 1 ) ) + ABS( B( 1 ) )DO 10 K = 1, N - 1A( K+1 ) = A( K+1 ) - LAMBDASCALE2 = ABS( C( K ) ) + ABS( A( K+1 ) )IF( K.LT.( N-1 ) )$ SCALE2 = SCALE2 + ABS( B( K+1 ) )IF( A( K ).EQ.ZERO ) THENPIV1 = ZEROELSEPIV1 = ABS( A( K ) ) / SCALE1END IFIF( C( K ).EQ.ZERO ) THENIN( K ) = 0PIV2 = ZEROSCALE1 = SCALE2IF( K.LT.( N-1 ) )$ D( K ) = ZEROELSEPIV2 = ABS( C( K ) ) / SCALE2IF( PIV2.LE.PIV1 ) THENIN( K ) = 0SCALE1 = SCALE2C( K ) = C( K ) / A( K )A( K+1 ) = A( K+1 ) - C( K )*B( K )IF( K.LT.( N-1 ) )$ D( K ) = ZEROELSEIN( K ) = 1MULT = A( K ) / C( K )A( K ) = C( K )TEMP = A( K+1 )A( K+1 ) = B( K ) - MULT*TEMPIF( K.LT.( N-1 ) ) THEND( K ) = B( K+1 )B( K+1 ) = -MULT*D( K )END IFB( K ) = TEMPC( K ) = MULTEND IFEND IFIF( ( MAX( PIV1, PIV2 ).LE.TL ) .AND. ( IN( N ).EQ.0 ) )$ IN( N ) = K10 CONTINUEIF( ( ABS( A( N ) ).LE.SCALE1*TL ) .AND. ( IN( N ).EQ.0 ) )$ IN( N ) = N*RETURN** End of DLAGTF*ENDSUBROUTINE DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,$ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,$ POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* December 1, 1999** .. Scalar Arguments ..INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,$ LDGNUM, NL, NR, NRHS, SQREDOUBLE PRECISION C, S* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), PERM( * )DOUBLE PRECISION B( LDB, * ), BX( LDBX, * ), DIFL( * ),$ DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),$ POLES( LDGNUM, * ), WORK( * ), Z( * )* ..** Purpose* =======** DLALS0 applies back the multiplying factors of either the left or the* right singular vector matrix of a diagonal matrix appended by a row* to the right hand side matrix B in solving the least squares problem* using the divide-and-conquer SVD approach.** For the left singular vector matrix, three types of orthogonal* matrices are involved:** (1L) Givens rotations: the number of such rotations is GIVPTR; the* pairs of columns/rows they were applied to are stored in GIVCOL;* and the C- and S-values of these rotations are stored in GIVNUM.** (2L) Permutation. The (NL+1)-st row of B is to be moved to the first* row, and for J=2:N, PERM(J)-th row of B is to be moved to the* J-th row.** (3L) The left singular vector matrix of the remaining matrix.** For the right singular vector matrix, four types of orthogonal* matrices are involved:** (1R) The right singular vector matrix of the remaining matrix.** (2R) If SQRE = 1, one extra Givens rotation to generate the right* null space.** (3R) The inverse transformation of (2L).** (4R) The inverse transformation of (1L).** Arguments* =========** ICOMPQ (input) INTEGER* Specifies whether singular vectors are to be computed in* factored form:* = 0: Left singular vector matrix.* = 1: Right singular vector matrix.** NL (input) INTEGER* The row dimension of the upper block. NL >= 1.** NR (input) INTEGER* The row dimension of the lower block. NR >= 1.** SQRE (input) INTEGER* = 0: the lower block is an NR-by-NR square matrix.* = 1: the lower block is an NR-by-(NR+1) rectangular matrix.** The bidiagonal matrix has row dimension N = NL + NR + 1,* and column dimension M = N + SQRE.** NRHS (input) INTEGER* The number of columns of B and BX. NRHS must be at least 1.** B (input/output) DOUBLE PRECISION array, dimension ( LDB, NRHS )* On input, B contains the right hand sides of the least* squares problem in rows 1 through M. On output, B contains* the solution X in rows 1 through N.** LDB (input) INTEGER* The leading dimension of B. LDB must be at least* max(1,MAX( M, N ) ).** BX (workspace) DOUBLE PRECISION array, dimension ( LDBX, NRHS )** LDBX (input) INTEGER* The leading dimension of BX.** PERM (input) INTEGER array, dimension ( N )* The permutations (from deflation and sorting) applied* to the two blocks.** GIVPTR (input) INTEGER* The number of Givens rotations which took place in this* subproblem.** GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 )* Each pair of numbers indicates a pair of rows/columns* involved in a Givens rotation.** LDGCOL (input) INTEGER* The leading dimension of GIVCOL, must be at least N.** GIVNUM (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )* Each number indicates the C or S value used in the* corresponding Givens rotation.** LDGNUM (input) INTEGER* The leading dimension of arrays DIFR, POLES and* GIVNUM, must be at least K.** POLES (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 )* On entry, POLES(1:K, 1) contains the new singular* values obtained from solving the secular equation, and* POLES(1:K, 2) is an array containing the poles in the secular* equation.** DIFL (input) DOUBLE PRECISION array, dimension ( K ).* On entry, DIFL(I) is the distance between I-th updated* (undeflated) singular value and the I-th (undeflated) old* singular value.** DIFR (input) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ).* On entry, DIFR(I, 1) contains the distances between I-th* updated (undeflated) singular value and the I+1-th* (undeflated) old singular value. And DIFR(I, 2) is the* normalizing factor for the I-th right singular vector.** Z (input) DOUBLE PRECISION array, dimension ( K )* Contain the components of the deflation-adjusted updating row* vector.** K (input) INTEGER* Contains the dimension of the non-deflated matrix,* This is the order of the related secular equation. 1 <= K <=N.** C (input) DOUBLE PRECISION* C contains garbage if SQRE =0 and the C-value of a Givens* rotation related to the right null space if SQRE = 1.** S (input) DOUBLE PRECISION* S contains garbage if SQRE =0 and the S-value of a Givens* rotation related to the right null space if SQRE = 1.** WORK (workspace) DOUBLE PRECISION array, dimension ( K )** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** Based on contributions by* Ming Gu and Ren-Cang Li, Computer Science Division, University of* California at Berkeley, USA* Osni Marques, LBNL/NERSC, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZERO, NEGONEPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0, NEGONE = -1.0D0 )* ..* .. Local Scalars ..INTEGER I, J, M, N, NLP1DOUBLE PRECISION DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DLACPY, DLASCL, DROT, DSCAL,$ XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( NL.LT.1 ) THENINFO = -2ELSE IF( NR.LT.1 ) THENINFO = -3ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -4END IF*N = NL + NR + 1*IF( NRHS.LT.1 ) THENINFO = -5ELSE IF( LDB.LT.N ) THENINFO = -7ELSE IF( LDBX.LT.N ) THENINFO = -9ELSE IF( GIVPTR.LT.0 ) THENINFO = -11ELSE IF( LDGCOL.LT.N ) THENINFO = -13ELSE IF( LDGNUM.LT.N ) THENINFO = -15ELSE IF( K.LT.1 ) THENINFO = -20END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLALS0', -INFO )RETURNEND IF*M = N + SQRENLP1 = NL + 1*IF( ICOMPQ.EQ.0 ) THEN** Apply back orthogonal transformations from the left.** Step (1L): apply back the Givens rotations performed.*DO 10 I = 1, GIVPTRCALL DROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,$ B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),$ GIVNUM( I, 1 ) )10 CONTINUE** Step (2L): permute rows of B.*CALL DCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )DO 20 I = 2, NCALL DCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )20 CONTINUE** Step (3L): apply the inverse of the left singular vector* matrix to BX.*IF( K.EQ.1 ) THENCALL DCOPY( NRHS, BX, LDBX, B, LDB )IF( Z( 1 ).LT.ZERO ) THENCALL DSCAL( NRHS, NEGONE, B, LDB )END IFELSEDO 50 J = 1, KDIFLJ = DIFL( J )DJ = POLES( J, 1 )DSIGJ = -POLES( J, 2 )IF( J.LT.K ) THENDIFRJ = -DIFR( J, 1 )DSIGJP = -POLES( J+1, 2 )END IFIF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )$ THENWORK( J ) = ZEROELSEWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /$ ( POLES( J, 2 )+DJ )END IFDO 30 I = 1, J - 1IF( ( Z( I ).EQ.ZERO ) .OR.$ ( POLES( I, 2 ).EQ.ZERO ) ) THENWORK( I ) = ZEROELSEWORK( I ) = POLES( I, 2 )*Z( I ) /$ ( DLAMC3( POLES( I, 2 ), DSIGJ )-$ DIFLJ ) / ( POLES( I, 2 )+DJ )END IF30 CONTINUEDO 40 I = J + 1, KIF( ( Z( I ).EQ.ZERO ) .OR.$ ( POLES( I, 2 ).EQ.ZERO ) ) THENWORK( I ) = ZEROELSEWORK( I ) = POLES( I, 2 )*Z( I ) /$ ( DLAMC3( POLES( I, 2 ), DSIGJP )+$ DIFRJ ) / ( POLES( I, 2 )+DJ )END IF40 CONTINUEWORK( 1 ) = NEGONETEMP = DNRM2( K, WORK, 1 )CALL DGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,$ B( J, 1 ), LDB )CALL DLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),$ LDB, INFO )50 CONTINUEEND IF** Move the deflated rows of BX to B also.*IF( K.LT.MAX( M, N ) )$ CALL DLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,$ B( K+1, 1 ), LDB )ELSE** Apply back the right orthogonal transformations.** Step (1R): apply back the new right singular vector matrix* to B.*IF( K.EQ.1 ) THENCALL DCOPY( NRHS, B, LDB, BX, LDBX )ELSEDO 80 J = 1, KDSIGJ = POLES( J, 2 )IF( Z( J ).EQ.ZERO ) THENWORK( J ) = ZEROELSEWORK( J ) = -Z( J ) / DIFL( J ) /$ ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )END IFDO 60 I = 1, J - 1IF( Z( J ).EQ.ZERO ) THENWORK( I ) = ZEROELSEWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I+1,$ 2 ) )-DIFR( I, 1 ) ) /$ ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )END IF60 CONTINUEDO 70 I = J + 1, KIF( Z( J ).EQ.ZERO ) THENWORK( I ) = ZEROELSEWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I,$ 2 ) )-DIFL( I ) ) /$ ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )END IF70 CONTINUECALL DGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,$ BX( J, 1 ), LDBX )80 CONTINUEEND IF** Step (2R): if SQRE = 1, apply back the rotation that is* related to the right null space of the subproblem.*IF( SQRE.EQ.1 ) THENCALL DCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )CALL DROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )END IFIF( K.LT.MAX( M, N ) )$ CALL DLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),$ LDBX )** Step (3R): permute rows of B.*CALL DCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )IF( SQRE.EQ.1 ) THENCALL DCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )END IFDO 90 I = 2, NCALL DCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )90 CONTINUE** Step (4R): apply back the Givens rotations performed.*DO 100 I = GIVPTR, 1, -1CALL DROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,$ B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),$ -GIVNUM( I, 1 ) )100 CONTINUEEND IF*RETURN** End of DLALS0*ENDSUBROUTINE DLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,$ LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,$ GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK,$ IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,$ SMLSIZ* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),$ K( * ), PERM( LDGCOL, * )DOUBLE PRECISION B( LDB, * ), BX( LDBX, * ), C( * ),$ DIFL( LDU, * ), DIFR( LDU, * ),$ GIVNUM( LDU, * ), POLES( LDU, * ), S( * ),$ U( LDU, * ), VT( LDU, * ), WORK( * ),$ Z( LDU, * )* ..** Purpose* =======** DLALSA is an itermediate step in solving the least squares problem* by computing the SVD of the coefficient matrix in compact form (The* singular vectors are computed as products of simple orthorgonal* matrices.).** If ICOMPQ = 0, DLALSA applies the inverse of the left singular vector* matrix of an upper bidiagonal matrix to the right hand side; and if* ICOMPQ = 1, DLALSA applies the right singular vector matrix to the* right hand side. The singular vector matrices were generated in* compact form by DLALSA.** Arguments* =========*** ICOMPQ (input) INTEGER* Specifies whether the left or the right singular vector* matrix is involved.* = 0: Left singular vector matrix* = 1: Right singular vector matrix** SMLSIZ (input) INTEGER* The maximum size of the subproblems at the bottom of the* computation tree.** N (input) INTEGER* The row and column dimensions of the upper bidiagonal matrix.** NRHS (input) INTEGER* The number of columns of B and BX. NRHS must be at least 1.** B (input) DOUBLE PRECISION array, dimension ( LDB, NRHS )* On input, B contains the right hand sides of the least* squares problem in rows 1 through M. On output, B contains* the solution X in rows 1 through N.** LDB (input) INTEGER* The leading dimension of B in the calling subprogram.* LDB must be at least max(1,MAX( M, N ) ).** BX (output) DOUBLE PRECISION array, dimension ( LDBX, NRHS )* On exit, the result of applying the left or right singular* vector matrix to B.** LDBX (input) INTEGER* The leading dimension of BX.** U (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ ).* On entry, U contains the left singular vector matrices of all* subproblems at the bottom level.** LDU (input) INTEGER, LDU = > N.* The leading dimension of arrays U, VT, DIFL, DIFR,* POLES, GIVNUM, and Z.** VT (input) DOUBLE PRECISION array, dimension ( LDU, SMLSIZ+1 ).* On entry, VT' contains the right singular vector matrices of* all subproblems at the bottom level.** K (input) INTEGER array, dimension ( N ).** DIFL (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ).* where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.** DIFR (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).* On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record* distances between singular values on the I-th level and* singular values on the (I -1)-th level, and DIFR(*, 2 * I)* record the normalizing factors of the right singular vectors* matrices of subproblems on I-th level.** Z (input) DOUBLE PRECISION array, dimension ( LDU, NLVL ).* On entry, Z(1, I) contains the components of the deflation-* adjusted updating row vector for subproblems on the I-th* level.** POLES (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).* On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old* singular values involved in the secular equations on the I-th* level.** GIVPTR (input) INTEGER array, dimension ( N ).* On entry, GIVPTR( I ) records the number of Givens* rotations performed on the I-th problem on the computation* tree.** GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ).* On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the* locations of Givens rotations performed on the I-th level on* the computation tree.** LDGCOL (input) INTEGER, LDGCOL = > N.* The leading dimension of arrays GIVCOL and PERM.** PERM (input) INTEGER array, dimension ( LDGCOL, NLVL ).* On entry, PERM(*, I) records permutations done on the I-th* level of the computation tree.** GIVNUM (input) DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).* On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-* values of Givens rotations performed on the I-th level on the* computation tree.** C (input) DOUBLE PRECISION array, dimension ( N ).* On entry, if the I-th subproblem is not square,* C( I ) contains the C-value of a Givens rotation related to* the right null space of the I-th subproblem.** S (input) DOUBLE PRECISION array, dimension ( N ).* On entry, if the I-th subproblem is not square,* S( I ) contains the S-value of a Givens rotation related to* the right null space of the I-th subproblem.** WORK (workspace) DOUBLE PRECISION array.* The dimension must be at least N.** IWORK (workspace) INTEGER array.* The dimension must be at least 3 * N** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** Based on contributions by* Ming Gu and Ren-Cang Li, Computer Science Division, University of* California at Berkeley, USA* Osni Marques, LBNL/NERSC, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER I, I1, IC, IM1, INODE, J, LF, LL, LVL, LVL2,$ ND, NDB1, NDIML, NDIMR, NL, NLF, NLP1, NLVL,$ NR, NRF, NRP1, SQRE* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLALS0, DLASDT, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( SMLSIZ.LT.3 ) THENINFO = -2ELSE IF( N.LT.SMLSIZ ) THENINFO = -3ELSE IF( NRHS.LT.1 ) THENINFO = -4ELSE IF( LDB.LT.N ) THENINFO = -6ELSE IF( LDBX.LT.N ) THENINFO = -8ELSE IF( LDU.LT.N ) THENINFO = -10ELSE IF( LDGCOL.LT.N ) THENINFO = -19END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLALSA', -INFO )RETURNEND IF** Book-keeping and setting up the computation tree.*INODE = 1NDIML = INODE + NNDIMR = NDIML + N*CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),$ IWORK( NDIMR ), SMLSIZ )** The following code applies back the left singular vector factors.* For applying back the right singular vector factors, go to 50.*IF( ICOMPQ.EQ.1 ) THENGO TO 50END IF** The nodes on the bottom level of the tree were solved* by DLASDQ. The corresponding left and right singular vector* matrices are in explicit form. First apply back the left* singular vector matrices.*NDB1 = ( ND+1 ) / 2DO 10 I = NDB1, ND** IC : center row of each node* NL : number of rows of left subproblem* NR : number of rows of right subproblem* NLF: starting row of the left subproblem* NRF: starting row of the right subproblem*I1 = I - 1IC = IWORK( INODE+I1 )NL = IWORK( NDIML+I1 )NR = IWORK( NDIMR+I1 )NLF = IC - NLNRF = IC + 1CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,$ B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,$ B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )10 CONTINUE** Next copy the rows of B that correspond to unchanged rows* in the bidiagonal matrix to BX.*DO 20 I = 1, NDIC = IWORK( INODE+I-1 )CALL DCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )20 CONTINUE** Finally go through the left singular vector matrices of all* the other subproblems bottom-up on the tree.*J = 2**NLVLSQRE = 0*DO 40 LVL = NLVL, 1, -1LVL2 = 2*LVL - 1** find the first node LF and last node LL on* the current level LVL*IF( LVL.EQ.1 ) THENLF = 1LL = 1ELSELF = 2**( LVL-1 )LL = 2*LF - 1END IFDO 30 I = LF, LLIM1 = I - 1IC = IWORK( INODE+IM1 )NL = IWORK( NDIML+IM1 )NR = IWORK( NDIMR+IM1 )NLF = IC - NLNRF = IC + 1J = J - 1CALL DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,$ B( NLF, 1 ), LDB, PERM( NLF, LVL ),$ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,$ GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),$ DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),$ Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,$ INFO )30 CONTINUE40 CONTINUEGO TO 90** ICOMPQ = 1: applying back the right singular vector factors.*50 CONTINUE** First now go through the right singular vector matrices of all* the tree nodes top-down.*J = 0DO 70 LVL = 1, NLVLLVL2 = 2*LVL - 1** Find the first node LF and last node LL on* the current level LVL.*IF( LVL.EQ.1 ) THENLF = 1LL = 1ELSELF = 2**( LVL-1 )LL = 2*LF - 1END IFDO 60 I = LL, LF, -1IM1 = I - 1IC = IWORK( INODE+IM1 )NL = IWORK( NDIML+IM1 )NR = IWORK( NDIMR+IM1 )NLF = IC - NLNRF = IC + 1IF( I.EQ.LL ) THENSQRE = 0ELSESQRE = 1END IFJ = J + 1CALL DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,$ BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),$ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,$ GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),$ DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),$ Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,$ INFO )60 CONTINUE70 CONTINUE** The nodes on the bottom level of the tree were solved* by DLASDQ. The corresponding right singular vector* matrices are in explicit form. Apply them back.*NDB1 = ( ND+1 ) / 2DO 80 I = NDB1, NDI1 = I - 1IC = IWORK( INODE+I1 )NL = IWORK( NDIML+I1 )NR = IWORK( NDIMR+I1 )NLP1 = NL + 1IF( I.EQ.ND ) THENNRP1 = NRELSENRP1 = NR + 1END IFNLF = IC - NLNRF = IC + 1CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,$ B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,$ B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )80 CONTINUE*90 CONTINUE*RETURN** End of DLALSA*ENDSUBROUTINE DLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,$ RANK, WORK, IWORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, N, NRHS, RANK, SMLSIZDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION B( LDB, * ), D( * ), E( * ), WORK( * )* ..** Purpose* =======** DLALSD uses the singular value decomposition of A to solve the least* squares problem of finding X to minimize the Euclidean norm of each* column of A*X-B, where A is N-by-N upper bidiagonal, and X and B* are N-by-NRHS. The solution X overwrites B.** The singular values of A smaller than RCOND times the largest* singular value are treated as zero in solving the least squares* problem; in this case a minimum norm solution is returned.* The actual singular values are returned in D in ascending order.** This code makes very mild assumptions about floating point* arithmetic. It will work on machines with a guard digit in* add/subtract, or on those binary machines without guard digits* which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.* It could conceivably fail on hexadecimal or decimal machines* without guard digits, but we know of none.** Arguments* =========** UPLO (input) CHARACTER*1* = 'U': D and E define an upper bidiagonal matrix.* = 'L': D and E define a lower bidiagonal matrix.** SMLSIZ (input) INTEGER* The maximum size of the subproblems at the bottom of the* computation tree.** N (input) INTEGER* The dimension of the bidiagonal matrix. N >= 0.** NRHS (input) INTEGER* The number of columns of B. NRHS must be at least 1.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry D contains the main diagonal of the bidiagonal* matrix. On exit, if INFO = 0, D contains its singular values.** E (input) DOUBLE PRECISION array, dimension (N-1)* Contains the super-diagonal entries of the bidiagonal matrix.* On exit, E has been destroyed.** B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)* On input, B contains the right hand sides of the least* squares problem. On output, B contains the solution X.** LDB (input) INTEGER* The leading dimension of B in the calling subprogram.* LDB must be at least max(1,N).** RCOND (input) DOUBLE PRECISION* The singular values of A less than or equal to RCOND times* the largest singular value are treated as zero in solving* the least squares problem. If RCOND is negative,* machine precision is used instead.* For example, if diag(S)*X=B were the least squares problem,* where diag(S) is a diagonal matrix of singular values, the* solution would be X(i) = B(i) / S(i) if S(i) is greater than* RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to* RCOND*max(S).** RANK (output) INTEGER* The number of singular values of A greater than RCOND times* the largest singular value.** WORK (workspace) DOUBLE PRECISION array, dimension at least* (9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2),* where NLVL = max(0, INT(log_2 (N/(SMLSIZ+1))) + 1).** IWORK (workspace) INTEGER array, dimension at least* (3*N*NLVL + 11*N)** INFO (output) INTEGER* = 0: successful exit.* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: The algorithm failed to compute an singular value while* working on the submatrix lying in rows and columns* INFO/(N+1) through MOD(INFO,N+1).** Further Details* ===============** Based on contributions by* Ming Gu and Ren-Cang Li, Computer Science Division, University of* California at Berkeley, USA* Osni Marques, LBNL/NERSC, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )* ..* .. Local Scalars ..INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,$ GIVPTR, I, ICMPQ1, ICMPQ2, IWK, J, K, NLVL,$ NM1, NSIZE, NSUB, NWORK, PERM, POLES, S, SIZEI,$ SMLSZP, SQRE, ST, ST1, U, VT, ZDOUBLE PRECISION CS, EPS, ORGNRM, R, SN, TOL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL IDAMAX, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLALSA, DLARTG, DLASCL,$ DLASDA, DLASDQ, DLASET, DLASRT, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, SIGN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.1 ) THENINFO = -4ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLALSD', -INFO )RETURNEND IF*EPS = DLAMCH( 'Epsilon' )** Set up the tolerance.*IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THENRCOND = EPSEND IF*RANK = 0** Quick return if possible.*IF( N.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THENIF( D( 1 ).EQ.ZERO ) THENCALL DLASET( 'A', 1, NRHS, ZERO, ZERO, B, LDB )ELSERANK = 1CALL DLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )D( 1 ) = ABS( D( 1 ) )END IFRETURNEND IF** Rotate the matrix if it is lower bidiagonal.*IF( UPLO.EQ.'L' ) THENDO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )IF( NRHS.EQ.1 ) THENCALL DROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )ELSEWORK( I*2-1 ) = CSWORK( I*2 ) = SNEND IF10 CONTINUEIF( NRHS.GT.1 ) THENDO 30 I = 1, NRHSDO 20 J = 1, N - 1CS = WORK( J*2-1 )SN = WORK( J*2 )CALL DROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )20 CONTINUE30 CONTINUEEND IFEND IF** Scale.*NM1 = N - 1ORGNRM = DLANST( 'M', N, D, E )IF( ORGNRM.EQ.ZERO ) THENCALL DLASET( 'A', N, NRHS, ZERO, ZERO, B, LDB )RETURNEND IF*CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )** If N is smaller than the minimum divide size SMLSIZ, then solve* the problem with another solver.*IF( N.LE.SMLSIZ ) THENNWORK = 1 + N*NCALL DLASET( 'A', N, N, ZERO, ONE, WORK, N )CALL DLASDQ( 'U', 0, N, N, 0, NRHS, D, E, WORK, N, WORK, N, B,$ LDB, WORK( NWORK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFTOL = RCOND*ABS( D( IDAMAX( N, D, 1 ) ) )DO 40 I = 1, NIF( D( I ).LE.TOL ) THENCALL DLASET( 'A', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )ELSECALL DLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),$ LDB, INFO )RANK = RANK + 1END IF40 CONTINUECALL DGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,$ WORK( NWORK ), N )CALL DLACPY( 'A', N, NRHS, WORK( NWORK ), N, B, LDB )** Unscale.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )CALL DLASRT( 'D', N, D, INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )*RETURNEND IF** Book-keeping and setting up some constants.*NLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1*SMLSZP = SMLSIZ + 1*U = 1VT = 1 + SMLSIZ*NDIFL = VT + SMLSZP*NDIFR = DIFL + NLVL*NZ = DIFR + NLVL*N*2C = Z + NLVL*NS = C + NPOLES = S + NGIVNUM = POLES + 2*NLVL*NBX = GIVNUM + 2*NLVL*NNWORK = BX + N*NRHS*SIZEI = 1 + NK = SIZEI + NGIVPTR = K + NPERM = GIVPTR + NGIVCOL = PERM + NLVL*NIWK = GIVCOL + NLVL*N*2*ST = 1SQRE = 0ICMPQ1 = 1ICMPQ2 = 0NSUB = 0*DO 50 I = 1, NIF( ABS( D( I ) ).LT.EPS ) THEND( I ) = SIGN( EPS, D( I ) )END IF50 CONTINUE*DO 60 I = 1, NM1IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THENNSUB = NSUB + 1IWORK( NSUB ) = ST** Subproblem found. First determine its size and then* apply divide and conquer on it.*IF( I.LT.NM1 ) THEN** A subproblem with E(I) small for I < NM1.*NSIZE = I - ST + 1IWORK( SIZEI+NSUB-1 ) = NSIZEELSE IF( ABS( E( I ) ).GE.EPS ) THEN** A subproblem with E(NM1) not too small but I = NM1.*NSIZE = N - ST + 1IWORK( SIZEI+NSUB-1 ) = NSIZEELSE** A subproblem with E(NM1) small. This implies an* 1-by-1 subproblem at D(N), which is not solved* explicitly.*NSIZE = I - ST + 1IWORK( SIZEI+NSUB-1 ) = NSIZENSUB = NSUB + 1IWORK( NSUB ) = NIWORK( SIZEI+NSUB-1 ) = 1CALL DCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )END IFST1 = ST - 1IF( NSIZE.EQ.1 ) THEN** This is a 1-by-1 subproblem and is not solved* explicitly.*CALL DCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )ELSE IF( NSIZE.LE.SMLSIZ ) THEN** This is a small subproblem and is solved by DLASDQ.*CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,$ WORK( VT+ST1 ), N )CALL DLASDQ( 'U', 0, NSIZE, NSIZE, 0, NRHS, D( ST ),$ E( ST ), WORK( VT+ST1 ), N, WORK( NWORK ),$ N, B( ST, 1 ), LDB, WORK( NWORK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFCALL DLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,$ WORK( BX+ST1 ), N )ELSE** A large problem. Solve it using divide and conquer.*CALL DLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),$ E( ST ), WORK( U+ST1 ), N, WORK( VT+ST1 ),$ IWORK( K+ST1 ), WORK( DIFL+ST1 ),$ WORK( DIFR+ST1 ), WORK( Z+ST1 ),$ WORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),$ IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),$ WORK( GIVNUM+ST1 ), WORK( C+ST1 ),$ WORK( S+ST1 ), WORK( NWORK ), IWORK( IWK ),$ INFO )IF( INFO.NE.0 ) THENRETURNEND IFBXST = BX + ST1CALL DLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),$ LDB, WORK( BXST ), N, WORK( U+ST1 ), N,$ WORK( VT+ST1 ), IWORK( K+ST1 ),$ WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),$ WORK( Z+ST1 ), WORK( POLES+ST1 ),$ IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,$ IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),$ WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),$ IWORK( IWK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFEND IFST = I + 1END IF60 CONTINUE** Apply the singular values and treat the tiny ones as zero.*TOL = RCOND*ABS( D( IDAMAX( N, D, 1 ) ) )*DO 70 I = 1, N** Some of the elements in D can be negative because 1-by-1* subproblems were not solved explicitly.*IF( ABS( D( I ) ).LE.TOL ) THENCALL DLASET( 'A', 1, NRHS, ZERO, ZERO, WORK( BX+I-1 ), N )ELSERANK = RANK + 1CALL DLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,$ WORK( BX+I-1 ), N, INFO )END IFD( I ) = ABS( D( I ) )70 CONTINUE** Now apply back the right singular vectors.*ICMPQ2 = 1DO 80 I = 1, NSUBST = IWORK( I )ST1 = ST - 1NSIZE = IWORK( SIZEI+I-1 )BXST = BX + ST1IF( NSIZE.EQ.1 ) THENCALL DCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )ELSE IF( NSIZE.LE.SMLSIZ ) THENCALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,$ WORK( VT+ST1 ), N, WORK( BXST ), N, ZERO,$ B( ST, 1 ), LDB )ELSECALL DLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,$ B( ST, 1 ), LDB, WORK( U+ST1 ), N,$ WORK( VT+ST1 ), IWORK( K+ST1 ),$ WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),$ WORK( Z+ST1 ), WORK( POLES+ST1 ),$ IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,$ IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),$ WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),$ IWORK( IWK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFEND IF80 CONTINUE** Unscale and sort the singular values.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )CALL DLASRT( 'D', N, D, INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )*RETURN** End of DLALSD*ENDSUBROUTINE DLAMRG( N1, N2, A, DTRD1, DTRD2, INDEX )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..INTEGER DTRD1, DTRD2, N1, N2* ..* .. Array Arguments ..INTEGER INDEX( * )DOUBLE PRECISION A( * )* ..** Purpose* =======** DLAMRG will create a permutation list which will merge the elements* of A (which is composed of two independently sorted sets) into a* single set which is sorted in ascending order.** Arguments* =========** N1 (input) INTEGER* N2 (input) INTEGER* These arguements contain the respective lengths of the two* sorted lists to be merged.** A (input) DOUBLE PRECISION array, dimension (N1+N2)* The first N1 elements of A contain a list of numbers which* are sorted in either ascending or descending order. Likewise* for the final N2 elements.** DTRD1 (input) INTEGER* DTRD2 (input) INTEGER* These are the strides to be taken through the array A.* Allowable strides are 1 and -1. They indicate whether a* subset of A is sorted in ascending (DTRDx = 1) or descending* (DTRDx = -1) order.** INDEX (output) INTEGER array, dimension (N1+N2)* On exit this array will contain a permutation such that* if B( I ) = A( INDEX( I ) ) for I=1,N1+N2, then B will be* sorted in ascending order.** =====================================================================** .. Local Scalars ..INTEGER I, IND1, IND2, N1SV, N2SV* ..* .. Executable Statements ..*N1SV = N1N2SV = N2IF( DTRD1.GT.0 ) THENIND1 = 1ELSEIND1 = N1END IFIF( DTRD2.GT.0 ) THENIND2 = 1 + N1ELSEIND2 = N1 + N2END IFI = 1* while ( (N1SV > 0) & (N2SV > 0) )10 CONTINUEIF( N1SV.GT.0 .AND. N2SV.GT.0 ) THENIF( A( IND1 ).LE.A( IND2 ) ) THENINDEX( I ) = IND1I = I + 1IND1 = IND1 + DTRD1N1SV = N1SV - 1ELSEINDEX( I ) = IND2I = I + 1IND2 = IND2 + DTRD2N2SV = N2SV - 1END IFGO TO 10END IF* end whileIF( N1SV.EQ.0 ) THENDO 20 N1SV = 1, N2SVINDEX( I ) = IND2I = I + 1IND2 = IND2 + DTRD220 CONTINUEELSE* N2SV .EQ. 0DO 30 N2SV = 1, N1SVINDEX( I ) = IND1I = I + 1IND1 = IND1 + DTRD130 CONTINUEEND IF*RETURN** End of DLAMRG*ENDSUBROUTINE DLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER SIDEINTEGER INCV, L, LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..** Purpose* =======** DLARZ applies a real elementary reflector H to a real M-by-N* matrix C, from either the left or the right. H is represented in the* form** H = I - tau * v * v'** where tau is a real scalar and v is a real vector.** If tau = 0, then H is taken to be the unit matrix.*** H is a product of k elementary reflectors as returned by DTZRZF.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': form H * C* = 'R': form C * H** M (input) INTEGER* The number of rows of the matrix C.** N (input) INTEGER* The number of columns of the matrix C.** L (input) INTEGER* The number of entries of the vector V containing* the meaningful part of the Householder vectors.* If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.** V (input) DOUBLE PRECISION array, dimension (1+(L-1)*abs(INCV))* The vector v in the representation of H as returned by* DTZRZF. V is not used if TAU = 0.** INCV (input) INTEGER* The increment between elements of v. INCV <> 0.** TAU (input) DOUBLE PRECISION* The value tau in the representation of H.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the M-by-N matrix C.* On exit, C is overwritten by the matrix H * C if SIDE = 'L',* or C * H if SIDE = 'R'.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** WORK (workspace) DOUBLE PRECISION array, dimension* (N) if SIDE = 'L'* or (M) if SIDE = 'R'** Further Details* ===============** Based on contributions by* A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGER* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C*IF( TAU.NE.ZERO ) THEN** w( 1:n ) = C( 1, 1:n )*CALL DCOPY( N, C, LDC, WORK, 1 )** w( 1:n ) = w( 1:n ) + C( m-l+1:m, 1:n )' * v( 1:l )*CALL DGEMV( 'Transpose', L, N, ONE, C( M-L+1, 1 ), LDC, V,$ INCV, ONE, WORK, 1 )** C( 1, 1:n ) = C( 1, 1:n ) - tau * w( 1:n )*CALL DAXPY( N, -TAU, WORK, 1, C, LDC )** C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...* tau * v( 1:l ) * w( 1:n )'*CALL DGER( L, N, -TAU, V, INCV, WORK, 1, C( M-L+1, 1 ),$ LDC )END IF*ELSE** Form C * H*IF( TAU.NE.ZERO ) THEN** w( 1:m ) = C( 1:m, 1 )*CALL DCOPY( M, C, 1, WORK, 1 )** w( 1:m ) = w( 1:m ) + C( 1:m, n-l+1:n, 1:n ) * v( 1:l )*CALL DGEMV( 'No transpose', M, L, ONE, C( 1, N-L+1 ), LDC,$ V, INCV, ONE, WORK, 1 )** C( 1:m, 1 ) = C( 1:m, 1 ) - tau * w( 1:m )*CALL DAXPY( M, -TAU, WORK, 1, C, 1 )** C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...* tau * w( 1:m ) * v( 1:l )'*CALL DGER( M, L, -TAU, WORK, 1, V, INCV, C( 1, N-L+1 ),$ LDC )*END IF*END IF*RETURN** End of DLARZ*ENDSUBROUTINE DLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,$ LDV, T, LDT, C, LDC, WORK, LDWORK )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* December 1, 1999** .. Scalar Arguments ..CHARACTER DIRECT, SIDE, STOREV, TRANSINTEGER K, L, LDC, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),$ WORK( LDWORK, * )* ..** Purpose* =======** DLARZB applies a real block reflector H or its transpose H**T to* a real distributed M-by-N C from the left or the right.** Currently, only STOREV = 'R' and DIRECT = 'B' are supported.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': apply H or H' from the Left* = 'R': apply H or H' from the Right** TRANS (input) CHARACTER*1* = 'N': apply H (No transpose)* = 'C': apply H' (Transpose)** DIRECT (input) CHARACTER*1* Indicates how H is formed from a product of elementary* reflectors* = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)* = 'B': H = H(k) . . . H(2) H(1) (Backward)** STOREV (input) CHARACTER*1* Indicates how the vectors which define the elementary* reflectors are stored:* = 'C': Columnwise (not supported yet)* = 'R': Rowwise** M (input) INTEGER* The number of rows of the matrix C.** N (input) INTEGER* The number of columns of the matrix C.** K (input) INTEGER* The order of the matrix T (= the number of elementary* reflectors whose product defines the block reflector).** L (input) INTEGER* The number of columns of the matrix V containing the* meaningful part of the Householder reflectors.* If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.** V (input) DOUBLE PRECISION array, dimension (LDV,NV).* If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.** LDV (input) INTEGER* The leading dimension of the array V.* If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.** T (input) DOUBLE PRECISION array, dimension (LDT,K)* The triangular K-by-K matrix T in the representation of the* block reflector.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= K.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the M-by-N matrix C.* On exit, C is overwritten by H*C or H'*C or C*H or C*H'.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** WORK (workspace) DOUBLE PRECISION array, dimension (LDWORK,K)** LDWORK (input) INTEGER* The leading dimension of the array WORK.* If SIDE = 'L', LDWORK >= max(1,N);* if SIDE = 'R', LDWORK >= max(1,M).** Further Details* ===============** Based on contributions by* A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..CHARACTER TRANSTINTEGER I, INFO, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DTRMM, XERBLA* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 )$ RETURN** Check for currently supported options*INFO = 0IF( .NOT.LSAME( DIRECT, 'B' ) ) THENINFO = -3ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLARZB', -INFO )RETURNEND IF*IF( LSAME( TRANS, 'N' ) ) THENTRANST = 'T'ELSETRANST = 'N'END IF*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H' * C** W( 1:n, 1:k ) = C( 1:k, 1:n )'*DO 10 J = 1, KCALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )10 CONTINUE** W( 1:n, 1:k ) = W( 1:n, 1:k ) + ...* C( m-l+1:m, 1:n )' * V( 1:k, 1:l )'*IF( L.GT.0 )$ CALL DGEMM( 'Transpose', 'Transpose', N, K, L, ONE,$ C( M-L+1, 1 ), LDC, V, LDV, ONE, WORK, LDWORK )** W( 1:n, 1:k ) = W( 1:n, 1:k ) * T' or W( 1:m, 1:k ) * T*CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, ONE, T,$ LDT, WORK, LDWORK )** C( 1:k, 1:n ) = C( 1:k, 1:n ) - W( 1:n, 1:k )'*DO 30 J = 1, NDO 20 I = 1, KC( I, J ) = C( I, J ) - WORK( J, I )20 CONTINUE30 CONTINUE** C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...* V( 1:k, 1:l )' * W( 1:n, 1:k )'*IF( L.GT.0 )$ CALL DGEMM( 'Transpose', 'Transpose', L, N, K, -ONE, V, LDV,$ WORK, LDWORK, ONE, C( M-L+1, 1 ), LDC )*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H'** W( 1:m, 1:k ) = C( 1:m, 1:k )*DO 40 J = 1, KCALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )40 CONTINUE** W( 1:m, 1:k ) = W( 1:m, 1:k ) + ...* C( 1:m, n-l+1:n ) * V( 1:k, 1:l )'*IF( L.GT.0 )$ CALL DGEMM( 'No transpose', 'Transpose', M, K, L, ONE,$ C( 1, N-L+1 ), LDC, V, LDV, ONE, WORK, LDWORK )** W( 1:m, 1:k ) = W( 1:m, 1:k ) * T or W( 1:m, 1:k ) * T'*CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, ONE, T,$ LDT, WORK, LDWORK )** C( 1:m, 1:k ) = C( 1:m, 1:k ) - W( 1:m, 1:k )*DO 60 J = 1, KDO 50 I = 1, MC( I, J ) = C( I, J ) - WORK( I, J )50 CONTINUE60 CONTINUE** C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...* W( 1:m, 1:k ) * V( 1:k, 1:l )*IF( L.GT.0 )$ CALL DGEMM( 'No transpose', 'No transpose', M, L, K, -ONE,$ WORK, LDWORK, V, LDV, ONE, C( 1, N-L+1 ), LDC )*END IF*RETURN** End of DLARZB*ENDSUBROUTINE DLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..CHARACTER DIRECT, STOREVINTEGER K, LDT, LDV, N* ..* .. Array Arguments ..DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )* ..** Purpose* =======** DLARZT forms the triangular factor T of a real block reflector* H of order > n, which is defined as a product of k elementary* reflectors.** If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;** If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.** If STOREV = 'C', the vector which defines the elementary reflector* H(i) is stored in the i-th column of the array V, and** H = I - V * T * V'** If STOREV = 'R', the vector which defines the elementary reflector* H(i) is stored in the i-th row of the array V, and** H = I - V' * T * V** Currently, only STOREV = 'R' and DIRECT = 'B' are supported.** Arguments* =========** DIRECT (input) CHARACTER*1* Specifies the order in which the elementary reflectors are* multiplied to form the block reflector:* = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)* = 'B': H = H(k) . . . H(2) H(1) (Backward)** STOREV (input) CHARACTER*1* Specifies how the vectors which define the elementary* reflectors are stored (see also Further Details):* = 'C': columnwise (not supported yet)* = 'R': rowwise** N (input) INTEGER* The order of the block reflector H. N >= 0.** K (input) INTEGER* The order of the triangular factor T (= the number of* elementary reflectors). K >= 1.** V (input/output) DOUBLE PRECISION array, dimension* (LDV,K) if STOREV = 'C'* (LDV,N) if STOREV = 'R'* The matrix V. See further details.** LDV (input) INTEGER* The leading dimension of the array V.* If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i).** T (output) DOUBLE PRECISION array, dimension (LDT,K)* The k by k triangular factor T of the block reflector.* If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is* lower triangular. The rest of the array is not used.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= K.** Further Details* ===============** Based on contributions by* A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA** The shape of the matrix V and the storage of the vectors which define* the H(i) is best illustrated by the following example with n = 5 and* k = 3. The elements equal to 1 are not stored; the corresponding* array elements are modified but restored on exit. The rest of the* array is not used.** DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':** ______V_____* ( v1 v2 v3 ) / \* ( v1 v2 v3 ) ( v1 v1 v1 v1 v1 . . . . 1 )* V = ( v1 v2 v3 ) ( v2 v2 v2 v2 v2 . . . 1 )* ( v1 v2 v3 ) ( v3 v3 v3 v3 v3 . . 1 )* ( v1 v2 v3 )* . . .* . . .* 1 . .* 1 .* 1** DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':** ______V_____* 1 / \* . 1 ( 1 . . . . v1 v1 v1 v1 v1 )* . . 1 ( . 1 . . . v2 v2 v2 v2 v2 )* . . . ( . . 1 . . v3 v3 v3 v3 v3 )* . . .* ( v1 v2 v3 )* ( v1 v2 v3 )* V = ( v1 v2 v3 )* ( v1 v2 v3 )* ( v1 v2 v3 )** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, INFO, J* ..* .. External Subroutines ..EXTERNAL DGEMV, DTRMV, XERBLA* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Check for currently supported options*INFO = 0IF( .NOT.LSAME( DIRECT, 'B' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLARZT', -INFO )RETURNEND IF*DO 20 I = K, 1, -1IF( TAU( I ).EQ.ZERO ) THEN** H(i) = I*DO 10 J = I, KT( J, I ) = ZERO10 CONTINUEELSE** general case*IF( I.LT.K ) THEN** T(i+1:k,i) = - tau(i) * V(i+1:k,1:n) * V(i,1:n)'*CALL DGEMV( 'No transpose', K-I, N, -TAU( I ),$ V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,$ T( I+1, I ), 1 )** T(i+1:k,i) = T(i+1:k,i+1:k) * T(i+1:k,i)*CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,$ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )END IFT( I, I ) = TAU( I )END IF20 CONTINUERETURN** End of DLARZT*ENDSUBROUTINE DLASQ1( N, D, E, WORK, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * )* ..** Purpose* =======** DLASQ1 computes the singular values of a real N-by-N bidiagonal* matrix with diagonal D and off-diagonal E. The singular values* are computed to high relative accuracy, in the absence of* denormalization, underflow and overflow. The algorithm was first* presented in** "Accurate singular values and differential qd algorithms" by K. V.* Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230,* 1994,** and the present implementation is described in "An implementation of* the dqds Algorithm (Positive Case)", LAPACK Working Note.** Arguments* =========** N (input) INTEGER* The number of rows and columns in the matrix. N >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, D contains the diagonal elements of the* bidiagonal matrix whose SVD is desired. On normal exit,* D contains the singular values in decreasing order.** E (input/output) DOUBLE PRECISION array, dimension (N)* On entry, elements E(1:N-1) contain the off-diagonal elements* of the bidiagonal matrix whose SVD is desired.* On exit, E is overwritten.** WORK (workspace) DOUBLE PRECISION array, dimension (4*N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: the algorithm failed* = 1, a split was marked by a positive value in E* = 2, current block of Z not diagonalized after 30*N* iterations (in inner while loop)* = 3, termination criterion of outer while loop not met* (program created more than N unreduced blocks)** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER I, IINFODOUBLE PRECISION EPS, SCALE, SAFMIN, SIGMN, SIGMX* ..* .. External Subroutines ..EXTERNAL DLAS2, DLASQ2, DLASRT, XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -2CALL XERBLA( 'DLASQ1', -INFO )RETURNELSE IF( N.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THEND( 1 ) = ABS( D( 1 ) )RETURNELSE IF( N.EQ.2 ) THENCALL DLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX )D( 1 ) = SIGMXD( 2 ) = SIGMNRETURNEND IF** Estimate the largest singular value.*SIGMX = ZERODO 10 I = 1, N - 1D( I ) = ABS( D( I ) )SIGMX = MAX( SIGMX, ABS( E( I ) ) )10 CONTINUED( N ) = ABS( D( N ) )** Early return if SIGMX is zero (matrix is already diagonal).*IF( SIGMX.EQ.ZERO ) THENCALL DLASRT( 'D', N, D, IINFO )RETURNEND IF*DO 20 I = 1, NSIGMX = MAX( SIGMX, D( I ) )20 CONTINUE** Copy D and E into WORK (in the Z format) and scale (squaring the* input data makes scaling by a power of the radix pointless).*EPS = DLAMCH( 'Precision' )SAFMIN = DLAMCH( 'Safe minimum' )SCALE = SQRT( EPS / SAFMIN )CALL DCOPY( N, D, 1, WORK( 1 ), 2 )CALL DCOPY( N-1, E, 1, WORK( 2 ), 2 )CALL DLASCL( 'G', 0, 0, SIGMX, SCALE, 2*N-1, 1, WORK, 2*N-1,$ IINFO )** Compute the q's and e's.*DO 30 I = 1, 2*N - 1WORK( I ) = WORK( I )**230 CONTINUEWORK( 2*N ) = ZERO*CALL DLASQ2( N, WORK, INFO )*IF( INFO.EQ.0 ) THENDO 40 I = 1, ND( I ) = SQRT( WORK( I ) )40 CONTINUECALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO )END IF*RETURN** End of DLASQ1*ENDSUBROUTINE DLASQ2( N, Z, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** Purpose* =======** DLASQ2 computes all the eigenvalues of the symmetric positive* definite tridiagonal matrix associated with the qd array Z to high* relative accuracy are computed to high relative accuracy, in the* absence of denormalization, underflow and overflow.** To see the relation of Z to the tridiagonal matrix, let L be a* unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and* let U be an upper bidiagonal matrix with 1's above and diagonal* Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the* symmetric tridiagonal to which it is similar.** Note : DLASQ2 defines a logical variable, IEEE, which is true* on machines which follow ieee-754 floating-point standard in their* handling of infinities and NaNs, and false otherwise. This variable* is passed to DLASQ3.** Arguments* =========** N (input) INTEGER* The number of rows and columns in the matrix. N >= 0.** Z (workspace) DOUBLE PRECISION array, dimension ( 4*N )* On entry Z holds the qd array. On exit, entries 1 to N hold* the eigenvalues in decreasing order, Z( 2*N+1 ) holds the* trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If* N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 )* holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of* shifts that failed.** INFO (output) INTEGER* = 0: successful exit* < 0: if the i-th argument is a scalar and had an illegal* value, then INFO = -i, if the i-th argument is an* array and the j-entry had an illegal value, then* INFO = -(i*100+j)* > 0: the algorithm failed* = 1, a split was marked by a positive value in E* = 2, current block of Z not diagonalized after 30*N* iterations (in inner while loop)* = 3, termination criterion of outer while loop not met* (program created more than N unreduced blocks)** Further Details* ===============* Local Variables: I0:N0 defines a current unreduced segment of Z.* The shifts are accumulated in SIGMA. Iteration count is in ITER.* Ping-pong is controlled by PP (alternates between 0 and 1).** =====================================================================** .. Parameters ..DOUBLE PRECISION CBIASPARAMETER ( CBIAS = 1.50D0 )DOUBLE PRECISION ZERO, HALF, ONE, TWO, FOUR, HUNDRDPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0,$ TWO = 2.0D0, FOUR = 4.0D0, HUNDRD = 100.0D0 )* ..* .. Local Scalars ..LOGICAL IEEEINTEGER I0, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, K,$ N0, NBIG, NDIV, NFAIL, PP, SPLTDOUBLE PRECISION D, DESIG, DMIN, E, EMAX, EMIN, EPS, OLDEMN,$ QMAX, QMIN, S, SAFMIN, SIGMA, T, TEMP, TOL,$ TOL2, TRACE, ZMAX* ..* .. External Subroutines ..EXTERNAL DLASQ3, DLASRT, XERBLA* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DLAMCHEXTERNAL DLAMCH, ILAENV* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments.* (in case DLASQ2 is not called by DLASQ1)*INFO = 0EPS = DLAMCH( 'Precision' )SAFMIN = DLAMCH( 'Safe minimum' )TOL = EPS*HUNDRDTOL2 = TOL**2*IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DLASQ2', 1 )RETURNELSE IF( N.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THEN** 1-by-1 case.*IF( Z( 1 ).LT.ZERO ) THENINFO = -201CALL XERBLA( 'DLASQ2', 2 )END IFRETURNELSE IF( N.EQ.2 ) THEN** 2-by-2 case.*IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THENINFO = -2CALL XERBLA( 'DLASQ2', 2 )RETURNELSE IF( Z( 3 ).GT.Z( 1 ) ) THEND = Z( 3 )Z( 3 ) = Z( 1 )Z( 1 ) = DEND IFZ( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 )IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THENT = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) )S = Z( 3 )*( Z( 2 ) / T )IF( S.LE.T ) THENS = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) )ELSES = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) )END IFT = Z( 1 ) + ( S+Z( 2 ) )Z( 3 ) = Z( 3 )*( Z( 1 ) / T )Z( 1 ) = TEND IFZ( 2 ) = Z( 3 )Z( 6 ) = Z( 2 ) + Z( 1 )RETURNEND IF** Check for negative data and compute sums of q's and e's.*Z( 2*N ) = ZEROEMIN = Z( 2 )QMAX = ZEROZMAX = ZEROD = ZEROE = ZERO*DO 10 K = 1, 2*( N-1 ), 2IF( Z( K ).LT.ZERO ) THENINFO = -( 200+K )CALL XERBLA( 'DLASQ2', 2 )RETURNELSE IF( Z( K+1 ).LT.ZERO ) THENINFO = -( 200+K+1 )CALL XERBLA( 'DLASQ2', 2 )RETURNEND IFD = D + Z( K )E = E + Z( K+1 )QMAX = MAX( QMAX, Z( K ) )EMIN = MIN( EMIN, Z( K+1 ) )ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) )10 CONTINUEIF( Z( 2*N-1 ).LT.ZERO ) THENINFO = -( 200+2*N-1 )CALL XERBLA( 'DLASQ2', 2 )RETURNEND IFD = D + Z( 2*N-1 )QMAX = MAX( QMAX, Z( 2*N-1 ) )ZMAX = MAX( QMAX, ZMAX )** Check for diagonality.*IF( E.EQ.ZERO ) THENDO 20 K = 2, NZ( K ) = Z( 2*K-1 )20 CONTINUECALL DLASRT( 'D', N, Z, IINFO )Z( 2*N-1 ) = DRETURNEND IF*TRACE = D + E** Check for zero data.*IF( TRACE.EQ.ZERO ) THENZ( 2*N-1 ) = ZERORETURNEND IF** Check whether the machine is IEEE conformable.*IEEE = ILAENV( 10, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND.$ ILAENV( 11, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1** Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...).*DO 30 K = 2*N, 2, -2Z( 2*K ) = ZEROZ( 2*K-1 ) = Z( K )Z( 2*K-2 ) = ZEROZ( 2*K-3 ) = Z( K-1 )30 CONTINUE*I0 = 1N0 = N** Reverse the qd-array, if warranted.*IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THENIPN4 = 4*( I0+N0 )DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4TEMP = Z( I4-3 )Z( I4-3 ) = Z( IPN4-I4-3 )Z( IPN4-I4-3 ) = TEMPTEMP = Z( I4-1 )Z( I4-1 ) = Z( IPN4-I4-5 )Z( IPN4-I4-5 ) = TEMP40 CONTINUEEND IF** Initial split checking via dqd and Li's test.*PP = 0*DO 80 K = 1, 2*D = Z( 4*N0+PP-3 )DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4IF( Z( I4-1 ).LE.TOL2*D ) THENZ( I4-1 ) = -ZEROD = Z( I4-3 )ELSED = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) )END IF50 CONTINUE** dqd maps Z to ZZ plus Li's test.*EMIN = Z( 4*I0+PP+1 )D = Z( 4*I0+PP-3 )DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4Z( I4-2*PP-2 ) = D + Z( I4-1 )IF( Z( I4-1 ).LE.TOL2*D ) THENZ( I4-1 ) = -ZEROZ( I4-2*PP-2 ) = DZ( I4-2*PP ) = ZEROD = Z( I4+1 )ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND.$ SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THENTEMP = Z( I4+1 ) / Z( I4-2*PP-2 )Z( I4-2*PP ) = Z( I4-1 )*TEMPD = D*TEMPELSEZ( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) )D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) )END IFEMIN = MIN( EMIN, Z( I4-2*PP ) )60 CONTINUEZ( 4*N0-PP-2 ) = D** Now find qmax.*QMAX = Z( 4*I0-PP-2 )DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4QMAX = MAX( QMAX, Z( I4 ) )70 CONTINUE** Prepare for the next iteration on K.*PP = 1 - PP80 CONTINUE*ITER = 2NFAIL = 0NDIV = 2*( N0-I0 )*DO 140 IWHILA = 1, N + 1IF( N0.LT.1 )$ GO TO 150** While array unfinished do** E(N0) holds the value of SIGMA when submatrix in I0:N0* splits from the rest of the array, but is negated.*DESIG = ZEROIF( N0.EQ.N ) THENSIGMA = ZEROELSESIGMA = -Z( 4*N0-1 )END IFIF( SIGMA.LT.ZERO ) THENINFO = 1RETURNEND IF** Find last unreduced submatrix's top index I0, find QMAX and* EMIN. Find Gershgorin-type bound if Q's much greater than E's.*EMAX = ZEROIF( N0.GT.I0 ) THENEMIN = ABS( Z( 4*N0-5 ) )ELSEEMIN = ZEROEND IFQMIN = Z( 4*N0-3 )QMAX = QMINDO 90 I4 = 4*N0, 8, -4IF( Z( I4-5 ).LE.ZERO )$ GO TO 100IF( QMIN.GE.FOUR*EMAX ) THENQMIN = MIN( QMIN, Z( I4-3 ) )EMAX = MAX( EMAX, Z( I4-5 ) )END IFQMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) )EMIN = MIN( EMIN, Z( I4-5 ) )90 CONTINUEI4 = 4*100 CONTINUEI0 = I4 / 4** Store EMIN for passing to DLASQ3.*Z( 4*N0-1 ) = EMIN** Put -(initial shift) into DMIN.*DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) )** Now I0:N0 is unreduced. PP = 0 for ping, PP = 1 for pong.*PP = 0*NBIG = 30*( N0-I0+1 )DO 120 IWHILB = 1, NBIGIF( I0.GT.N0 )$ GO TO 130** While submatrix unfinished take a good dqds step.*CALL DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,$ ITER, NDIV, IEEE )*PP = 1 - PP** When EMIN is very small check for splits.*IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THENIF( Z( 4*N0 ).LE.TOL2*QMAX .OR.$ Z( 4*N0-1 ).LE.TOL2*SIGMA ) THENSPLT = I0 - 1QMAX = Z( 4*I0-3 )EMIN = Z( 4*I0-1 )OLDEMN = Z( 4*I0 )DO 110 I4 = 4*I0, 4*( N0-3 ), 4IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR.$ Z( I4-1 ).LE.TOL2*SIGMA ) THENZ( I4-1 ) = -SIGMASPLT = I4 / 4QMAX = ZEROEMIN = Z( I4+3 )OLDEMN = Z( I4+4 )ELSEQMAX = MAX( QMAX, Z( I4+1 ) )EMIN = MIN( EMIN, Z( I4-1 ) )OLDEMN = MIN( OLDEMN, Z( I4 ) )END IF110 CONTINUEZ( 4*N0-1 ) = EMINZ( 4*N0 ) = OLDEMNI0 = SPLT + 1END IFEND IF*120 CONTINUE*INFO = 2RETURN** end IWHILB*130 CONTINUE*140 CONTINUE*INFO = 3RETURN** end IWHILA*150 CONTINUE** Move q's to the front.*DO 160 K = 2, NZ( K ) = Z( 4*K-3 )160 CONTINUE** Sort and compute sum of eigenvalues.*CALL DLASRT( 'D', N, Z, IINFO )*E = ZERODO 170 K = N, 1, -1E = E + Z( K )170 CONTINUE** Store trace, sum(eigenvalues) and information on performance.*Z( 2*N+1 ) = TRACEZ( 2*N+2 ) = EZ( 2*N+3 ) = DBLE( ITER )Z( 2*N+4 ) = DBLE( NDIV ) / DBLE( N**2 )Z( 2*N+5 ) = HUNDRD*NFAIL / DBLE( ITER )RETURN** End of DLASQ2*ENDSUBROUTINE DLASRT( ID, N, D, INFO )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments ..CHARACTER IDINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * )* ..** Purpose* =======** Sort the numbers in D in increasing order (if ID = 'I') or* in decreasing order (if ID = 'D' ).** Use Quick Sort, reverting to Insertion sort on arrays of* size <= 20. Dimension of STACK limits N to about 2**32.** Arguments* =========** ID (input) CHARACTER*1* = 'I': sort D in increasing order;* = 'D': sort D in decreasing order.** N (input) INTEGER* The length of the array D.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the array to be sorted.* On exit, D has been sorted into increasing order* (D(1) <= ... <= D(N) ) or into decreasing order* (D(1) >= ... >= D(N) ), depending on ID.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** =====================================================================** .. Parameters ..INTEGER SELECTPARAMETER ( SELECT = 20 )* ..* .. Local Scalars ..INTEGER DIR, ENDD, I, J, START, STKPNTDOUBLE PRECISION D1, D2, D3, DMNMX, TMP* ..* .. Local Arrays ..INTEGER STACK( 2, 32 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input paramters.*INFO = 0DIR = -1IF( LSAME( ID, 'D' ) ) THENDIR = 0ELSE IF( LSAME( ID, 'I' ) ) THENDIR = 1END IFIF( DIR.EQ.-1 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASRT', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.1 )$ RETURN*STKPNT = 1STACK( 1, 1 ) = 1STACK( 2, 1 ) = N10 CONTINUESTART = STACK( 1, STKPNT )ENDD = STACK( 2, STKPNT )STKPNT = STKPNT - 1IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN** Do Insertion sort on D( START:ENDD )*IF( DIR.EQ.0 ) THEN** Sort into decreasing order*DO 30 I = START + 1, ENDDDO 20 J = I, START + 1, -1IF( D( J ).GT.D( J-1 ) ) THENDMNMX = D( J )D( J ) = D( J-1 )D( J-1 ) = DMNMXELSEGO TO 30END IF20 CONTINUE30 CONTINUE*ELSE** Sort into increasing order*DO 50 I = START + 1, ENDDDO 40 J = I, START + 1, -1IF( D( J ).LT.D( J-1 ) ) THENDMNMX = D( J )D( J ) = D( J-1 )D( J-1 ) = DMNMXELSEGO TO 50END IF40 CONTINUE50 CONTINUE*END IF*ELSE IF( ENDD-START.GT.SELECT ) THEN** Partition D( START:ENDD ) and stack parts, largest one first** Choose partition entry as median of 3*D1 = D( START )D2 = D( ENDD )I = ( START+ENDD ) / 2D3 = D( I )IF( D1.LT.D2 ) THENIF( D3.LT.D1 ) THENDMNMX = D1ELSE IF( D3.LT.D2 ) THENDMNMX = D3ELSEDMNMX = D2END IFELSEIF( D3.LT.D2 ) THENDMNMX = D2ELSE IF( D3.LT.D1 ) THENDMNMX = D3ELSEDMNMX = D1END IFEND IF*IF( DIR.EQ.0 ) THEN** Sort into decreasing order*I = START - 1J = ENDD + 160 CONTINUE70 CONTINUEJ = J - 1IF( D( J ).LT.DMNMX )$ GO TO 7080 CONTINUEI = I + 1IF( D( I ).GT.DMNMX )$ GO TO 80IF( I.LT.J ) THENTMP = D( I )D( I ) = D( J )D( J ) = TMPGO TO 60END IFIF( J-START.GT.ENDD-J-1 ) THENSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDELSESTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JEND IFELSE** Sort into increasing order*I = START - 1J = ENDD + 190 CONTINUE100 CONTINUEJ = J - 1IF( D( J ).GT.DMNMX )$ GO TO 100110 CONTINUEI = I + 1IF( D( I ).LT.DMNMX )$ GO TO 110IF( I.LT.J ) THENTMP = D( I )D( I ) = D( J )D( J ) = TMPGO TO 90END IFIF( J-START.GT.ENDD-J-1 ) THENSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDELSESTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JEND IFEND IFEND IFIF( STKPNT.GT.0 )$ GO TO 10RETURN** End of DLASRT*ENDSUBROUTINE DLATRZ( M, N, L, A, LDA, TAU, WORK )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments ..INTEGER L, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DLATRZ factors the M-by-(M+L) real upper trapezoidal matrix* [ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R 0 ) * Z, by means* of orthogonal transformations. Z is an (M+L)-by-(M+L) orthogonal* matrix and, R and A1 are M-by-M upper triangular matrices.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix A. M >= 0.** N (input) INTEGER* The number of columns of the matrix A. N >= 0.** L (input) INTEGER* The number of columns of the matrix A containing the* meaningful part of the Householder vectors. N-M >= L >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the leading M-by-N upper trapezoidal part of the* array A must contain the matrix to be factorized.* On exit, the leading M-by-M upper triangular part of A* contains the upper triangular matrix R, and elements N-L+1 to* N of the first M rows of A, with the array TAU, represent the* orthogonal matrix Z as a product of M elementary reflectors.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (output) DOUBLE PRECISION array, dimension (M)* The scalar factors of the elementary reflectors.** WORK (workspace) DOUBLE PRECISION array, dimension (M)** Further Details* ===============** Based on contributions by* A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA** The factorization is obtained by Householder's method. The kth* transformation matrix, Z( k ), which is used to introduce zeros into* the ( m - k + 1 )th row of A, is given in the form** Z( k ) = ( I 0 ),* ( 0 T( k ) )** where** T( k ) = I - tau*u( k )*u( k )', u( k ) = ( 1 ),* ( 0 )* ( z( k ) )** tau is a scalar and z( k ) is an l element vector. tau and z( k )* are chosen to annihilate the elements of the kth row of A2.** The scalar tau is returned in the kth element of TAU and the vector* u( k ) in the kth row of A2, such that the elements of z( k ) are* in a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in* the upper triangular part of A1.** Z is given by** Z = Z( 1 ) * Z( 2 ) * ... * Z( m ).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I* ..* .. External Subroutines ..EXTERNAL DLARFG, DLARZ* ..* .. Executable Statements ..** Test the input arguments** Quick return if possible*IF( M.EQ.0 ) THENRETURNELSE IF( M.EQ.N ) THENDO 10 I = 1, NTAU( I ) = ZERO10 CONTINUERETURNEND IF*DO 20 I = M, 1, -1** Generate elementary reflector H(i) to annihilate* [ A(i,i) A(i,n-l+1:n) ]*CALL DLARFG( L+1, A( I, I ), A( I, N-L+1 ), LDA, TAU( I ) )** Apply H(i) to A(1:i-1,i:n) from the right*CALL DLARZ( 'Right', I-1, N-I+1, L, A( I, N-L+1 ), LDA,$ TAU( I ), A( 1, I ), LDA, WORK )*20 CONTINUE*RETURN** End of DLATRZ*ENDSUBROUTINE DLATZM( SIDE, M, N, V, INCV, TAU, C1, C2, LDC, WORK )** -- LAPACK routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* February 29, 1992** .. Scalar Arguments ..CHARACTER SIDEINTEGER INCV, LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C1( LDC, * ), C2( LDC, * ), V( * ), WORK( * )* ..** Purpose* =======** This routine is deprecated and has been replaced by routine DORMRZ.** DLATZM applies a Householder matrix generated by DTZRQF to a matrix.** Let P = I - tau*u*u', u = ( 1 ),* ( v )* where v is an (m-1) vector if SIDE = 'L', or a (n-1) vector if* SIDE = 'R'.** If SIDE equals 'L', let* C = [ C1 ] 1* [ C2 ] m-1* n* Then C is overwritten by P*C.** If SIDE equals 'R', let* C = [ C1, C2 ] m* 1 n-1* Then C is overwritten by C*P.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': form P * C* = 'R': form C * P** M (input) INTEGER* The number of rows of the matrix C.** N (input) INTEGER* The number of columns of the matrix C.** V (input) DOUBLE PRECISION array, dimension* (1 + (M-1)*abs(INCV)) if SIDE = 'L'* (1 + (N-1)*abs(INCV)) if SIDE = 'R'* The vector v in the representation of P. V is not used* if TAU = 0.** INCV (input) INTEGER* The increment between elements of v. INCV <> 0** TAU (input) DOUBLE PRECISION* The value tau in the representation of P.** C1 (input/output) DOUBLE PRECISION array, dimension* (LDC,N) if SIDE = 'L'* (M,1) if SIDE = 'R'* On entry, the n-vector C1 if SIDE = 'L', or the m-vector C1* if SIDE = 'R'.** On exit, the first row of P*C if SIDE = 'L', or the first* column of C*P if SIDE = 'R'.** C2 (input/output) DOUBLE PRECISION array, dimension* (LDC, N) if SIDE = 'L'* (LDC, N-1) if SIDE = 'R'* On entry, the (m - 1) x n matrix C2 if SIDE = 'L', or the* m x (n - 1) matrix C2 if SIDE = 'R'.** On exit, rows 2:m of P*C if SIDE = 'L', or columns 2:m of C*P* if SIDE = 'R'.** LDC (input) INTEGER* The leading dimension of the arrays C1 and C2. LDC >= (1,M).** WORK (workspace) DOUBLE PRECISION array, dimension* (N) if SIDE = 'L'* (M) if SIDE = 'R'** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGER* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( ( MIN( M, N ).EQ.0 ) .OR. ( TAU.EQ.ZERO ) )$ RETURN*IF( LSAME( SIDE, 'L' ) ) THEN** w := C1 + v' * C2*CALL DCOPY( N, C1, LDC, WORK, 1 )CALL DGEMV( 'Transpose', M-1, N, ONE, C2, LDC, V, INCV, ONE,$ WORK, 1 )** [ C1 ] := [ C1 ] - tau* [ 1 ] * w'* [ C2 ] [ C2 ] [ v ]*CALL DAXPY( N, -TAU, WORK, 1, C1, LDC )CALL DGER( M-1, N, -TAU, V, INCV, WORK, 1, C2, LDC )*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** w := C1 + C2 * v*CALL DCOPY( M, C1, 1, WORK, 1 )CALL DGEMV( 'No transpose', M, N-1, ONE, C2, LDC, V, INCV, ONE,$ WORK, 1 )** [ C1, C2 ] := [ C1, C2 ] - tau* w * [ 1 , v']*CALL DAXPY( M, -TAU, WORK, 1, C1, 1 )CALL DGER( M, N-1, -TAU, WORK, 1, V, INCV, C2, LDC )END IF*RETURN** End of DLATZM*END