Rev 14286 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
SUBROUTINE 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* June 30, 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 if only singular values wanted (NCVT = NRU = NCC = 0)* max( 1, 4*N-4 ) otherwise** 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 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 DGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,$ VS, LDVS, WORK, LWORK, BWORK, INFO )** -- LAPACK driver 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 JOBVS, SORTINTEGER INFO, LDA, LDVS, LWORK, N, SDIM* ..* .. Array Arguments ..LOGICAL BWORK( * )DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),$ WR( * )* ..* .. Function Arguments ..LOGICAL SELECTEXTERNAL SELECT* ..** Purpose* =======** DGEES computes for an N-by-N real nonsymmetric matrix A, the* eigenvalues, the real Schur form T, and, optionally, the matrix of* Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).** Optionally, it also orders the eigenvalues on the diagonal of the* real Schur form so that selected eigenvalues are at the top left.* The leading columns of Z then form an orthonormal basis for the* invariant subspace corresponding to the selected eigenvalues.** A matrix is in real Schur form if it is upper quasi-triangular with* 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the* form* [ a b ]* [ c a ]** where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).** Arguments* =========** JOBVS (input) CHARACTER*1* = 'N': Schur vectors are not computed;* = 'V': Schur vectors are computed.** SORT (input) CHARACTER*1* Specifies whether or not to order the eigenvalues on the* diagonal of the Schur form.* = 'N': Eigenvalues are not ordered;* = 'S': Eigenvalues are ordered (see SELECT).** SELECT (input) LOGICAL FUNCTION of two DOUBLE PRECISION arguments* SELECT must be declared EXTERNAL in the calling subroutine.* If SORT = 'S', SELECT is used to select eigenvalues to sort* to the top left of the Schur form.* If SORT = 'N', SELECT is not referenced.* An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if* SELECT(WR(j),WI(j)) is true; i.e., if either one of a complex* conjugate pair of eigenvalues is selected, then both complex* eigenvalues are selected.* Note that a selected complex eigenvalue may no longer* satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since* ordering may change the value of complex eigenvalues* (especially if the eigenvalue is ill-conditioned); in this* case INFO is set to N+2 (see INFO below).** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the N-by-N matrix A.* On exit, A has been overwritten by its real Schur form T.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** SDIM (output) INTEGER* If SORT = 'N', SDIM = 0.* If SORT = 'S', SDIM = number of eigenvalues (after sorting)* for which SELECT is true. (Complex conjugate* pairs for which SELECT is true for either* eigenvalue count as 2.)** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* WR and WI contain the real and imaginary parts,* respectively, of the computed eigenvalues in the same order* that they appear on the diagonal of the output Schur form T.* Complex conjugate pairs of eigenvalues will appear* consecutively with the eigenvalue having the positive* imaginary part first.** VS (output) DOUBLE PRECISION array, dimension (LDVS,N)* If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur* vectors.* If JOBVS = 'N', VS is not referenced.** LDVS (input) INTEGER* The leading dimension of the array VS. LDVS >= 1; if* JOBVS = 'V', LDVS >= N.** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) contains the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,3*N).* For good performance, LWORK must generally be larger.** 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.** BWORK (workspace) LOGICAL array, dimension (N)* Not referenced if SORT = '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: the QR algorithm failed to compute all the* eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI* contain those eigenvalues which have converged; if* JOBVS = 'V', VS contains the matrix which reduces A* to its partially converged Schur form.* = N+1: the eigenvalues could not be reordered because some* eigenvalues were too close to separate (the problem* is very ill-conditioned);* = N+2: after reordering, roundoff changed values of some* complex eigenvalues so that leading eigenvalues in* the Schur form no longer satisfy SELECT=.TRUE. This* could also be caused by underflow due to scaling.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTST,$ WANTVSINTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,$ IHI, ILO, INXT, IP, ITAU, IWRK, K, MAXB,$ MAXWRK, MINWRKDOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM* ..* .. Local Arrays ..INTEGER IDUM( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,$ DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )WANTVS = LSAME( JOBVS, 'V' )WANTST = LSAME( SORT, 'S' )IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THENINFO = -1ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THENINFO = -11END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.)*MINWRK = 1IF( INFO.EQ.0 .AND. ( LWORK.GE.1 .OR. LQUERY ) ) THENMAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )MINWRK = MAX( 1, 3*N )IF( .NOT.WANTVS ) THENMAXB = MAX( ILAENV( 8, 'DHSEQR', 'SN', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'SN', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, N+HSWORK, 1 )ELSEMAXWRK = MAX( MAXWRK, 2*N+( N-1 )*$ ILAENV( 1, 'DORGHR', ' ', N, 1, N, -1 ) )MAXB = MAX( ILAENV( 8, 'DHSEQR', 'EN', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'EN', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, N+HSWORK, 1 )END IFWORK( 1 ) = MAXWRKEND IFIF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEES ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSDIM = 0RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Permute the matrix to make it more nearly triangular* (Workspace: need N)*IBAL = 1CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )** Reduce to upper Hessenberg form* (Workspace: need 3*N, prefer 2*N+N*NB)*ITAU = N + IBALIWRK = N + ITAUCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVS ) THEN** Copy Householder vectors to VS*CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )** Generate orthogonal matrix in VS* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )END IF*SDIM = 0** Perform QR iteration, accumulating Schur vectors in VS if desired* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,$ WORK( IWRK ), LWORK-IWRK+1, IEVAL )IF( IEVAL.GT.0 )$ INFO = IEVAL** Sort eigenvalues if desired*IF( WANTST .AND. INFO.EQ.0 ) THENIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )END IFDO 10 I = 1, NBWORK( I ) = SELECT( WR( I ), WI( I ) )10 CONTINUE** Reorder eigenvalues and transform Schur vectors* (Workspace: none needed)*CALL DTRSEN( 'N', JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,$ SDIM, S, SEP, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,$ ICOND )IF( ICOND.GT.0 )$ INFO = N + ICONDEND IF*IF( WANTVS ) THEN** Undo balancing* (Workspace: need N)*CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,$ IERR )END IF*IF( SCALEA ) THEN** Undo scaling for the Schur form of A*CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )CALL DCOPY( N, A, LDA+1, WR, 1 )IF( CSCALE.EQ.SMLNUM ) THEN** If scaling back towards underflow, adjust WI if an* offdiagonal element of a 2-by-2 block in the Schur form* underflows.*IF( IEVAL.GT.0 ) THENI1 = IEVAL + 1I2 = IHI - 1CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI,$ MAX( ILO-1, 1 ), IERR )ELSE IF( WANTST ) THENI1 = 1I2 = N - 1ELSEI1 = ILOI2 = IHI - 1END IFINXT = I1 - 1DO 20 I = I1, I2IF( I.LT.INXT )$ GO TO 20IF( WI( I ).EQ.ZERO ) THENINXT = I + 1ELSEIF( A( I+1, I ).EQ.ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.$ ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROIF( I.GT.1 )$ CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )IF( N.GT.I+1 )$ CALL DSWAP( N-I-1, A( I, I+2 ), LDA,$ A( I+1, I+2 ), LDA )CALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )A( I, I+1 ) = A( I+1, I )A( I+1, I ) = ZEROEND IFINXT = I + 2END IF20 CONTINUEEND IF** Undo scaling for the imaginary part of the eigenvalues*CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,$ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )END IF*IF( WANTST .AND. INFO.EQ.0 ) THEN** Check if reordering successful*LASTSL = .TRUE.LST2SL = .TRUE.SDIM = 0IP = 0DO 30 I = 1, NCURSL = SELECT( WR( I ), WI( I ) )IF( WI( I ).EQ.ZERO ) THENIF( CURSL )$ SDIM = SDIM + 1IP = 0IF( CURSL .AND. .NOT.LASTSL )$ INFO = N + 2ELSEIF( IP.EQ.1 ) THEN** Last eigenvalue of conjugate pair*CURSL = CURSL .OR. LASTSLLASTSL = CURSLIF( CURSL )$ SDIM = SDIM + 2IP = -1IF( CURSL .AND. .NOT.LST2SL )$ INFO = N + 2ELSE** First eigenvalue of conjugate pair*IP = 1END IFEND IFLST2SL = LASTSLLASTSL = CURSL30 CONTINUEEND IF*WORK( 1 ) = MAXWRKRETURN** End of DGEES*ENDSUBROUTINE DGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,$ WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,$ IWORK, LIWORK, BWORK, INFO )** -- LAPACK driver 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 JOBVS, SENSE, SORTINTEGER INFO, LDA, LDVS, LIWORK, LWORK, N, SDIMDOUBLE PRECISION RCONDE, RCONDV* ..* .. Array Arguments ..LOGICAL BWORK( * )INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),$ WR( * )* ..* .. Function Arguments ..LOGICAL SELECTEXTERNAL SELECT* ..** Purpose* =======** DGEESX computes for an N-by-N real nonsymmetric matrix A, the* eigenvalues, the real Schur form T, and, optionally, the matrix of* Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).** Optionally, it also orders the eigenvalues on the diagonal of the* real Schur form so that selected eigenvalues are at the top left;* computes a reciprocal condition number for the average of the* selected eigenvalues (RCONDE); and computes a reciprocal condition* number for the right invariant subspace corresponding to the* selected eigenvalues (RCONDV). The leading columns of Z form an* orthonormal basis for this invariant subspace.** For further explanation of the reciprocal condition numbers RCONDE* and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where* these quantities are called s and sep respectively).** A real matrix is in real Schur form if it is upper quasi-triangular* with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in* the form* [ a b ]* [ c a ]** where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).** Arguments* =========** JOBVS (input) CHARACTER*1* = 'N': Schur vectors are not computed;* = 'V': Schur vectors are computed.** SORT (input) CHARACTER*1* Specifies whether or not to order the eigenvalues on the* diagonal of the Schur form.* = 'N': Eigenvalues are not ordered;* = 'S': Eigenvalues are ordered (see SELECT).** SELECT (input) LOGICAL FUNCTION of two DOUBLE PRECISION arguments* SELECT must be declared EXTERNAL in the calling subroutine.* If SORT = 'S', SELECT is used to select eigenvalues to sort* to the top left of the Schur form.* If SORT = 'N', SELECT is not referenced.* An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if* SELECT(WR(j),WI(j)) is true; i.e., if either one of a* complex conjugate pair of eigenvalues is selected, then both* are. Note that a selected complex eigenvalue may no longer* satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since* ordering may change the value of complex eigenvalues* (especially if the eigenvalue is ill-conditioned); in this* case INFO may be set to N+3 (see INFO below).** SENSE (input) CHARACTER*1* Determines which reciprocal condition numbers are computed.* = 'N': None are computed;* = 'E': Computed for average of selected eigenvalues only;* = 'V': Computed for selected right invariant subspace only;* = 'B': Computed for both.* If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA, N)* On entry, the N-by-N matrix A.* On exit, A is overwritten by its real Schur form T.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** SDIM (output) INTEGER* If SORT = 'N', SDIM = 0.* If SORT = 'S', SDIM = number of eigenvalues (after sorting)* for which SELECT is true. (Complex conjugate* pairs for which SELECT is true for either* eigenvalue count as 2.)** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* WR and WI contain the real and imaginary parts, respectively,* of the computed eigenvalues, in the same order that they* appear on the diagonal of the output Schur form T. Complex* conjugate pairs of eigenvalues appear consecutively with the* eigenvalue having the positive imaginary part first.** VS (output) DOUBLE PRECISION array, dimension (LDVS,N)* If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur* vectors.* If JOBVS = 'N', VS is not referenced.** LDVS (input) INTEGER* The leading dimension of the array VS. LDVS >= 1, and if* JOBVS = 'V', LDVS >= N.** RCONDE (output) DOUBLE PRECISION* If SENSE = 'E' or 'B', RCONDE contains the reciprocal* condition number for the average of the selected eigenvalues.* Not referenced if SENSE = 'N' or 'V'.** RCONDV (output) DOUBLE PRECISION* If SENSE = 'V' or 'B', RCONDV contains the reciprocal* condition number for the selected right invariant subspace.* Not referenced if SENSE = 'N' or 'E'.** 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,3*N).* Also, if SENSE = 'E' or 'V' or 'B',* LWORK >= N+2*SDIM*(N-SDIM), where SDIM is the number of* selected eigenvalues computed by this routine. Note that* N+2*SDIM*(N-SDIM) <= N+N*N/2.* For good performance, LWORK must generally be larger.** IWORK (workspace/output) INTEGER array, dimension (LIWORK)* Not referenced if SENSE = 'N' or 'E'.* On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.** LIWORK (input) INTEGER* The dimension of the array IWORK.* LIWORK >= 1; if SENSE = 'V' or 'B', LIWORK >= SDIM*(N-SDIM).** BWORK (workspace) LOGICAL array, dimension (N)* Not referenced if SORT = '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: the QR algorithm failed to compute all the* eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI* contain those eigenvalues which have converged; if* JOBVS = 'V', VS contains the transformation which* reduces A to its partially converged Schur form.* = N+1: the eigenvalues could not be reordered because some* eigenvalues were too close to separate (the problem* is very ill-conditioned);* = N+2: after reordering, roundoff changed values of some* complex eigenvalues so that leading eigenvalues in* the Schur form no longer satisfy SELECT=.TRUE. This* could also be caused by underflow due to scaling.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL CURSL, LASTSL, LST2SL, SCALEA, WANTSB, WANTSE,$ WANTSN, WANTST, WANTSV, WANTVSINTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,$ IHI, ILO, INXT, IP, ITAU, IWRK, K, MAXB,$ MAXWRK, MINWRKDOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, SMLNUM* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,$ DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0WANTVS = LSAME( JOBVS, 'V' )WANTST = LSAME( SORT, 'S' )WANTSN = LSAME( SENSE, 'N' )WANTSE = LSAME( SENSE, 'E' )WANTSV = LSAME( SENSE, 'V' )WANTSB = LSAME( SENSE, 'B' )IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THENINFO = -1ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.$ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THENINFO = -12END IF** Compute workspace* (Note: Comments in the code beginning "RWorkspace:" describe the* minimal amount of real workspace needed at that point in the* code, as well as the preferred amount for good performance.* IWorkspace refers to integer workspace.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.* If SENSE = 'E', 'V' or 'B', then the amount of workspace needed* depends on SDIM, which is computed by the routine DTRSEN later* in the code.)*MINWRK = 1IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THENMAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )MINWRK = MAX( 1, 3*N )IF( .NOT.WANTVS ) THENMAXB = MAX( ILAENV( 8, 'DHSEQR', 'SN', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'SN', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, N+HSWORK, 1 )ELSEMAXWRK = MAX( MAXWRK, 2*N+( N-1 )*$ ILAENV( 1, 'DORGHR', ' ', N, 1, N, -1 ) )MAXB = MAX( ILAENV( 8, 'DHSEQR', 'SV', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'SV', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, N+HSWORK, 1 )END IFWORK( 1 ) = MAXWRKEND IFIF( LWORK.LT.MINWRK ) THENINFO = -16END IFIF( LIWORK.LT.1 ) THENINFO = -18END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEESX', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSDIM = 0RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Permute the matrix to make it more nearly triangular* (RWorkspace: need N)*IBAL = 1CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )** Reduce to upper Hessenberg form* (RWorkspace: need 3*N, prefer 2*N+N*NB)*ITAU = N + IBALIWRK = N + ITAUCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVS ) THEN** Copy Householder vectors to VS*CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )** Generate orthogonal matrix in VS* (RWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )END IF*SDIM = 0** Perform QR iteration, accumulating Schur vectors in VS if desired* (RWorkspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,$ WORK( IWRK ), LWORK-IWRK+1, IEVAL )IF( IEVAL.GT.0 )$ INFO = IEVAL** Sort eigenvalues if desired*IF( WANTST .AND. INFO.EQ.0 ) THENIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )END IFDO 10 I = 1, NBWORK( I ) = SELECT( WR( I ), WI( I ) )10 CONTINUE** Reorder eigenvalues, transform Schur vectors, and compute* reciprocal condition numbers* (RWorkspace: if SENSE is not 'N', need N+2*SDIM*(N-SDIM)* otherwise, need N )* (IWorkspace: if SENSE is 'V' or 'B', need SDIM*(N-SDIM)* otherwise, need 0 )*CALL DTRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,$ SDIM, RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,$ IWORK, LIWORK, ICOND )IF( .NOT.WANTSN )$ MAXWRK = MAX( MAXWRK, N+2*SDIM*( N-SDIM ) )IF( ICOND.EQ.-15 ) THEN** Not enough real workspace*INFO = -16ELSE IF( ICOND.EQ.-17 ) THEN** Not enough integer workspace*INFO = -18ELSE IF( ICOND.GT.0 ) THEN** DTRSEN failed to reorder or to restore standard Schur form*INFO = ICOND + NEND IFEND IF*IF( WANTVS ) THEN** Undo balancing* (RWorkspace: need N)*CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,$ IERR )END IF*IF( SCALEA ) THEN** Undo scaling for the Schur form of A*CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )CALL DCOPY( N, A, LDA+1, WR, 1 )IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THENDUM( 1 ) = RCONDVCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )RCONDV = DUM( 1 )END IFIF( CSCALE.EQ.SMLNUM ) THEN** If scaling back towards underflow, adjust WI if an* offdiagonal element of a 2-by-2 block in the Schur form* underflows.*IF( IEVAL.GT.0 ) THENI1 = IEVAL + 1I2 = IHI - 1CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,$ IERR )ELSE IF( WANTST ) THENI1 = 1I2 = N - 1ELSEI1 = ILOI2 = IHI - 1END IFINXT = I1 - 1DO 20 I = I1, I2IF( I.LT.INXT )$ GO TO 20IF( WI( I ).EQ.ZERO ) THENINXT = I + 1ELSEIF( A( I+1, I ).EQ.ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.$ ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROIF( I.GT.1 )$ CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )IF( N.GT.I+1 )$ CALL DSWAP( N-I-1, A( I, I+2 ), LDA,$ A( I+1, I+2 ), LDA )CALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )A( I, I+1 ) = A( I+1, I )A( I+1, I ) = ZEROEND IFINXT = I + 2END IF20 CONTINUEEND IFCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,$ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )END IF*IF( WANTST .AND. INFO.EQ.0 ) THEN** Check if reordering successful*LASTSL = .TRUE.LST2SL = .TRUE.SDIM = 0IP = 0DO 30 I = 1, NCURSL = SELECT( WR( I ), WI( I ) )IF( WI( I ).EQ.ZERO ) THENIF( CURSL )$ SDIM = SDIM + 1IP = 0IF( CURSL .AND. .NOT.LASTSL )$ INFO = N + 2ELSEIF( IP.EQ.1 ) THEN** Last eigenvalue of conjugate pair*CURSL = CURSL .OR. LASTSLLASTSL = CURSLIF( CURSL )$ SDIM = SDIM + 2IP = -1IF( CURSL .AND. .NOT.LST2SL )$ INFO = N + 2ELSE** First eigenvalue of conjugate pair*IP = 1END IFEND IFLST2SL = LASTSLLASTSL = CURSL30 CONTINUEEND IF*WORK( 1 ) = MAXWRKIF( WANTSV .OR. WANTSB ) THENIWORK( 1 ) = SDIM*( N-SDIM )ELSEIWORK( 1 ) = 1END IF*RETURN** End of DGEESX*ENDSUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,$ LDVR, WORK, LWORK, INFO )** -- LAPACK driver 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 JOBVL, JOBVRINTEGER INFO, LDA, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),$ WI( * ), WORK( * ), WR( * )* ..** Purpose* =======** DGEEV computes for an N-by-N real nonsymmetric matrix A, the* eigenvalues and, optionally, the left and/or right eigenvectors.** The right eigenvector v(j) of A satisfies* A * v(j) = lambda(j) * v(j)* where lambda(j) is its eigenvalue.* The left eigenvector u(j) of A satisfies* u(j)**H * A = lambda(j) * u(j)**H* where u(j)**H denotes the conjugate transpose of u(j).** The computed eigenvectors are normalized to have Euclidean norm* equal to 1 and largest component real.** Arguments* =========** JOBVL (input) CHARACTER*1* = 'N': left eigenvectors of A are not computed;* = 'V': left eigenvectors of A are computed.** JOBVR (input) CHARACTER*1* = 'N': right eigenvectors of A are not computed;* = 'V': right eigenvectors of A are computed.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the N-by-N matrix A.* On exit, A has been overwritten.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* WR and WI contain the real and imaginary parts,* respectively, of the computed eigenvalues. Complex* conjugate pairs of eigenvalues appear consecutively* with the eigenvalue having the positive imaginary part* first.** VL (output) DOUBLE PRECISION array, dimension (LDVL,N)* If JOBVL = 'V', the left eigenvectors u(j) are stored one* after another in the columns of VL, in the same order* as their eigenvalues.* If JOBVL = 'N', VL is not referenced.* If the j-th eigenvalue is real, then u(j) = VL(:,j),* the j-th column of VL.* If the j-th and (j+1)-st eigenvalues form a complex* conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and* u(j+1) = VL(:,j) - i*VL(:,j+1).** LDVL (input) INTEGER* The leading dimension of the array VL. LDVL >= 1; if* JOBVL = 'V', LDVL >= N.** VR (output) DOUBLE PRECISION array, dimension (LDVR,N)* If JOBVR = 'V', the right eigenvectors v(j) are stored one* after another in the columns of VR, in the same order* as their eigenvalues.* If JOBVR = 'N', VR is not referenced.* If the j-th eigenvalue is real, then v(j) = VR(:,j),* the j-th column of VR.* If the j-th and (j+1)-st eigenvalues form a complex* conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and* v(j+1) = VR(:,j) - i*VR(:,j+1).** LDVR (input) INTEGER* The leading dimension of the array VR. LDVR >= 1; if* JOBVR = 'V', LDVR >= 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,3*N), and* if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N. For good* performance, LWORK must generally be larger.** 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, the QR algorithm failed to compute all the* eigenvalues, and no eigenvectors have been computed;* elements i+1:N of WR and WI contain eigenvalues which* have converged.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, SCALEA, WANTVL, WANTVRCHARACTER SIDEINTEGER HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,$ MAXB, MAXWRK, MINWRK, NOUTDOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,$ SN* ..* .. Local Arrays ..LOGICAL SELECT( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY, DLARTG,$ DLASCL, DORGHR, DROT, DSCAL, DTREVC, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAX, ILAENVDOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,$ DNRM2* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )WANTVL = LSAME( JOBVL, 'V' )WANTVR = LSAME( JOBVR, 'V' )IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THENINFO = -1ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THENINFO = -9ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THENINFO = -11END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.)*MINWRK = 1IF( INFO.EQ.0 ) THENc IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THENMAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THENMINWRK = MAX( 1, 3*N )MAXB = MAX( ILAENV( 8, 'DHSEQR', 'EN', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'EN', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, N+1, N+HSWORK )ELSEMINWRK = MAX( 1, 4*N )MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*$ ILAENV( 1, 'DORGHR', ' ', N, 1, N, -1 ) )MAXB = MAX( ILAENV( 8, 'DHSEQR', 'SV', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'SV', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, N+1, N+HSWORK )MAXWRK = MAX( MAXWRK, 4*N )END IFWORK( 1 ) = MAXWRKEND IFIF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Balance the matrix* (Workspace: need N)*IBAL = 1CALL DGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )** Reduce to upper Hessenberg form* (Workspace: need 3*N, prefer 2*N+N*NB)*ITAU = IBAL + NIWRK = ITAU + NCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVL ) THEN** Want left eigenvectors* Copy Householder vectors to VL*SIDE = 'L'CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )** Generate orthogonal matrix in VL* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VL* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*IF( WANTVR ) THEN** Want left and right eigenvectors* Copy Schur vectors to VR*SIDE = 'B'CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )END IF*ELSE IF( WANTVR ) THEN** Want right eigenvectors* Copy Householder vectors to VR*SIDE = 'R'CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )** Generate orthogonal matrix in VR* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VR* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*ELSE** Compute eigenvalues only* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )END IF** If INFO > 0 from DHSEQR, then quit*IF( INFO.GT.0 )$ GO TO 50*IF( WANTVL .OR. WANTVR ) THEN** Compute left and/or right eigenvectors* (Workspace: need 4*N)*CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,$ N, NOUT, WORK( IWRK ), IERR )END IF*IF( WANTVL ) THEN** Undo balancing of left eigenvectors* (Workspace: need N)*CALL DGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,$ IERR )** Normalize left eigenvectors and make largest component real*DO 20 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),$ DNRM2( N, VL( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )DO 10 K = 1, NWORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**210 CONTINUEK = IDAMAX( N, WORK( IWRK ), 1 )CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )VL( K, I+1 ) = ZEROEND IF20 CONTINUEEND IF*IF( WANTVR ) THEN** Undo balancing of right eigenvectors* (Workspace: need N)*CALL DGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,$ IERR )** Normalize right eigenvectors and make largest component real*DO 40 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),$ DNRM2( N, VR( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )DO 30 K = 1, NWORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**230 CONTINUEK = IDAMAX( N, WORK( IWRK ), 1 )CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )VR( K, I+1 ) = ZEROEND IF40 CONTINUEEND IF** Undo scaling if necessary*50 CONTINUEIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )IF( INFO.GT.0 ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,$ IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,$ IERR )END IFEND IF*WORK( 1 ) = MAXWRKRETURN** End of DGEEV*ENDSUBROUTINE DGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,$ VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,$ RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )** -- LAPACK driver 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 BALANC, JOBVL, JOBVR, SENSEINTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, NDOUBLE PRECISION ABNRM* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), RCONDE( * ), RCONDV( * ),$ SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),$ WI( * ), WORK( * ), WR( * )* ..** Purpose* =======** DGEEVX computes for an N-by-N real nonsymmetric matrix A, the* eigenvalues and, optionally, the left and/or right eigenvectors.** Optionally also, it computes a balancing transformation to improve* the conditioning of the eigenvalues and eigenvectors (ILO, IHI,* SCALE, and ABNRM), reciprocal condition numbers for the eigenvalues* (RCONDE), and reciprocal condition numbers for the right* eigenvectors (RCONDV).** The right eigenvector v(j) of A satisfies* A * v(j) = lambda(j) * v(j)* where lambda(j) is its eigenvalue.* The left eigenvector u(j) of A satisfies* u(j)**H * A = lambda(j) * u(j)**H* where u(j)**H denotes the conjugate transpose of u(j).** The computed eigenvectors are normalized to have Euclidean norm* equal to 1 and largest component real.** Balancing a matrix means permuting the rows and columns to make it* more nearly upper triangular, and applying a diagonal similarity* transformation D * A * D**(-1), where D is a diagonal matrix, to* make its rows and columns closer in norm and the condition numbers* of its eigenvalues and eigenvectors smaller. The computed* reciprocal condition numbers correspond to the balanced matrix.* Permuting rows and columns will not change the condition numbers* (in exact arithmetic) but diagonal scaling will. For further* explanation of balancing, see section 4.10.2 of the LAPACK* Users' Guide.** Arguments* =========** BALANC (input) CHARACTER*1* Indicates how the input matrix should be diagonally scaled* and/or permuted to improve the conditioning of its* eigenvalues.* = 'N': Do not diagonally scale or permute;* = 'P': Perform permutations to make the matrix more nearly* upper triangular. Do not diagonally scale;* = 'S': Diagonally scale the matrix, i.e. replace A by* D*A*D**(-1), where D is a diagonal matrix chosen* to make the rows and columns of A more equal in* norm. Do not permute;* = 'B': Both diagonally scale and permute A.** Computed reciprocal condition numbers will be for the matrix* after balancing and/or permuting. Permuting does not change* condition numbers (in exact arithmetic), but balancing does.** JOBVL (input) CHARACTER*1* = 'N': left eigenvectors of A are not computed;* = 'V': left eigenvectors of A are computed.* If SENSE = 'E' or 'B', JOBVL must = 'V'.** JOBVR (input) CHARACTER*1* = 'N': right eigenvectors of A are not computed;* = 'V': right eigenvectors of A are computed.* If SENSE = 'E' or 'B', JOBVR must = 'V'.** SENSE (input) CHARACTER*1* Determines which reciprocal condition numbers are computed.* = 'N': None are computed;* = 'E': Computed for eigenvalues only;* = 'V': Computed for right eigenvectors only;* = 'B': Computed for eigenvalues and right eigenvectors.** If SENSE = 'E' or 'B', both left and right eigenvectors* must also be computed (JOBVL = 'V' and JOBVR = 'V').** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the N-by-N matrix A.* On exit, A has been overwritten. If JOBVL = 'V' or* JOBVR = 'V', A contains the real Schur form of the balanced* version of the input matrix A.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* WR and WI contain the real and imaginary parts,* respectively, of the computed eigenvalues. Complex* conjugate pairs of eigenvalues will appear consecutively* with the eigenvalue having the positive imaginary part* first.** VL (output) DOUBLE PRECISION array, dimension (LDVL,N)* If JOBVL = 'V', the left eigenvectors u(j) are stored one* after another in the columns of VL, in the same order* as their eigenvalues.* If JOBVL = 'N', VL is not referenced.* If the j-th eigenvalue is real, then u(j) = VL(:,j),* the j-th column of VL.* If the j-th and (j+1)-st eigenvalues form a complex* conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and* u(j+1) = VL(:,j) - i*VL(:,j+1).** LDVL (input) INTEGER* The leading dimension of the array VL. LDVL >= 1; if* JOBVL = 'V', LDVL >= N.** VR (output) DOUBLE PRECISION array, dimension (LDVR,N)* If JOBVR = 'V', the right eigenvectors v(j) are stored one* after another in the columns of VR, in the same order* as their eigenvalues.* If JOBVR = 'N', VR is not referenced.* If the j-th eigenvalue is real, then v(j) = VR(:,j),* the j-th column of VR.* If the j-th and (j+1)-st eigenvalues form a complex* conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and* v(j+1) = VR(:,j) - i*VR(:,j+1).** LDVR (input) INTEGER* The leading dimension of the array VR. LDVR >= 1, and if* JOBVR = 'V', LDVR >= N.** ILO,IHI (output) INTEGER* ILO and IHI are integer values determined when A was* balanced. The balanced A(i,j) = 0 if I > J and* J = 1,...,ILO-1 or I = IHI+1,...,N.** SCALE (output) DOUBLE PRECISION array, dimension (N)* Details of the permutations and scaling factors applied* when balancing 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.** ABNRM (output) DOUBLE PRECISION* The one-norm of the balanced matrix (the maximum* of the sum of absolute values of elements of any column).** RCONDE (output) DOUBLE PRECISION array, dimension (N)* RCONDE(j) is the reciprocal condition number of the j-th* eigenvalue.** RCONDV (output) DOUBLE PRECISION array, dimension (N)* RCONDV(j) is the reciprocal condition number of the j-th* right eigenvector.** 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. If SENSE = 'N' or 'E',* LWORK >= max(1,2*N), and if JOBVL = 'V' or JOBVR = 'V',* LWORK >= 3*N. If SENSE = 'V' or 'B', LWORK >= N*(N+6).* For good performance, LWORK must generally be larger.** 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.** IWORK (workspace) INTEGER array, dimension (2*N-2)* If SENSE = 'N' or 'E', not referenced.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: if INFO = i, the QR algorithm failed to compute all the* eigenvalues, and no eigenvectors or condition numbers* have been computed; elements 1:ILO-1 and i+1:N of WR* and WI contain eigenvalues which have converged.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,$ WNTSNN, WNTSNVCHARACTER JOB, SIDEINTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K, MAXB,$ MAXWRK, MINWRK, NOUTDOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,$ SN* ..* .. Local Arrays ..LOGICAL SELECT( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY, DLARTG,$ DLASCL, DORGHR, DROT, DSCAL, DTREVC, DTRSNA,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAX, ILAENVDOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,$ DNRM2* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )WANTVL = LSAME( JOBVL, 'V' )WANTVR = LSAME( JOBVR, 'V' )WNTSNN = LSAME( SENSE, 'N' )WNTSNE = LSAME( SENSE, 'E' )WNTSNV = LSAME( SENSE, 'V' )WNTSNB = LSAME( SENSE, 'B' )IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC,$ 'S' ) .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )$ THENINFO = -1ELSE IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THENINFO = -2ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THENINFO = -3ELSE IF( .NOT.( WNTSNN .OR. WNTSNE .OR. WNTSNB .OR. WNTSNV ) .OR.$ ( ( WNTSNE .OR. WNTSNB ) .AND. .NOT.( WANTVL .AND.$ WANTVR ) ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THENINFO = -11ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THENINFO = -13END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.)*MINWRK = 1IF( INFO.EQ.0 .AND. ( LWORK.GE.1 .OR. LQUERY ) ) THENMAXWRK = N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THENMINWRK = MAX( 1, 2*N )IF( .NOT.WNTSNN )$ MINWRK = MAX( MINWRK, N*N+6*N )MAXB = MAX( ILAENV( 8, 'DHSEQR', 'SN', N, 1, N, -1 ), 2 )IF( WNTSNN ) THENK = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'EN', N,$ 1, N, -1 ) ) )ELSEK = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'SN', N,$ 1, N, -1 ) ) )END IFHSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, 1, HSWORK )IF( .NOT.WNTSNN )$ MAXWRK = MAX( MAXWRK, N*N+6*N )ELSEMINWRK = MAX( 1, 3*N )IF( ( .NOT.WNTSNN ) .AND. ( .NOT.WNTSNE ) )$ MINWRK = MAX( MINWRK, N*N+6*N )MAXB = MAX( ILAENV( 8, 'DHSEQR', 'SN', N, 1, N, -1 ), 2 )K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'DHSEQR', 'EN', N, 1,$ N, -1 ) ) )HSWORK = MAX( K*( K+2 ), 2*N )MAXWRK = MAX( MAXWRK, 1, HSWORK )MAXWRK = MAX( MAXWRK, N+( N-1 )*$ ILAENV( 1, 'DORGHR', ' ', N, 1, N, -1 ) )IF( ( .NOT.WNTSNN ) .AND. ( .NOT.WNTSNE ) )$ MAXWRK = MAX( MAXWRK, N*N+6*N )MAXWRK = MAX( MAXWRK, 3*N, 1 )END IFWORK( 1 ) = MAXWRKEND IFIF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -21END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEVX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ICOND = 0ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Balance the matrix and compute ABNRM*CALL DGEBAL( BALANC, N, A, LDA, ILO, IHI, SCALE, IERR )ABNRM = DLANGE( '1', N, N, A, LDA, DUM )IF( SCALEA ) THENDUM( 1 ) = ABNRMCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )ABNRM = DUM( 1 )END IF** Reduce to upper Hessenberg form* (Workspace: need 2*N, prefer N+N*NB)*ITAU = 1IWRK = ITAU + NCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVL ) THEN** Want left eigenvectors* Copy Householder vectors to VL*SIDE = 'L'CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )** Generate orthogonal matrix in VL* (Workspace: need 2*N-1, prefer N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VL* (Workspace: need 1, prefer HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*IF( WANTVR ) THEN** Want left and right eigenvectors* Copy Schur vectors to VR*SIDE = 'B'CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )END IF*ELSE IF( WANTVR ) THEN** Want right eigenvectors* Copy Householder vectors to VR*SIDE = 'R'CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )** Generate orthogonal matrix in VR* (Workspace: need 2*N-1, prefer N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VR* (Workspace: need 1, prefer HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*ELSE** Compute eigenvalues only* If condition numbers desired, compute Schur form*IF( WNTSNN ) THENJOB = 'E'ELSEJOB = 'S'END IF** (Workspace: need 1, prefer HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( JOB, 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )END IF** If INFO > 0 from DHSEQR, then quit*IF( INFO.GT.0 )$ GO TO 50*IF( WANTVL .OR. WANTVR ) THEN** Compute left and/or right eigenvectors* (Workspace: need 3*N)*CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,$ N, NOUT, WORK( IWRK ), IERR )END IF** Compute condition numbers if desired* (Workspace: need N*N+6*N unless SENSE = 'E')*IF( .NOT.WNTSNN ) THENCALL DTRSNA( SENSE, 'A', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,$ RCONDE, RCONDV, N, NOUT, WORK( IWRK ), N, IWORK,$ ICOND )END IF*IF( WANTVL ) THEN** Undo balancing of left eigenvectors*CALL DGEBAK( BALANC, 'L', N, ILO, IHI, SCALE, N, VL, LDVL,$ IERR )** Normalize left eigenvectors and make largest component real*DO 20 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),$ DNRM2( N, VL( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )DO 10 K = 1, NWORK( K ) = VL( K, I )**2 + VL( K, I+1 )**210 CONTINUEK = IDAMAX( N, WORK, 1 )CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )VL( K, I+1 ) = ZEROEND IF20 CONTINUEEND IF*IF( WANTVR ) THEN** Undo balancing of right eigenvectors*CALL DGEBAK( BALANC, 'R', N, ILO, IHI, SCALE, N, VR, LDVR,$ IERR )** Normalize right eigenvectors and make largest component real*DO 40 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),$ DNRM2( N, VR( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )DO 30 K = 1, NWORK( K ) = VR( K, I )**2 + VR( K, I+1 )**230 CONTINUEK = IDAMAX( N, WORK, 1 )CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )VR( K, I+1 ) = ZEROEND IF40 CONTINUEEND IF** Undo scaling if necessary*50 CONTINUEIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )IF( INFO.EQ.0 ) THENIF( ( WNTSNV .OR. WNTSNB ) .AND. ICOND.EQ.0 )$ CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, RCONDV, N,$ IERR )ELSECALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,$ IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,$ IERR )END IFEND IF*WORK( 1 ) = MAXWRKRETURN** End of DGEEVX*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 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 DGESC2( N, A, LDA, RHS, IPIV, JPIV, SCALE )** -- LAPACK auxiliary 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 LDA, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..INTEGER IPIV( * ), JPIV( * )DOUBLE PRECISION A( LDA, * ), RHS( * )* ..** Purpose* =======** DGESC2 solves a system of linear equations** A * X = scale* RHS** with a general N-by-N matrix A using the LU factorization with* complete pivoting computed by DGETC2.** Arguments* =========** N (input) INTEGER* The order of the matrix A.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the LU part of the factorization of the n-by-n* matrix A computed by DGETC2: A = P * L * U * Q** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1, N).** RHS (input/output) DOUBLE PRECISION array, dimension (N).* On entry, the right hand side vector b.* On exit, the solution vector X.** IPIV (iput) INTEGER array, dimension (N).* The pivot indices; for 1 <= i <= N, row i of the* matrix has been interchanged with row IPIV(i).** JPIV (iput) INTEGER array, dimension (N).* The pivot indices; for 1 <= j <= N, column j of the* matrix has been interchanged with column JPIV(j).** SCALE (output) DOUBLE PRECISION* On exit, SCALE contains the scale factor. SCALE is chosen* 0 <= SCALE <= 1 to prevent owerflow in the solution.** Further Details* ===============** Based on contributions by* Bo Kagstrom and Peter Poromaa, Department of Computing Science,* Umea University, S-901 87 Umea, Sweden.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, TWOPARAMETER ( ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION BIGNUM, EPS, SMLNUM, TEMP* ..* .. External Subroutines ..EXTERNAL DLASWP, DSCAL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL IDAMAX, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Set constant to control owerflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Apply permutations IPIV to RHS*CALL DLASWP( 1, RHS, LDA, 1, N-1, IPIV, 1 )** Solve for L part*DO 20 I = 1, N - 1DO 10 J = I + 1, NRHS( J ) = RHS( J ) - A( J, I )*RHS( I )10 CONTINUE20 CONTINUE** Solve for U part*SCALE = ONE** Check for scaling*I = IDAMAX( N, RHS, 1 )IF( TWO*SMLNUM*ABS( RHS( I ) ).GT.ABS( A( N, N ) ) ) THENTEMP = ( ONE / TWO ) / ABS( RHS( I ) )CALL DSCAL( N, TEMP, RHS( 1 ), 1 )SCALE = SCALE*TEMPEND IF*DO 40 I = N, 1, -1TEMP = ONE / A( I, I )RHS( I ) = RHS( I )*TEMPDO 30 J = I + 1, NRHS( I ) = RHS( I ) - RHS( J )*( A( I, J )*TEMP )30 CONTINUE40 CONTINUE** Apply permutations JPIV to the solution (RHS)*CALL DLASWP( 1, RHS, LDA, 1, N-1, JPIV, -1 )RETURN** End of DGESC2*ENDSUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,$ WORK, LWORK, INFO )** -- LAPACK driver 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 JOBU, JOBVTINTEGER INFO, LDA, LDU, LDVT, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** Purpose* =======** DGESVD computes the singular value decomposition (SVD) of a real* M-by-N matrix A, optionally computing the left and/or right singular* vectors. The SVD is written** A = U * SIGMA * transpose(V)** where SIGMA is an M-by-N matrix which is zero except for its* min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and* V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA* are the singular values of A; they are real and non-negative, and* are returned in descending order. The first min(m,n) columns of* U and V are the left and right singular vectors of A.** Note that the routine returns V**T, not V.** Arguments* =========** JOBU (input) CHARACTER*1* Specifies options for computing all or part of the matrix U:* = 'A': all M columns of U are returned in array U:* = 'S': the first min(m,n) columns of U (the left singular* vectors) are returned in the array U;* = 'O': the first min(m,n) columns of U (the left singular* vectors) are overwritten on the array A;* = 'N': no columns of U (no left singular vectors) are* computed.** JOBVT (input) CHARACTER*1* Specifies options for computing all or part of the matrix* V**T:* = 'A': all N rows of V**T are returned in the array VT;* = 'S': the first min(m,n) rows of V**T (the right singular* vectors) are returned in the array VT;* = 'O': the first min(m,n) rows of V**T (the right singular* vectors) are overwritten on the array A;* = 'N': no rows of V**T (no right singular vectors) are* computed.** JOBVT and JOBU cannot both be 'O'.** M (input) INTEGER* The number of rows of the input matrix A. M >= 0.** N (input) INTEGER* The number of columns of the input matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit,* if JOBU = 'O', A is overwritten with the first min(m,n)* columns of U (the left singular vectors,* stored columnwise);* if JOBVT = 'O', A is overwritten with the first min(m,n)* rows of V**T (the right singular vectors,* stored rowwise);* if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A* are destroyed.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** S (output) DOUBLE PRECISION array, dimension (min(M,N))* The singular values of A, sorted so that S(i) >= S(i+1).** U (output) DOUBLE PRECISION array, dimension (LDU,UCOL)* (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.* If JOBU = 'A', U contains the M-by-M orthogonal matrix U;* if JOBU = 'S', U contains the first min(m,n) columns of U* (the left singular vectors, stored columnwise);* if JOBU = 'N' or 'O', U is not referenced.** LDU (input) INTEGER* The leading dimension of the array U. LDU >= 1; if* JOBU = 'S' or 'A', LDU >= M.** VT (output) DOUBLE PRECISION array, dimension (LDVT,N)* If JOBVT = 'A', VT contains the N-by-N orthogonal matrix* V**T;* if JOBVT = 'S', VT contains the first min(m,n) rows of* V**T (the right singular vectors, stored rowwise);* if JOBVT = 'N' or 'O', VT is not referenced.** LDVT (input) INTEGER* The leading dimension of the array VT. LDVT >= 1; if* JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK;* if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged* superdiagonal elements of an upper bidiagonal matrix B* whose diagonal is in S (not necessarily sorted). B* satisfies A = U * B * VT, so it has the same singular values* as A, and singular vectors related by U and VT.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= 1.* LWORK >= MAX(3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).* For good performance, LWORK should generally be larger.** 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 DBDSQR did not converge, INFO specifies how many* superdiagonals of an intermediate bidiagonal form B* did not converge to zero. See the description of WORK* above for details.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,$ WNTVA, WNTVAS, WNTVN, WNTVO, WNTVSINTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,$ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,$ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,$ NRVT, WRKBLDOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DBDSQR, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,$ DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0MINMN = MIN( M, N )MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )WNTUA = LSAME( JOBU, 'A' )WNTUS = LSAME( JOBU, 'S' )WNTUAS = WNTUA .OR. WNTUSWNTUO = LSAME( JOBU, 'O' )WNTUN = LSAME( JOBU, 'N' )WNTVA = LSAME( JOBVT, 'A' )WNTVS = LSAME( JOBVT, 'S' )WNTVAS = WNTVA .OR. WNTVSWNTVO = LSAME( JOBVT, 'O' )WNTVN = LSAME( JOBVT, 'N' )MINWRK = 1LQUERY = ( LWORK.EQ.-1 )*IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THENINFO = -1ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.$ ( WNTVO .AND. WNTUO ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THENINFO = -9ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.$ ( WNTVS .AND. LDVT.LT.MINMN ) ) THENINFO = -11END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)*IF( INFO.EQ.0 .AND. ( LWORK.GE.1 .OR. LQUERY ) .AND. M.GT.0 .AND.$ N.GT.0 ) THENIF( M.GE.N ) THEN** Compute space needed for DBDSQR*BDSPAC = 5*NIF( M.GE.MNTHR ) THENIF( WNTUN ) THEN** Path 1 (M much larger than N, JOBU='N')*MAXWRK = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,$ -1 )MAXWRK = MAX( MAXWRK, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )IF( WNTVO .OR. WNTVAS )$ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )MAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 4*N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUO .AND. WNTVN ) THEN** Path 2 (M much larger than N, JOBU='O', JOBVT='N')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,$ N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )MINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUO .AND. WNTVAS ) THEN** Path 3 (M much larger than N, JOBU='O', JOBVT='S' or* 'A')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,$ N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )MINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUS .AND. WNTVN ) THEN** Path 4 (M much larger than N, JOBU='S', JOBVT='N')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,$ N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUS .AND. WNTVO ) THEN** Path 5 (M much larger than N, JOBU='S', JOBVT='O')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,$ N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*N*N + WRKBLMINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUS .AND. WNTVAS ) THEN** Path 6 (M much larger than N, JOBU='S', JOBVT='S' or* 'A')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,$ N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUA .AND. WNTVN ) THEN** Path 7 (M much larger than N, JOBU='A', JOBVT='N')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,$ M, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUA .AND. WNTVO ) THEN** Path 8 (M much larger than N, JOBU='A', JOBVT='O')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,$ M, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*N*N + WRKBLMINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTUA .AND. WNTVAS ) THEN** Path 9 (M much larger than N, JOBU='A', JOBVT='S' or* 'A')*WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,$ M, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+2*N*$ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )WRKBL = MAX( WRKBL, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )WRKBL = MAX( WRKBL, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )END IFELSE** Path 10 (M at least N, but not much larger)*MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,$ -1, -1 )IF( WNTUS .OR. WNTUO )$ MAXWRK = MAX( MAXWRK, 3*N+N*$ ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 ) )IF( WNTUA )$ MAXWRK = MAX( MAXWRK, 3*N+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, N, -1 ) )IF( .NOT.WNTVN )$ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*$ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )MAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 3*N+M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )END IFELSE** Compute space needed for DBDSQR*BDSPAC = 5*MIF( N.GE.MNTHR ) THENIF( WNTVN ) THEN** Path 1t(N much larger than M, JOBVT='N')*MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,$ -1 )MAXWRK = MAX( MAXWRK, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )IF( WNTUO .OR. WNTUAS )$ MAXWRK = MAX( MAXWRK, 3*M+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )MAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 4*M, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVO .AND. WNTUN ) THEN** Path 2t(N much larger than M, JOBU='N', JOBVT='O')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )MINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVO .AND. WNTUAS ) THEN** Path 3t(N much larger than M, JOBU='S' or 'A',* JOBVT='O')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )MINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVS .AND. WNTUN ) THEN** Path 4t(N much larger than M, JOBU='N', JOBVT='S')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVS .AND. WNTUO ) THEN** Path 5t(N much larger than M, JOBU='O', JOBVT='S')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*M*M + WRKBLMINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVS .AND. WNTUAS ) THEN** Path 6t(N much larger than M, JOBU='S' or 'A',* JOBVT='S')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVA .AND. WNTUN ) THEN** Path 7t(N much larger than M, JOBU='N', JOBVT='A')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVA .AND. WNTUO ) THEN** Path 8t(N much larger than M, JOBU='O', JOBVT='A')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*M*M + WRKBLMINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )ELSE IF( WNTVA .AND. WNTUAS ) THEN** Path 9t(N much larger than M, JOBU='S' or 'A',* JOBVT='A')*WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,$ N, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )WRKBL = MAX( WRKBL, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )WRKBL = MAX( WRKBL, 3*M+M*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )END IFELSE** Path 10t(N greater than M, but not much larger)*MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,$ -1, -1 )IF( WNTVS .OR. WNTVO )$ MAXWRK = MAX( MAXWRK, 3*M+M*$ ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) )IF( WNTVA )$ MAXWRK = MAX( MAXWRK, 3*M+N*$ ILAENV( 1, 'DORGBR', 'P', N, N, M, -1 ) )IF( .NOT.WNTUN )$ MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*$ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )MAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 3*M+N, BDSPAC )MAXWRK = MAX( MAXWRK, MINWRK )END IFEND IFWORK( 1 ) = MAXWRKEND IF*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGESVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENIF( LWORK.GE.1 )$ WORK( 1 ) = ONERETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, DUM )ISCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENISCL = 1CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )ELSE IF( ANRM.GT.BIGNUM ) THENISCL = 1CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )END IF*IF( M.GE.N ) THEN** A has at least as many rows as columns. If A has sufficiently* more rows than columns, first reduce using the QR* decomposition (if sufficient workspace available)*IF( M.GE.MNTHR ) THEN*IF( WNTUN ) THEN** Path 1 (M much larger than N, JOBU='N')* No left singular vectors to be computed*ITAU = 1IWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Zero out below R*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )IE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )NCVT = 0IF( WNTVO .OR. WNTVAS ) THEN** If right singular vectors desired, generate P'.* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )NCVT = NEND IFIWORK = IE + N** Perform bidiagonal QR iteration, computing right* singular vectors of A in A if desired* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,$ DUM, 1, DUM, 1, WORK( IWORK ), INFO )** If right singular vectors desired in VT, copy them there*IF( WNTVAS )$ CALL DLACPY( 'F', N, N, A, LDA, VT, LDVT )*ELSE IF( WNTUO .AND. WNTVN ) THEN** Path 2 (M much larger than N, JOBU='O', JOBVT='N')* N left singular vectors to be overwritten on A and* no right singular vectors to be computed*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN** WORK(IU) is LDA by N, WORK(IR) is LDA by N*LDWRKU = LDALDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN** WORK(IU) is LDA by N, WORK(IR) is N by N*LDWRKU = LDALDWRKR = NELSE** WORK(IU) is LDWRKU by N, WORK(IR) is N by N*LDWRKU = ( LWORK-N*N-N ) / NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IR) and zero out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),$ LDWRKR )** Generate Q in A* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing R* (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR)* (Workspace: need N*N+BDSPAC)*CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,$ WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + N** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in WORK(IU) and copying to A* (Workspace: need N*N+2*N, prefer N*N+M*N+N)*DO 10 I = 1, M, LDWRKUCHUNK = MIN( M-I+1, LDWRKU )CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),$ LDA, WORK( IR ), LDWRKR, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,$ A( I, 1 ), LDA )10 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize A* (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing A* (Workspace: need 4*N, prefer 3*N+N*NB)*CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,$ A, LDA, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTUO .AND. WNTVAS ) THEN** Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')* N left singular vectors to be overwritten on A and* N right singular vectors to be computed in VT*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by N*LDWRKU = LDALDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is N by N*LDWRKU = LDALDWRKR = NELSE** WORK(IU) is LDWRKU by N and WORK(IR) is N by N*LDWRKU = ( LWORK-N*N-N ) / NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, VT( 2, 1 ),$ LDVT )** Generate Q in A* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT, copying result to WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )** Generate left vectors bidiagonalizing R in WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing R in VT* (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR) and computing right* singular vectors of R in VT* (Workspace: need N*N+BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,$ WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + N** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in WORK(IU) and copying to A* (Workspace: need N*N+2*N, prefer N*N+M*N+N)*DO 20 I = 1, M, LDWRKUCHUNK = MIN( M-I+1, LDWRKU )CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),$ LDA, WORK( IR ), LDWRKR, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,$ A( I, 1 ), LDA )20 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, VT( 2, 1 ),$ LDVT )** Generate Q in A* (Workspace: need 2*N, prefer N+N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in A by left vectors bidiagonalizing R* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,$ WORK( ITAUQ ), A, LDA, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing R in VT* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in A and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,$ A, LDA, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTUS ) THEN*IF( WNTVN ) THEN** Path 4 (M much larger than N, JOBU='S', JOBVT='N')* N left singular vectors to be computed in U and* no right singular vectors to be computed*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IR) is LDA by N*LDWRKR = LDAELSE** WORK(IR) is N by N*LDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IR), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IR+1 ), LDWRKR )** Generate Q in A* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing R in WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR)* (Workspace: need N*N+BDSPAC)*CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,$ 1, WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in U* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,$ WORK( IR ), LDWRKR, ZERO, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N, prefer N+N*NB)*CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),$ LDA )** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left vectors bidiagonalizing R* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,$ 1, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVO ) THEN** Path 5 (M much larger than N, JOBU='S', JOBVT='O')* N left singular vectors to be computed in U and* N right singular vectors to be overwritten on A*IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is N by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = NELSE** WORK(IU) is N by N and WORK(IR) is N by N*LDWRKU = NIR = IU + LDWRKU*NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )** Generate Q in A* (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*N*N+4*N,* prefer 2*N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*N*N+4*N-1,* prefer 2*N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in WORK(IR)* (Workspace: need 2*N*N+BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, WORK( IU ),$ LDWRKU, DUM, 1, WORK( IWORK ), INFO )** Multiply Q in A by left singular vectors of R in* WORK(IU), storing result in U* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,$ WORK( IU ), LDWRKU, ZERO, U, LDU )** Copy right singular vectors of R to A* (Workspace: need N*N)*CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N, prefer N+N*NB)*CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),$ LDA )** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left vectors bidiagonalizing R* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing R in A* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,$ LDA, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVAS ) THEN** Path 6 (M much larger than N, JOBU='S', JOBVT='S'* or 'A')* N left singular vectors to be computed in U and* N right singular vectors to be computed in VT*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IU) is LDA by N*LDWRKU = LDAELSE** WORK(IU) is N by N*LDWRKU = NEND IFITAU = IU + LDWRKU*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )** Generate Q in A* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to VT* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,$ LDVT )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need N*N+4*N-1,* prefer N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in VT* (Workspace: need N*N+BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,$ LDVT, WORK( IU ), LDWRKU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in A by left singular vectors of R in* WORK(IU), storing result in U* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,$ WORK( IU ), LDWRKU, ZERO, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N, prefer N+N*NB)*CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, VT( 2, 1 ),$ LDVT )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in VT* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*ELSE IF( WNTUA ) THEN*IF( WNTVN ) THEN** Path 7 (M much larger than N, JOBU='A', JOBVT='N')* M left singular vectors to be computed in U and* no right singular vectors to be computed*IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IR) is LDA by N*LDWRKR = LDAELSE** WORK(IR) is N by N*LDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Copy R to WORK(IR), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IR+1 ), LDWRKR )** Generate Q in U* (Workspace: need N*N+N+M, prefer N*N+N+M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in WORK(IR)* (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR)* (Workspace: need N*N+BDSPAC)*CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,$ 1, WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in U by left singular vectors of R in* WORK(IR), storing result in A* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,$ WORK( IR ), LDWRKR, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N+M, prefer N+M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),$ LDA )** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in A* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,$ 1, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVO ) THEN** Path 8 (M much larger than N, JOBU='A', JOBVT='O')* M left singular vectors to be computed in U and* N right singular vectors to be overwritten on A*IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is N by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = NELSE** WORK(IU) is N by N and WORK(IR) is N by N*LDWRKU = NIR = IU + LDWRKU*NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*N*N+4*N,* prefer 2*N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*N*N+4*N-1,* prefer 2*N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in WORK(IR)* (Workspace: need 2*N*N+BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, WORK( IU ),$ LDWRKU, DUM, 1, WORK( IWORK ), INFO )** Multiply Q in U by left singular vectors of R in* WORK(IU), storing result in A* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,$ WORK( IU ), LDWRKU, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )** Copy right singular vectors of R from WORK(IR) to A*CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N+M, prefer N+M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),$ LDA )** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in A* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in A* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,$ LDA, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVAS ) THEN** Path 9 (M much larger than N, JOBU='A', JOBVT='S'* or 'A')* M left singular vectors to be computed in U and* N right singular vectors to be computed in VT*IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IU) is LDA by N*LDWRKU = LDAELSE** WORK(IU) is N by N*LDWRKU = NEND IFITAU = IU + LDWRKU*NIWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N*N+N+M, prefer N*N+N+M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to VT* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,$ LDVT )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need N*N+4*N-1,* prefer N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in VT* (Workspace: need N*N+BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,$ LDVT, WORK( IU ), LDWRKU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in U by left singular vectors of R in* WORK(IU), storing result in A* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,$ WORK( IU ), LDWRKU, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N+M, prefer N+M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R from A to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, VT( 2, 1 ),$ LDVT )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT* (Workspace: need 4*N, prefer 3*N+2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in VT* (Workspace: need 3*N+M, prefer 3*N+M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*END IF*ELSE** M .LT. MNTHR** Path 10 (M at least N, but not much larger)* Reduce to bidiagonal form without QR decomposition*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize A* (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )IF( WNTUAS ) THEN** If left singular vectors desired in U, copy result to U* and generate left bidiagonalizing vectors in U* (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)*CALL DLACPY( 'L', M, N, A, LDA, U, LDU )IF( WNTUS )$ NCU = NIF( WNTUA )$ NCU = MCALL DORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVAS ) THEN** If right singular vectors desired in VT, copy result to* VT and generate right bidiagonalizing vectors in VT* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTUO ) THEN** If left singular vectors desired in A, generate left* bidiagonalizing vectors in A* (Workspace: need 4*N, prefer 3*N+N*NB)*CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVO ) THEN** If right singular vectors desired in A, generate right* bidiagonalizing vectors in A* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIWORK = IE + NIF( WNTUAS .OR. WNTUO )$ NRU = MIF( WNTUN )$ NRU = 0IF( WNTVAS .OR. WNTVO )$ NCVT = NIF( WNTVN )$ NCVT = 0IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,$ U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in A and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )END IF*END IF*ELSE** A has more columns than rows. If A has sufficiently more* columns than rows, first reduce using the LQ decomposition (if* sufficient workspace available)*IF( N.GE.MNTHR ) THEN*IF( WNTVN ) THEN** Path 1t(N much larger than M, JOBVT='N')* No right singular vectors to be computed*ITAU = 1IWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Zero out above L*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )IF( WNTUO .OR. WNTUAS ) THEN** If left singular vectors desired, generate Q* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIWORK = IE + MNRU = 0IF( WNTUO .OR. WNTUAS )$ NRU = M** Perform bidiagonal QR iteration, computing left singular* vectors of A in A if desired* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,$ LDA, DUM, 1, WORK( IWORK ), INFO )** If left singular vectors desired in U, copy them there*IF( WNTUAS )$ CALL DLACPY( 'F', M, M, A, LDA, U, LDU )*ELSE IF( WNTVO .AND. WNTUN ) THEN** Path 2t(N much larger than M, JOBU='N', JOBVT='O')* M right singular vectors to be overwritten on A and* no left singular vectors to be computed*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by M*LDWRKU = LDACHUNK = NLDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is M by M*LDWRKU = LDACHUNK = NLDWRKR = MELSE** WORK(IU) is M by CHUNK and WORK(IR) is M by M*LDWRKU = MCHUNK = ( LWORK-M*M-M ) / MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IR) and zero out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IR+LDWRKR ), LDWRKR )** Generate Q in A* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IR)* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing L* (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + M** Multiply right singular vectors of L in WORK(IR) by Q* in A, storing result in WORK(IU) and copying to A* (Workspace: need M*M+2*M, prefer M*M+M*N+M)*DO 30 I = 1, N, CHUNKBLK = MIN( N-I+1, CHUNK )CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),$ LDWRKR, A( 1, I ), LDA, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,$ A( 1, I ), LDA )30 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize A* (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing A* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,$ DUM, 1, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTVO .AND. WNTUAS ) THEN** Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')* M right singular vectors to be overwritten on A and* M left singular vectors to be computed in U*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by M*LDWRKU = LDACHUNK = NLDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is M by M*LDWRKU = LDACHUNK = NLDWRKR = MELSE** WORK(IU) is M by CHUNK and WORK(IR) is M by M*LDWRKU = MCHUNK = ( LWORK-M*M-M ) / MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing about above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )** Generate Q in A* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U, copying result to WORK(IR)* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )** Generate right vectors bidiagonalizing L in WORK(IR)* (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing L in U* (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in U, and computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, U, LDU, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + M** Multiply right singular vectors of L in WORK(IR) by Q* in A, storing result in WORK(IU) and copying to A* (Workspace: need M*M+2*M, prefer M*M+M*N+M))*DO 40 I = 1, N, CHUNKBLK = MIN( N-I+1, CHUNK )CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),$ LDWRKR, A( 1, I ), LDA, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,$ A( 1, I ), LDA )40 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )** Generate Q in A* (Workspace: need 2*M, prefer M+M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right vectors bidiagonalizing L by Q in A* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,$ WORK( ITAUP ), A, LDA, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing L in U* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,$ U, LDU, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTVS ) THEN*IF( WNTUN ) THEN** Path 4t(N much larger than M, JOBU='N', JOBVT='S')* M right singular vectors to be computed in VT and* no left singular vectors to be computed*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IR) is LDA by M*LDWRKR = LDAELSE** WORK(IR) is M by M*LDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IR), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IR+LDWRKR ), LDWRKR )** Generate Q in A* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IR)* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing L in* WORK(IR)* (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IR) by* Q in A, storing result in VT* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),$ LDWRKR, A, LDA, ZERO, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy result to VT*CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right vectors bidiagonalizing L by Q in VT* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,$ LDVT, DUM, 1, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUO ) THEN** Path 5t(N much larger than M, JOBU='O', JOBVT='S')* M right singular vectors to be computed in VT and* M left singular vectors to be overwritten on A*IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is LDA by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is M by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = MELSE** WORK(IU) is M by M and WORK(IR) is M by M*LDWRKU = MIR = IU + LDWRKU*MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out below it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )** Generate Q in A* (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*M*M+4*M,* prefer 2*M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*M*M+4*M-1,* prefer 2*M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in WORK(IR) and computing* right singular vectors of L in WORK(IU)* (Workspace: need 2*M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, WORK( IR ),$ LDWRKR, DUM, 1, WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in A, storing result in VT* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, A, LDA, ZERO, VT, LDVT )** Copy left singular vectors of L to A* (Workspace: need M*M)*CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right vectors bidiagonalizing L by Q in VT* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors of L in A* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, compute left* singular vectors of A in A and compute right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUAS ) THEN** Path 6t(N much larger than M, JOBU='S' or 'A',* JOBVT='S')* M right singular vectors to be computed in VT and* M left singular vectors to be computed in U*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IU) is LDA by N*LDWRKU = LDAELSE** WORK(IU) is LDA by M*LDWRKU = MEND IFITAU = IU + LDWRKU*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )** Generate Q in A* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to U* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,$ LDU )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need M*M+4*M-1,* prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in U and computing right* singular vectors of L in WORK(IU)* (Workspace: need M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, U, LDU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in A, storing result in VT* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, A, LDA, ZERO, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in U by Q* in VT* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*ELSE IF( WNTVA ) THEN*IF( WNTUN ) THEN** Path 7t(N much larger than M, JOBU='N', JOBVT='A')* N right singular vectors to be computed in VT and* no left singular vectors to be computed*IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IR) is LDA by M*LDWRKR = LDAELSE** WORK(IR) is M by M*LDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Copy L to WORK(IR), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IR+LDWRKR ), LDWRKR )** Generate Q in VT* (Workspace: need M*M+M+N, prefer M*M+M+N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IR)* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in WORK(IR)* (Workspace: need M*M+4*M-1,* prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IR) by* Q in VT, storing result in A* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),$ LDWRKR, VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M+N, prefer M+N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in A by Q* in VT* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,$ LDVT, DUM, 1, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUO ) THEN** Path 8t(N much larger than M, JOBU='O', JOBVT='A')* N right singular vectors to be computed in VT and* M left singular vectors to be overwritten on A*IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is LDA by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is M by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = MELSE** WORK(IU) is M by M and WORK(IR) is M by M*LDWRKU = MIR = IU + LDWRKU*MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*M*M+4*M,* prefer 2*M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*M*M+4*M-1,* prefer 2*M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in WORK(IR) and computing* right singular vectors of L in WORK(IU)* (Workspace: need 2*M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, WORK( IR ),$ LDWRKR, DUM, 1, WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in VT, storing result in A* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )** Copy left singular vectors of A from WORK(IR) to A*CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M+N, prefer M+N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in A by Q* in VT* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in A* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in A and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUAS ) THEN** Path 9t(N much larger than M, JOBU='S' or 'A',* JOBVT='A')* N right singular vectors to be computed in VT and* M left singular vectors to be computed in U*IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IU) is LDA by M*LDWRKU = LDAELSE** WORK(IU) is M by M*LDWRKU = MEND IFITAU = IU + LDWRKU*MIWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M*M+M+N, prefer M*M+M+N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to U* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,$ LDU )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in U and computing right* singular vectors of L in WORK(IU)* (Workspace: need M*M+BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, U, LDU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in VT, storing result in A* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M+N, prefer M+N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U* (Workspace: need 4*M, prefer 3*M+2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in U by Q* in VT* (Workspace: need 3*M+N, prefer 3*M+N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*END IF*ELSE** N .LT. MNTHR** Path 10t(N greater than M, but not much larger)* Reduce to bidiagonal form without LQ decomposition*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize A* (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )IF( WNTUAS ) THEN** If left singular vectors desired in U, copy result to U* and generate left bidiagonalizing vectors in U* (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVAS ) THEN** If right singular vectors desired in VT, copy result to* VT and generate right bidiagonalizing vectors in VT* (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)*CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )IF( WNTVA )$ NRVT = NIF( WNTVS )$ NRVT = MCALL DORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTUO ) THEN** If left singular vectors desired in A, generate left* bidiagonalizing vectors in A* (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)*CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVO ) THEN** If right singular vectors desired in A, generate right* bidiagonalizing vectors in A* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIWORK = IE + MIF( WNTUAS .OR. WNTUO )$ NRU = MIF( WNTUN )$ NRU = 0IF( WNTVAS .OR. WNTVO )$ NCVT = NIF( WNTVN )$ NCVT = 0IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,$ U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in A and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )END IF*END IF*END IF** If DBDSQR failed to converge, copy unconverged superdiagonals* to WORK( 2:MINMN )*IF( INFO.NE.0 ) THENIF( IE.GT.2 ) THENDO 50 I = 1, MINMN - 1WORK( I+1 ) = WORK( I+IE-1 )50 CONTINUEEND IFIF( IE.LT.2 ) THENDO 60 I = MINMN - 1, 1, -1WORK( I+1 ) = WORK( I+IE-1 )60 CONTINUEEND IFEND IF** Undo scaling if necessary*IF( ISCL.EQ.1 ) THENIF( ANRM.GT.BIGNUM )$ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,$ IERR )IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )$ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),$ MINMN, IERR )IF( ANRM.LT.SMLNUM )$ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,$ IERR )IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )$ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),$ MINMN, IERR )END IF** Return optimal workspace in WORK(1)*WORK( 1 ) = MAXWRK*RETURN** End of DGESVD*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 DLABAD( SMALL, LARGE )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION LARGE, SMALL* ..** Purpose* =======** DLABAD takes as input the values computed by DLAMCH for underflow and* overflow, and returns the square root of each of these values if the* log of LARGE is sufficiently large. This subroutine is intended to* identify machines with a large exponent range, such as the Crays, and* redefine the underflow and overflow limits to be the square roots of* the values computed by DLAMCH. This subroutine is needed because* DLAMCH does not compensate for poor arithmetic in the upper half of* the exponent range, as is found on a Cray.** Arguments* =========** SMALL (input/output) DOUBLE PRECISION* On entry, the underflow threshold as computed by DLAMCH.* On exit, if LOG10(LARGE) is sufficiently large, the square* root of SMALL, otherwise unchanged.** LARGE (input/output) DOUBLE PRECISION* On entry, the overflow threshold as computed by DLAMCH.* On exit, if LOG10(LARGE) is sufficiently large, the square* root of LARGE, otherwise unchanged.** =====================================================================** .. Intrinsic Functions ..INTRINSIC LOG10, SQRT* ..* .. Executable Statements ..** If it looks like we're on a Cray, take the square root of* SMALL and LARGE to avoid overflow and underflow problems.*IF( LOG10( LARGE ).GT.2000.D0 ) THENSMALL = SQRT( SMALL )LARGE = SQRT( LARGE )END IF*RETURN** End of DLABAD*ENDSUBROUTINE DLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,$ LDY )** -- LAPACK auxiliary 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 LDA, LDX, LDY, M, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),$ TAUQ( * ), X( LDX, * ), Y( LDY, * )* ..** Purpose* =======** DLABRD reduces the first NB rows and columns of a real general* m by n matrix A to upper or lower bidiagonal form by an orthogonal* transformation Q' * A * P, and returns the matrices X and Y which* are needed to apply the transformation to the unreduced part of A.** If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower* bidiagonal form.** This is an auxiliary routine called by DGEBRD** Arguments* =========** M (input) INTEGER* The number of rows in the matrix A.** N (input) INTEGER* The number of columns in the matrix A.** NB (input) INTEGER* The number of leading rows and columns of A to be reduced.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the m by n general matrix to be reduced.* On exit, the first NB rows and columns of the matrix are* overwritten; the rest of the array is unchanged.* If m >= n, elements on and below the diagonal in the first NB* columns, with the array TAUQ, represent the orthogonal* matrix Q as a product of elementary reflectors; and* elements above the diagonal in the first NB rows, with the* array TAUP, represent the orthogonal matrix P as a product* of elementary reflectors.* If m < n, elements below the diagonal in the first NB* columns, with the array TAUQ, represent the orthogonal* matrix Q as a product of elementary reflectors, and* elements on and above the diagonal in the first NB rows,* 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 (NB)* The diagonal elements of the first NB rows and columns of* the reduced matrix. D(i) = A(i,i).** E (output) DOUBLE PRECISION array, dimension (NB)* The off-diagonal elements of the first NB rows and columns of* the reduced matrix.** TAUQ (output) DOUBLE PRECISION array dimension (NB)* The scalar factors of the elementary reflectors which* represent the orthogonal matrix Q. See Further Details.** TAUP (output) DOUBLE PRECISION array, dimension (NB)* The scalar factors of the elementary reflectors which* represent the orthogonal matrix P. See Further Details.** X (output) DOUBLE PRECISION array, dimension (LDX,NB)* The m-by-nb matrix X required to update the unreduced part* of A.** LDX (input) INTEGER* The leading dimension of the array X. LDX >= M.** Y (output) DOUBLE PRECISION array, dimension (LDY,NB)* The n-by-nb matrix Y required to update the unreduced part* of A.** LDY (output) INTEGER* The leading dimension of the array Y. LDY >= N.** Further Details* ===============** The matrices Q and P are represented as products of elementary* reflectors:** Q = H(1) H(2) . . . H(nb) and P = G(1) G(2) . . . G(nb)** 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.** If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in* A(i:m,i); u(1:i) = 0, u(i+1) = 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).** If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in* A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in* A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).** The elements of the vectors v and u together form the m-by-nb matrix* V and the nb-by-n matrix U' which are needed, with X and Y, to apply* the transformation to the unreduced part of the matrix, using a block* update of the form: A := A - V*Y' - X*U'.** The contents of A on exit are illustrated by the following examples* with nb = 2:** m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n):** ( 1 1 u1 u1 u1 ) ( 1 u1 u1 u1 u1 u1 )* ( v1 1 1 u2 u2 ) ( 1 1 u2 u2 u2 u2 )* ( v1 v2 a a a ) ( v1 1 a a a a )* ( v1 v2 a a a ) ( v1 v2 a a a a )* ( v1 v2 a a a ) ( v1 v2 a a a a )* ( v1 v2 a a a )** where a denotes an element of the original matrix which is unchanged,* 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.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER I* ..* .. External Subroutines ..EXTERNAL DGEMV, DLARFG, DSCAL* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 )$ RETURN*IF( M.GE.N ) THEN** Reduce to upper bidiagonal form*DO 10 I = 1, NB** Update A(i:m,i)*CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ),$ LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 )CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ),$ LDX, A( 1, I ), 1, ONE, A( I, I ), 1 )** Generate reflection Q(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 )IF( I.LT.N ) THENA( I, I ) = ONE** Compute Y(i+1:n,i)*CALL DGEMV( 'Transpose', M-I+1, N-I, ONE, A( I, I+1 ),$ LDA, A( I, I ), 1, ZERO, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, A( I, 1 ), LDA,$ A( I, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),$ LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, X( I, 1 ), LDX,$ A( I, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),$ LDA, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )** Update A(i,i+1:n)*CALL DGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ),$ LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA )CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),$ LDA, X( I, 1 ), LDX, ONE, A( I, I+1 ), LDA )** Generate reflection P(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** Compute X(i+1:m,i)*CALL DGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ),$ LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I, I, ONE, Y( I+1, 1 ), LDY,$ A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ),$ LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),$ LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),$ LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )END IF10 CONTINUEELSE** Reduce to lower bidiagonal form*DO 20 I = 1, NB** Update A(i,i:n)*CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ),$ LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA )CALL DGEMV( 'Transpose', I-1, N-I+1, -ONE, A( 1, I ), LDA,$ X( I, 1 ), LDX, ONE, A( I, I ), LDA )** Generate reflection P(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 )IF( I.LT.M ) THENA( I, I ) = ONE** Compute X(i+1:m,i)*CALL DGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ),$ LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I+1, I-1, ONE, Y( I, 1 ), LDY,$ A( I, I ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),$ LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ),$ LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),$ LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )** Update A(i+1:m,i)*CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),$ LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ),$ LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 )** Generate reflection Q(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** Compute Y(i+1:n,i)*CALL DGEMV( 'Transpose', M-I, N-I, ONE, A( I+1, I+1 ),$ LDA, A( I+1, I ), 1, ZERO, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I, I-1, ONE, A( I+1, 1 ), LDA,$ A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),$ LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I, I, ONE, X( I+1, 1 ), LDX,$ A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'Transpose', I, N-I, -ONE, A( 1, I+1 ), LDA,$ Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )END IF20 CONTINUEEND IFRETURN** End of DLABRD*ENDSUBROUTINE DLACON( N, V, X, ISGN, EST, KASE )** -- LAPACK auxiliary 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 KASE, NDOUBLE PRECISION EST* ..* .. Array Arguments ..INTEGER ISGN( * )DOUBLE PRECISION V( * ), X( * )* ..** Purpose* =======** DLACON estimates the 1-norm of a square, real matrix A.* Reverse communication is used for evaluating matrix-vector products.** Arguments* =========** N (input) INTEGER* The order of the matrix. N >= 1.** V (workspace) DOUBLE PRECISION array, dimension (N)* On the final return, V = A*W, where EST = norm(V)/norm(W)* (W is not returned).** X (input/output) DOUBLE PRECISION array, dimension (N)* On an intermediate return, X should be overwritten by* A * X, if KASE=1,* A' * X, if KASE=2,* and DLACON must be re-called with all the other parameters* unchanged.** ISGN (workspace) INTEGER array, dimension (N)** EST (output) DOUBLE PRECISION* An estimate (a lower bound) for norm(A).** KASE (input/output) INTEGER* On the initial call to DLACON, KASE should be 0.* On an intermediate return, KASE will be 1 or 2, indicating* whether X should be overwritten by A * X or A' * X.* On the final return from DLACON, KASE will again be 0.** Further Details* ======= =======** Contributed by Nick Higham, University of Manchester.* Originally named SONEST, dated March 16, 1988.** Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of* a real or complex matrix, with applications to condition estimation",* ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER I, ITER, J, JLAST, JUMPDOUBLE PRECISION ALTSGN, ESTOLD, TEMP* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DASUMEXTERNAL IDAMAX, DASUM* ..* .. External Subroutines ..EXTERNAL DCOPY* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, NINT, SIGN* ..* .. Save statement ..SAVE* ..* .. Executable Statements ..*IF( KASE.EQ.0 ) THENDO 10 I = 1, NX( I ) = ONE / DBLE( N )10 CONTINUEKASE = 1JUMP = 1RETURNEND IF*GO TO ( 20, 40, 70, 110, 140 )JUMP** ................ ENTRY (JUMP = 1)* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X.*20 CONTINUEIF( N.EQ.1 ) THENV( 1 ) = X( 1 )EST = ABS( V( 1 ) )* ... QUITGO TO 150END IFEST = DASUM( N, X, 1 )*DO 30 I = 1, NX( I ) = SIGN( ONE, X( I ) )ISGN( I ) = NINT( X( I ) )30 CONTINUEKASE = 2JUMP = 2RETURN** ................ ENTRY (JUMP = 2)* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X.*40 CONTINUEJ = IDAMAX( N, X, 1 )ITER = 2** MAIN LOOP - ITERATIONS 2,3,...,ITMAX.*50 CONTINUEDO 60 I = 1, NX( I ) = ZERO60 CONTINUEX( J ) = ONEKASE = 1JUMP = 3RETURN** ................ ENTRY (JUMP = 3)* X HAS BEEN OVERWRITTEN BY A*X.*70 CONTINUECALL DCOPY( N, X, 1, V, 1 )ESTOLD = ESTEST = DASUM( N, V, 1 )DO 80 I = 1, NIF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )$ GO TO 9080 CONTINUE* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.GO TO 120*90 CONTINUE* TEST FOR CYCLING.IF( EST.LE.ESTOLD )$ GO TO 120*DO 100 I = 1, NX( I ) = SIGN( ONE, X( I ) )ISGN( I ) = NINT( X( I ) )100 CONTINUEKASE = 2JUMP = 4RETURN** ................ ENTRY (JUMP = 4)* X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X.*110 CONTINUEJLAST = JJ = IDAMAX( N, X, 1 )IF( ( X( JLAST ).NE.ABS( X( J ) ) ) .AND. ( ITER.LT.ITMAX ) ) THENITER = ITER + 1GO TO 50END IF** ITERATION COMPLETE. FINAL STAGE.*120 CONTINUEALTSGN = ONEDO 130 I = 1, NX( I ) = ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) )ALTSGN = -ALTSGN130 CONTINUEKASE = 1JUMP = 5RETURN** ................ ENTRY (JUMP = 5)* X HAS BEEN OVERWRITTEN BY A*X.*140 CONTINUETEMP = TWO*( DASUM( N, X, 1 ) / DBLE( 3*N ) )IF( TEMP.GT.EST ) THENCALL DCOPY( N, X, 1, V, 1 )EST = TEMPEND IF*150 CONTINUEKASE = 0RETURN** End of DLACON*ENDSUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB )** -- LAPACK auxiliary 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 UPLOINTEGER LDA, LDB, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** Purpose* =======** DLACPY copies all or part of a two-dimensional matrix A to another* matrix B.** Arguments* =========** UPLO (input) CHARACTER*1* Specifies the part of the matrix A to be copied to B.* = 'U': Upper triangular part* = 'L': Lower triangular part* Otherwise: All of the matrix A** 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 A. If UPLO = 'U', only the upper triangle* or trapezoid is accessed; if UPLO = 'L', only the lower* triangle or trapezoid is accessed.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** B (output) DOUBLE PRECISION array, dimension (LDB,N)* On exit, B = A in the locations specified by UPLO.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,M).** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = 1, MIN( J, M )B( I, J ) = A( I, J )10 CONTINUE20 CONTINUEELSE IF( LSAME( UPLO, 'L' ) ) THENDO 40 J = 1, NDO 30 I = J, MB( I, J ) = A( I, J )30 CONTINUE40 CONTINUEELSEDO 60 J = 1, NDO 50 I = 1, MB( I, J ) = A( I, J )50 CONTINUE60 CONTINUEEND IFRETURN** End of DLACPY*ENDSUBROUTINE DLADIV( A, B, C, D, P, Q )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION A, B, C, D, P, Q* ..** Purpose* =======** DLADIV performs complex division in real arithmetic** a + i*b* p + i*q = ---------* c + i*d** The algorithm is due to Robert L. Smith and can be found* in D. Knuth, The art of Computer Programming, Vol.2, p.195** Arguments* =========** A (input) DOUBLE PRECISION* B (input) DOUBLE PRECISION* C (input) DOUBLE PRECISION* D (input) DOUBLE PRECISION* The scalars a, b, c, and d in the above expression.** P (output) DOUBLE PRECISION* Q (output) DOUBLE PRECISION* The scalars p and q in the above expression.** =====================================================================** .. Local Scalars ..DOUBLE PRECISION E, F* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*IF( ABS( D ).LT.ABS( C ) ) THENE = D / CF = C + D*EP = ( A+B*E ) / FQ = ( B-A*E ) / FELSEE = C / DF = D + C*EP = ( B+A*E ) / FQ = ( -A+B*E ) / FEND IF*RETURN** End of DLADIV*ENDSUBROUTINE DLAE2( A, B, C, RT1, RT2 )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION A, B, C, RT1, RT2* ..** Purpose* =======** DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix* [ A B ]* [ B C ].* On return, RT1 is the eigenvalue of larger absolute value, and RT2* is the eigenvalue of smaller absolute value.** Arguments* =========** A (input) DOUBLE PRECISION* The (1,1) element of the 2-by-2 matrix.** B (input) DOUBLE PRECISION* The (1,2) and (2,1) elements of the 2-by-2 matrix.** C (input) DOUBLE PRECISION* The (2,2) element of the 2-by-2 matrix.** RT1 (output) DOUBLE PRECISION* The eigenvalue of larger absolute value.** RT2 (output) DOUBLE PRECISION* The eigenvalue of smaller absolute value.** Further Details* ===============** RT1 is accurate to a few ulps barring over/underflow.** RT2 may be inaccurate if there is massive cancellation in the* determinant A*C-B*B; higher precision or correctly rounded or* correctly truncated arithmetic would be needed to compute RT2* accurately in all cases.** Overflow is possible only if RT1 is within a factor of 5 of overflow.* Underflow is harmless if the input data is 0 or exceeds* underflow_threshold / macheps.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )* ..* .. Local Scalars ..DOUBLE PRECISION AB, ACMN, ACMX, ADF, DF, RT, SM, TB* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..** Compute the eigenvalues*SM = A + CDF = A - CADF = ABS( DF )TB = B + BAB = ABS( TB )IF( ABS( A ).GT.ABS( C ) ) THENACMX = AACMN = CELSEACMX = CACMN = AEND IFIF( ADF.GT.AB ) THENRT = ADF*SQRT( ONE+( AB / ADF )**2 )ELSE IF( ADF.LT.AB ) THENRT = AB*SQRT( ONE+( ADF / AB )**2 )ELSE** Includes case AB=ADF=0*RT = AB*SQRT( TWO )END IFIF( SM.LT.ZERO ) THENRT1 = HALF*( SM-RT )** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE IF( SM.GT.ZERO ) THENRT1 = HALF*( SM+RT )** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE** Includes case RT1 = RT2 = 0*RT1 = HALF*RTRT2 = -HALF*RTEND IFRETURN** End of DLAE2*ENDSUBROUTINE DLAEV2( A, B, C, RT1, RT2, CS1, SN1 )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION A, B, C, CS1, RT1, RT2, SN1* ..** Purpose* =======** DLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix* [ A B ]* [ B C ].* On return, RT1 is the eigenvalue of larger absolute value, RT2 is the* eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right* eigenvector for RT1, giving the decomposition** [ CS1 SN1 ] [ A B ] [ CS1 -SN1 ] = [ RT1 0 ]* [-SN1 CS1 ] [ B C ] [ SN1 CS1 ] [ 0 RT2 ].** Arguments* =========** A (input) DOUBLE PRECISION* The (1,1) element of the 2-by-2 matrix.** B (input) DOUBLE PRECISION* The (1,2) element and the conjugate of the (2,1) element of* the 2-by-2 matrix.** C (input) DOUBLE PRECISION* The (2,2) element of the 2-by-2 matrix.** RT1 (output) DOUBLE PRECISION* The eigenvalue of larger absolute value.** RT2 (output) DOUBLE PRECISION* The eigenvalue of smaller absolute value.** CS1 (output) DOUBLE PRECISION* SN1 (output) DOUBLE PRECISION* The vector (CS1, SN1) is a unit right eigenvector for RT1.** Further Details* ===============** RT1 is accurate to a few ulps barring over/underflow.** RT2 may be inaccurate if there is massive cancellation in the* determinant A*C-B*B; higher precision or correctly rounded or* correctly truncated arithmetic would be needed to compute RT2* accurately in all cases.** CS1 and SN1 are accurate to a few ulps barring over/underflow.** Overflow is possible only if RT1 is within a factor of 5 of overflow.* Underflow is harmless if the input data is 0 or exceeds* underflow_threshold / macheps.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )* ..* .. Local Scalars ..INTEGER SGN1, SGN2DOUBLE PRECISION AB, ACMN, ACMX, ACS, ADF, CS, CT, DF, RT, SM,$ TB, TN* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..** Compute the eigenvalues*SM = A + CDF = A - CADF = ABS( DF )TB = B + BAB = ABS( TB )IF( ABS( A ).GT.ABS( C ) ) THENACMX = AACMN = CELSEACMX = CACMN = AEND IFIF( ADF.GT.AB ) THENRT = ADF*SQRT( ONE+( AB / ADF )**2 )ELSE IF( ADF.LT.AB ) THENRT = AB*SQRT( ONE+( ADF / AB )**2 )ELSE** Includes case AB=ADF=0*RT = AB*SQRT( TWO )END IFIF( SM.LT.ZERO ) THENRT1 = HALF*( SM-RT )SGN1 = -1** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE IF( SM.GT.ZERO ) THENRT1 = HALF*( SM+RT )SGN1 = 1** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE** Includes case RT1 = RT2 = 0*RT1 = HALF*RTRT2 = -HALF*RTSGN1 = 1END IF** Compute the eigenvector*IF( DF.GE.ZERO ) THENCS = DF + RTSGN2 = 1ELSECS = DF - RTSGN2 = -1END IFACS = ABS( CS )IF( ACS.GT.AB ) THENCT = -TB / CSSN1 = ONE / SQRT( ONE+CT*CT )CS1 = CT*SN1ELSEIF( AB.EQ.ZERO ) THENCS1 = ONESN1 = ZEROELSETN = -CS / TBCS1 = ONE / SQRT( ONE+TN*TN )SN1 = TN*CS1END IFEND IFIF( SGN1.EQ.SGN2 ) THENTN = CS1CS1 = -SN1SN1 = TNEND IFRETURN** End of DLAEV2*ENDSUBROUTINE DLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,$ INFO )** -- LAPACK auxiliary 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 ..LOGICAL WANTQINTEGER INFO, J1, LDQ, LDT, N, N1, N2* ..* .. Array Arguments ..DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )* ..** Purpose* =======** DLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in* an upper quasi-triangular matrix T by an orthogonal similarity* transformation.** T must be in Schur canonical form, that is, block upper triangular* with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block* has its diagonal elemnts equal and its off-diagonal elements of* opposite sign.** Arguments* =========** WANTQ (input) LOGICAL* = .TRUE. : accumulate the transformation in the matrix Q;* = .FALSE.: do not accumulate the transformation.** N (input) INTEGER* The order of the matrix T. N >= 0.** T (input/output) DOUBLE PRECISION array, dimension (LDT,N)* On entry, the upper quasi-triangular matrix T, in Schur* canonical form.* On exit, the updated matrix T, again in Schur canonical form.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= max(1,N).** Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N)* On entry, if WANTQ is .TRUE., the orthogonal matrix Q.* On exit, if WANTQ is .TRUE., the updated matrix Q.* If WANTQ is .FALSE., Q is not referenced.** LDQ (input) INTEGER* The leading dimension of the array Q.* LDQ >= 1; and if WANTQ is .TRUE., LDQ >= N.** J1 (input) INTEGER* The index of the first row of the first block T11.** N1 (input) INTEGER* The order of the first block T11. N1 = 0, 1 or 2.** N2 (input) INTEGER* The order of the second block T22. N2 = 0, 1 or 2.** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* = 1: the transformed matrix T would be too far from Schur* form; the blocks are not swapped and T and Q are* unchanged.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TENPARAMETER ( TEN = 1.0D+1 )INTEGER LDD, LDXPARAMETER ( LDD = 4, LDX = 2 )* ..* .. Local Scalars ..INTEGER IERR, J2, J3, J4, K, NDDOUBLE PRECISION CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,$ T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,$ WR1, WR2, XNORM* ..* .. Local Arrays ..DOUBLE PRECISION D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),$ X( LDX, 2 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLANGEEXTERNAL DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DLACPY, DLANV2, DLARFG, DLARFX, DLARTG, DLASY2,$ DROT* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.EQ.0 .OR. N1.EQ.0 .OR. N2.EQ.0 )$ RETURNIF( J1+N1.GT.N )$ RETURN*J2 = J1 + 1J3 = J1 + 2J4 = J1 + 3*IF( N1.EQ.1 .AND. N2.EQ.1 ) THEN** Swap two 1-by-1 blocks.*T11 = T( J1, J1 )T22 = T( J2, J2 )** Determine the transformation to perform the interchange.*CALL DLARTG( T( J1, J2 ), T22-T11, CS, SN, TEMP )** Apply transformation to the matrix T.*IF( J3.LE.N )$ CALL DROT( N-J1-1, T( J1, J3 ), LDT, T( J2, J3 ), LDT, CS,$ SN )CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )*T( J1, J1 ) = T22T( J2, J2 ) = T11*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )END IF*ELSE** Swapping involves at least one 2-by-2 block.** Copy the diagonal block of order N1+N2 to the local array D* and compute its norm.*ND = N1 + N2CALL DLACPY( 'Full', ND, ND, T( J1, J1 ), LDT, D, LDD )DNORM = DLANGE( 'Max', ND, ND, D, LDD, WORK )** Compute machine-dependent threshold for test for accepting* swap.*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSTHRESH = MAX( TEN*EPS*DNORM, SMLNUM )** Solve T11*X - X*T22 = scale*T12 for X.*CALL DLASY2( .FALSE., .FALSE., -1, N1, N2, D, LDD,$ D( N1+1, N1+1 ), LDD, D( 1, N1+1 ), LDD, SCALE, X,$ LDX, XNORM, IERR )** Swap the adjacent diagonal blocks.*K = N1 + N1 + N2 - 3GO TO ( 10, 20, 30 )K*10 CONTINUE** N1 = 1, N2 = 2: generate elementary reflector H so that:** ( scale, X11, X12 ) H = ( 0, 0, * )*U( 1 ) = SCALEU( 2 ) = X( 1, 1 )U( 3 ) = X( 1, 2 )CALL DLARFG( 3, U( 3 ), U, 1, TAU )U( 3 ) = ONET11 = T( J1, J1 )** Perform swap provisionally on diagonal block in D.*CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )** Test whether to reject swap.*IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 3,$ 3 )-T11 ) ).GT.THRESH )GO TO 50** Accept swap: apply transformation to the entire matrix T.*CALL DLARFX( 'L', 3, N-J1+1, U, TAU, T( J1, J1 ), LDT, WORK )CALL DLARFX( 'R', J2, 3, U, TAU, T( 1, J1 ), LDT, WORK )*T( J3, J1 ) = ZEROT( J3, J2 ) = ZEROT( J3, J3 ) = T11*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )END IFGO TO 40*20 CONTINUE** N1 = 2, N2 = 1: generate elementary reflector H so that:** H ( -X11 ) = ( * )* ( -X21 ) = ( 0 )* ( scale ) = ( 0 )*U( 1 ) = -X( 1, 1 )U( 2 ) = -X( 2, 1 )U( 3 ) = SCALECALL DLARFG( 3, U( 1 ), U( 2 ), 1, TAU )U( 1 ) = ONET33 = T( J3, J3 )** Perform swap provisionally on diagonal block in D.*CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )** Test whether to reject swap.*IF( MAX( ABS( D( 2, 1 ) ), ABS( D( 3, 1 ) ), ABS( D( 1,$ 1 )-T33 ) ).GT.THRESH )GO TO 50** Accept swap: apply transformation to the entire matrix T.*CALL DLARFX( 'R', J3, 3, U, TAU, T( 1, J1 ), LDT, WORK )CALL DLARFX( 'L', 3, N-J1, U, TAU, T( J1, J2 ), LDT, WORK )*T( J1, J1 ) = T33T( J2, J1 ) = ZEROT( J3, J1 ) = ZERO*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )END IFGO TO 40*30 CONTINUE** N1 = 2, N2 = 2: generate elementary reflectors H(1) and H(2) so* that:** H(2) H(1) ( -X11 -X12 ) = ( * * )* ( -X21 -X22 ) ( 0 * )* ( scale 0 ) ( 0 0 )* ( 0 scale ) ( 0 0 )*U1( 1 ) = -X( 1, 1 )U1( 2 ) = -X( 2, 1 )U1( 3 ) = SCALECALL DLARFG( 3, U1( 1 ), U1( 2 ), 1, TAU1 )U1( 1 ) = ONE*TEMP = -TAU1*( X( 1, 2 )+U1( 2 )*X( 2, 2 ) )U2( 1 ) = -TEMP*U1( 2 ) - X( 2, 2 )U2( 2 ) = -TEMP*U1( 3 )U2( 3 ) = SCALECALL DLARFG( 3, U2( 1 ), U2( 2 ), 1, TAU2 )U2( 1 ) = ONE** Perform swap provisionally on diagonal block in D.*CALL DLARFX( 'L', 3, 4, U1, TAU1, D, LDD, WORK )CALL DLARFX( 'R', 4, 3, U1, TAU1, D, LDD, WORK )CALL DLARFX( 'L', 3, 4, U2, TAU2, D( 2, 1 ), LDD, WORK )CALL DLARFX( 'R', 4, 3, U2, TAU2, D( 1, 2 ), LDD, WORK )** Test whether to reject swap.*IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 4, 1 ) ),$ ABS( D( 4, 2 ) ) ).GT.THRESH )GO TO 50** Accept swap: apply transformation to the entire matrix T.*CALL DLARFX( 'L', 3, N-J1+1, U1, TAU1, T( J1, J1 ), LDT, WORK )CALL DLARFX( 'R', J4, 3, U1, TAU1, T( 1, J1 ), LDT, WORK )CALL DLARFX( 'L', 3, N-J1+1, U2, TAU2, T( J2, J1 ), LDT, WORK )CALL DLARFX( 'R', J4, 3, U2, TAU2, T( 1, J2 ), LDT, WORK )*T( J3, J1 ) = ZEROT( J3, J2 ) = ZEROT( J4, J1 ) = ZEROT( J4, J2 ) = ZERO*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DLARFX( 'R', N, 3, U1, TAU1, Q( 1, J1 ), LDQ, WORK )CALL DLARFX( 'R', N, 3, U2, TAU2, Q( 1, J2 ), LDQ, WORK )END IF*40 CONTINUE*IF( N2.EQ.2 ) THEN** Standardize new 2-by-2 block T11*CALL DLANV2( T( J1, J1 ), T( J1, J2 ), T( J2, J1 ),$ T( J2, J2 ), WR1, WI1, WR2, WI2, CS, SN )CALL DROT( N-J1-1, T( J1, J1+2 ), LDT, T( J2, J1+2 ), LDT,$ CS, SN )CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )IF( WANTQ )$ CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )END IF*IF( N1.EQ.2 ) THEN** Standardize new 2-by-2 block T22*J3 = J1 + N2J4 = J3 + 1CALL DLANV2( T( J3, J3 ), T( J3, J4 ), T( J4, J3 ),$ T( J4, J4 ), WR1, WI1, WR2, WI2, CS, SN )IF( J3+2.LE.N )$ CALL DROT( N-J3-1, T( J3, J3+2 ), LDT, T( J4, J3+2 ),$ LDT, CS, SN )CALL DROT( J3-1, T( 1, J3 ), 1, T( 1, J4 ), 1, CS, SN )IF( WANTQ )$ CALL DROT( N, Q( 1, J3 ), 1, Q( 1, J4 ), 1, CS, SN )END IF*END IFRETURN** Exit with INFO = 1 if swap was rejected.*50 CONTINUEINFO = 1RETURN** End of DLAEXC*ENDSUBROUTINE DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,$ ILOZ, IHIZ, Z, LDZ, INFO )** -- LAPACK auxiliary 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 ..LOGICAL WANTT, WANTZINTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )* ..** Purpose* =======** DLAHQR is an auxiliary routine called by DHSEQR to update the* eigenvalues and Schur decomposition already computed by DHSEQR, by* dealing with the Hessenberg submatrix in rows and columns ILO to IHI.** Arguments* =========** WANTT (input) LOGICAL* = .TRUE. : the full Schur form T is required;* = .FALSE.: only eigenvalues are required.** WANTZ (input) LOGICAL* = .TRUE. : the matrix of Schur vectors Z is required;* = .FALSE.: Schur vectors are not required.** 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 quasi-triangular in* rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless* ILO = 1). DLAHQR works primarily with the Hessenberg* submatrix in rows and columns ILO to IHI, but applies* transformations to all of H if WANTT is .TRUE..* 1 <= ILO <= max(1,IHI); IHI <= N.** H (input/output) DOUBLE PRECISION array, dimension (LDH,N)* On entry, the upper Hessenberg matrix H.* On exit, if WANTT is .TRUE., H is upper quasi-triangular in* rows and columns ILO:IHI, with any 2-by-2 diagonal blocks in* standard form. If WANTT is .FALSE., 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 ILO to IHI are stored in the corresponding* elements of WR and WI. 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 WANTT is .TRUE., 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).** ILOZ (input) INTEGER* IHIZ (input) INTEGER* Specify the rows of Z to which transformations must be* applied if WANTZ is .TRUE..* 1 <= ILOZ <= ILO; IHI <= IHIZ <= N.** Z (input/output) DOUBLE PRECISION array, dimension (LDZ,N)* If WANTZ is .TRUE., on entry Z must contain the current* matrix Z of transformations accumulated by DHSEQR, and on* exit Z has been updated; transformations are applied only to* the submatrix Z(ILOZ:IHIZ,ILO:IHI).* If WANTZ is .FALSE., Z is not referenced.** LDZ (input) INTEGER* The leading dimension of the array Z. LDZ >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* > 0: DLAHQR failed to compute all the eigenvalues ILO to IHI* in a total of 30*(IHI-ILO+1) iterations; if INFO = i,* elements i+1:ihi of WR and WI contain those eigenvalues* which have been successfully computed.** Further Details* ===============** 2-96 Based on modifications by* David Day, Sandia National Laboratory, USA** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, HALFPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D0 )DOUBLE PRECISION DAT1, DAT2PARAMETER ( DAT1 = 0.75D+0, DAT2 = -0.4375D+0 )* ..* .. Local Scalars ..INTEGER I, I1, I2, ITN, ITS, J, K, L, M, NH, NR, NZDOUBLE PRECISION AVE, CS, DISC, H00, H10, H11, H12, H21, H22,$ H33, H33S, H43H34, H44, H44S, OVFL, S, SMLNUM,$ SN, SUM, T1, T2, T3, TST1, ULP, UNFL, V1, V2,$ V3* ..* .. Local Arrays ..DOUBLE PRECISION V( 3 ), WORK( 1 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLANHSEXTERNAL DLAMCH, DLANHS* ..* .. External Subroutines ..EXTERNAL DCOPY, DLANV2, DLARFG, DROT* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( ILO.EQ.IHI ) THENWR( ILO ) = H( ILO, ILO )WI( ILO ) = ZERORETURNEND IF*NH = IHI - ILO + 1NZ = IHIZ - ILOZ + 1** 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 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 1 or 2. 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 = IHI10 CONTINUEL = ILOIF( I.LT.ILO )$ GO TO 150** Perform QR iterations on rows and columns ILO to I until a* submatrix of order 1 or 2 splits off at the bottom because a* subdiagonal element has become negligible.*DO 130 ITS = 0, ITN** Look for a single small subdiagonal element.*DO 20 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 3020 CONTINUE30 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 1 or 2 has split off.*IF( L.GE.I-1 )$ GO TO 140** 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.10 .OR. ITS.EQ.20 ) THEN** Exceptional shift.*S = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )H44 = DAT1*S + H( I, I )H33 = H44H43H34 = DAT2*S*SELSE** Prepare to use Francis' double shift* (i.e. 2nd degree generalized Rayleigh quotient)*H44 = H( I, I )H33 = H( I-1, I-1 )H43H34 = H( I, I-1 )*H( I-1, I )S = H( I-1, I-2 )*H( I-1, I-2 )DISC = ( H33-H44 )*HALFDISC = DISC*DISC + H43H34IF( DISC.GT.ZERO ) THEN** Real roots: use Wilkinson's shift twice*DISC = SQRT( DISC )AVE = HALF*( H33+H44 )IF( ABS( H33 )-ABS( H44 ).GT.ZERO ) THENH33 = H33*H44 - H43H34H44 = H33 / ( SIGN( DISC, AVE )+AVE )ELSEH44 = SIGN( DISC, AVE ) + AVEEND IFH33 = H44H43H34 = ZEROEND IFEND IF** Look for two consecutive small subdiagonal elements.*DO 40 M = I - 2, L, -1* Determine the effect of starting the double-shift QR* iteration at row M, and see if this would make H(M,M-1)* negligible.*H11 = H( M, M )H22 = H( M+1, M+1 )H21 = H( M+1, M )H12 = H( M, M+1 )H44S = H44 - H11H33S = H33 - H11V1 = ( H33S*H44S-H43H34 ) / H21 + H12V2 = H22 - H11 - H33S - H44SV3 = H( M+2, M+1 )S = ABS( V1 ) + ABS( V2 ) + ABS( V3 )V1 = V1 / SV2 = V2 / SV3 = V3 / SV( 1 ) = V1V( 2 ) = V2V( 3 ) = V3IF( M.EQ.L )$ GO TO 50H00 = H( M-1, M-1 )H10 = H( M, M-1 )TST1 = ABS( V1 )*( ABS( H00 )+ABS( H11 )+ABS( H22 ) )IF( ABS( H10 )*( ABS( V2 )+ABS( V3 ) ).LE.ULP*TST1 )$ GO TO 5040 CONTINUE50 CONTINUE** Double-shift QR step*DO 120 K = M, 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( 3, I-K+1 )IF( K.GT.M )$ CALL DCOPY( NR, H( K, K-1 ), 1, V, 1 )CALL DLARFG( NR, V( 1 ), V( 2 ), 1, T1 )IF( K.GT.M ) THENH( K, K-1 ) = V( 1 )H( K+1, K-1 ) = ZEROIF( K.LT.I-1 )$ H( K+2, K-1 ) = ZEROELSE IF( M.GT.L ) THENH( K, K-1 ) = -H( K, K-1 )END IFV2 = V( 2 )T2 = T1*V2IF( NR.EQ.3 ) THENV3 = V( 3 )T3 = T1*V3** Apply G from the left to transform the rows of the matrix* in columns K to I2.*DO 60 J = K, I2SUM = H( K, J ) + V2*H( K+1, J ) + V3*H( K+2, J )H( K, J ) = H( K, J ) - SUM*T1H( K+1, J ) = H( K+1, J ) - SUM*T2H( K+2, J ) = H( K+2, J ) - SUM*T360 CONTINUE** Apply G from the right to transform the columns of the* matrix in rows I1 to min(K+3,I).*DO 70 J = I1, MIN( K+3, I )SUM = H( J, K ) + V2*H( J, K+1 ) + V3*H( J, K+2 )H( J, K ) = H( J, K ) - SUM*T1H( J, K+1 ) = H( J, K+1 ) - SUM*T2H( J, K+2 ) = H( J, K+2 ) - SUM*T370 CONTINUE*IF( WANTZ ) THEN** Accumulate transformations in the matrix Z*DO 80 J = ILOZ, IHIZSUM = Z( J, K ) + V2*Z( J, K+1 ) + V3*Z( J, K+2 )Z( J, K ) = Z( J, K ) - SUM*T1Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2Z( J, K+2 ) = Z( J, K+2 ) - SUM*T380 CONTINUEEND IFELSE IF( NR.EQ.2 ) THEN** Apply G from the left to transform the rows of the matrix* in columns K to I2.*DO 90 J = K, I2SUM = H( K, J ) + V2*H( K+1, J )H( K, J ) = H( K, J ) - SUM*T1H( K+1, J ) = H( K+1, J ) - SUM*T290 CONTINUE** Apply G from the right to transform the columns of the* matrix in rows I1 to min(K+3,I).*DO 100 J = I1, ISUM = H( J, K ) + V2*H( J, K+1 )H( J, K ) = H( J, K ) - SUM*T1H( J, K+1 ) = H( J, K+1 ) - SUM*T2100 CONTINUE*IF( WANTZ ) THEN** Accumulate transformations in the matrix Z*DO 110 J = ILOZ, IHIZSUM = Z( J, K ) + V2*Z( J, K+1 )Z( J, K ) = Z( J, K ) - SUM*T1Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2110 CONTINUEEND IFEND IF120 CONTINUE*130 CONTINUE** Failure to converge in remaining number of iterations*INFO = IRETURN*140 CONTINUE*IF( L.EQ.I ) THEN** H(I,I-1) is negligible: one eigenvalue has converged.*WR( I ) = H( I, I )WI( I ) = ZEROELSE IF( L.EQ.I-1 ) THEN** H(I-1,I-2) is negligible: a pair of eigenvalues have converged.** Transform the 2-by-2 submatrix to standard Schur form,* and compute and store the eigenvalues.*CALL DLANV2( H( I-1, I-1 ), H( I-1, I ), H( I, I-1 ),$ H( I, I ), WR( I-1 ), WI( I-1 ), WR( I ), WI( I ),$ CS, SN )*IF( WANTT ) THEN** Apply the transformation to the rest of H.*IF( I2.GT.I )$ CALL DROT( I2-I, H( I-1, I+1 ), LDH, H( I, I+1 ), LDH,$ CS, SN )CALL DROT( I-I1-1, H( I1, I-1 ), 1, H( I1, I ), 1, CS, SN )END IFIF( WANTZ ) THEN** Apply the transformation to Z.*CALL DROT( NZ, Z( ILOZ, I-1 ), 1, Z( ILOZ, I ), 1, CS, SN )END IFEND IF** Decrement number of remaining iterations, and return to start of* the main loop with new value of I.*ITN = ITN - ITSI = L - 1GO TO 10*150 CONTINUERETURN** End of DLAHQR*ENDSUBROUTINE DLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )** -- LAPACK auxiliary 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 K, LDA, LDT, LDY, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ),$ Y( LDY, NB )* ..** Purpose* =======** DLAHRD reduces the first NB columns of a real general n-by-(n-k+1)* matrix A so that elements below the k-th subdiagonal are zero. The* reduction is performed by an orthogonal similarity transformation* Q' * A * Q. The routine returns the matrices V and T which determine* Q as a block reflector I - V*T*V', and also the matrix Y = A * V * T.** This is an auxiliary routine called by DGEHRD.** Arguments* =========** N (input) INTEGER* The order of the matrix A.** K (input) INTEGER* The offset for the reduction. Elements below the k-th* subdiagonal in the first NB columns are reduced to zero.** NB (input) INTEGER* The number of columns to be reduced.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N-K+1)* On entry, the n-by-(n-k+1) general matrix A.* On exit, the elements on and above the k-th subdiagonal in* the first NB columns are overwritten with the corresponding* elements of the reduced matrix; the elements below the k-th* subdiagonal, with the array TAU, represent the matrix Q as a* product of elementary reflectors. The other columns of A are* unchanged. See Further Details.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** TAU (output) DOUBLE PRECISION array, dimension (NB)* The scalar factors of the elementary reflectors. See Further* Details.** T (output) DOUBLE PRECISION array, dimension (LDT,NB)* The upper triangular matrix T.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= NB.** Y (output) DOUBLE PRECISION array, dimension (LDY,NB)* The n-by-nb matrix Y.** LDY (input) INTEGER* The leading dimension of the array Y. LDY >= N.** Further Details* ===============** The matrix Q is represented as a product of nb elementary reflectors** Q = H(1) H(2) . . . H(nb).** 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+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in* A(i+k+1:n,i), and tau in TAU(i).** The elements of the vectors v together form the (n-k+1)-by-nb matrix* V which is needed, with T and Y, to apply the transformation to the* unreduced part of the matrix, using an update of the form:* A := (I - V*T*V') * (A - Y*V').** The contents of A on exit are illustrated by the following example* with n = 7, k = 3 and nb = 2:** ( a h a a a )* ( a h a a a )* ( a h a a a )* ( h h a a a )* ( v1 h a a a )* ( v1 v2 a a a )* ( v1 v2 a 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 ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION EI* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DLARFG, DSCAL, DTRMV* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.1 )$ RETURN*DO 10 I = 1, NBIF( I.GT.1 ) THEN** Update A(1:n,i)** Compute i-th column of A - Y * V'*CALL DGEMV( 'No transpose', N, I-1, -ONE, Y, LDY,$ A( K+I-1, 1 ), LDA, ONE, A( 1, I ), 1 )** Apply I - V * T' * V' to this column (call it b) from the* left, using the last column of T as workspace** Let V = ( V1 ) and b = ( b1 ) (first I-1 rows)* ( V2 ) ( b2 )** where V1 is unit lower triangular** w := V1' * b1*CALL DCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )CALL DTRMV( 'Lower', 'Transpose', 'Unit', I-1, A( K+1, 1 ),$ LDA, T( 1, NB ), 1 )** w := w + V2'*b2*CALL DGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ),$ LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )** w := T'*w*CALL DTRMV( 'Upper', 'Transpose', 'Non-unit', I-1, T, LDT,$ T( 1, NB ), 1 )** b2 := b2 - V2*w*CALL DGEMV( 'No transpose', N-K-I+1, I-1, -ONE, A( K+I, 1 ),$ LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )** b1 := b1 - V1*w*CALL DTRMV( 'Lower', 'No transpose', 'Unit', I-1,$ A( K+1, 1 ), LDA, T( 1, NB ), 1 )CALL DAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )*A( K+I-1, I-1 ) = EIEND IF** Generate the elementary reflector H(i) to annihilate* A(k+i+1:n,i)*CALL DLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,$ TAU( I ) )EI = A( K+I, I )A( K+I, I ) = ONE** Compute Y(1:n,i)*CALL DGEMV( 'No transpose', N, N-K-I+1, ONE, A( 1, I+1 ), LDA,$ A( K+I, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ), LDA,$ A( K+I, I ), 1, ZERO, T( 1, I ), 1 )CALL DGEMV( 'No transpose', N, I-1, -ONE, Y, LDY, T( 1, I ), 1,$ ONE, Y( 1, I ), 1 )CALL DSCAL( N, TAU( I ), Y( 1, I ), 1 )** Compute T(1:i,i)*CALL DSCAL( I-1, -TAU( I ), T( 1, I ), 1 )CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, LDT,$ T( 1, I ), 1 )T( I, I ) = TAU( I )*10 CONTINUEA( K+NB, NB ) = EI*RETURN** End of DLAHRD*ENDSUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,$ LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )** -- LAPACK auxiliary 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 ..LOGICAL LTRANSINTEGER INFO, LDA, LDB, LDX, NA, NWDOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * )* ..** Purpose* =======** DLALN2 solves a system of the form (ca A - w D ) X = s B* or (ca A' - w D) X = s B with possible scaling ("s") and* perturbation of A. (A' means A-transpose.)** A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA* real diagonal matrix, w is a real or complex value, and X and B are* NA x 1 matrices -- real if w is real, complex if w is complex. NA* may be 1 or 2.** If w is complex, X and B are represented as NA x 2 matrices,* the first column of each being the real part and the second* being the imaginary part.** "s" is a scaling factor (.LE. 1), computed by DLALN2, which is* so chosen that X can be computed without overflow. X is further* scaled if necessary to assure that norm(ca A - w D)*norm(X) is less* than overflow.** If both singular values of (ca A - w D) are less than SMIN,* SMIN*identity will be used instead of (ca A - w D). If only one* singular value is less than SMIN, one element of (ca A - w D) will be* perturbed enough to make the smallest singular value roughly SMIN.* If both singular values are at least SMIN, (ca A - w D) will not be* perturbed. In any case, the perturbation will be at most some small* multiple of max( SMIN, ulp*norm(ca A - w D) ). The singular values* are computed by infinity-norm approximations, and thus will only be* correct to a factor of 2 or so.** Note: all input quantities are assumed to be smaller than overflow* by a reasonable factor. (See BIGNUM.)** Arguments* ==========** LTRANS (input) LOGICAL* =.TRUE.: A-transpose will be used.* =.FALSE.: A will be used (not transposed.)** NA (input) INTEGER* The size of the matrix A. It may (only) be 1 or 2.** NW (input) INTEGER* 1 if "w" is real, 2 if "w" is complex. It may only be 1* or 2.** SMIN (input) DOUBLE PRECISION* The desired lower bound on the singular values of A. This* should be a safe distance away from underflow or overflow,* say, between (underflow/machine precision) and (machine* precision * overflow ). (See BIGNUM and ULP.)** CA (input) DOUBLE PRECISION* The coefficient c, which A is multiplied by.** A (input) DOUBLE PRECISION array, dimension (LDA,NA)* The NA x NA matrix A.** LDA (input) INTEGER* The leading dimension of A. It must be at least NA.** D1 (input) DOUBLE PRECISION* The 1,1 element in the diagonal matrix D.** D2 (input) DOUBLE PRECISION* The 2,2 element in the diagonal matrix D. Not used if NW=1.** B (input) DOUBLE PRECISION array, dimension (LDB,NW)* The NA x NW matrix B (right-hand side). If NW=2 ("w" is* complex), column 1 contains the real part of B and column 2* contains the imaginary part.** LDB (input) INTEGER* The leading dimension of B. It must be at least NA.** WR (input) DOUBLE PRECISION* The real part of the scalar "w".** WI (input) DOUBLE PRECISION* The imaginary part of the scalar "w". Not used if NW=1.** X (output) DOUBLE PRECISION array, dimension (LDX,NW)* The NA x NW matrix X (unknowns), as computed by DLALN2.* If NW=2 ("w" is complex), on exit, column 1 will contain* the real part of X and column 2 will contain the imaginary* part.** LDX (input) INTEGER* The leading dimension of X. It must be at least NA.** SCALE (output) DOUBLE PRECISION* The scale factor that B must be multiplied by to insure* that overflow does not occur when computing X. Thus,* (ca A - w D) X will be SCALE*B, not B (ignoring* perturbations of A.) It will be at most 1.** XNORM (output) DOUBLE PRECISION* The infinity-norm of X, when X is regarded as an NA x NW* real matrix.** INFO (output) INTEGER* An error flag. It will be set to zero if no error occurs,* a negative number if an argument is in error, or a positive* number if ca A - w D had to be perturbed.* The possible values are:* = 0: No error occurred, and (ca A - w D) did not have to be* perturbed.* = 1: (ca A - w D) had to be perturbed to make its smallest* (or only) singular value greater than SMIN.* NOTE: In the interests of speed, this routine does not* check the inputs for errors.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..INTEGER ICMAX, JDOUBLE PRECISION BBND, BI1, BI2, BIGNUM, BNORM, BR1, BR2, CI21,$ CI22, CMAX, CNORM, CR21, CR22, CSI, CSR, LI21,$ LR21, SMINI, SMLNUM, TEMP, U22ABS, UI11, UI11R,$ UI12, UI12S, UI22, UR11, UR11R, UR12, UR12S,$ UR22, XI1, XI2, XR1, XR2* ..* .. Local Arrays ..LOGICAL RSWAP( 4 ), ZSWAP( 4 )INTEGER IPIVOT( 4, 4 )DOUBLE PRECISION CI( 2, 2 ), CIV( 4 ), CR( 2, 2 ), CRV( 4 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DLADIV* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Equivalences ..EQUIVALENCE ( CI( 1, 1 ), CIV( 1 ) ),$ ( CR( 1, 1 ), CRV( 1 ) )* ..* .. Data statements ..DATA ZSWAP / .FALSE., .FALSE., .TRUE., .TRUE. /DATA RSWAP / .FALSE., .TRUE., .FALSE., .TRUE. /DATA IPIVOT / 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4,$ 3, 2, 1 /* ..* .. Executable Statements ..** Compute BIGNUM*SMLNUM = TWO*DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMSMINI = MAX( SMIN, SMLNUM )** Don't check for input errors*INFO = 0** Standard Initializations*SCALE = ONE*IF( NA.EQ.1 ) THEN** 1 x 1 (i.e., scalar) system C X = B*IF( NW.EQ.1 ) THEN** Real 1x1 system.** C = ca A - w D*CSR = CA*A( 1, 1 ) - WR*D1CNORM = ABS( CSR )** If | C | < SMINI, use C = SMINI*IF( CNORM.LT.SMINI ) THENCSR = SMINICNORM = SMINIINFO = 1END IF** Check scaling for X = B / C*BNORM = ABS( B( 1, 1 ) )IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*CNORM )$ SCALE = ONE / BNORMEND IF** Compute X*X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / CSRXNORM = ABS( X( 1, 1 ) )ELSE** Complex 1x1 system (w is complex)** C = ca A - w D*CSR = CA*A( 1, 1 ) - WR*D1CSI = -WI*D1CNORM = ABS( CSR ) + ABS( CSI )** If | C | < SMINI, use C = SMINI*IF( CNORM.LT.SMINI ) THENCSR = SMINICSI = ZEROCNORM = SMINIINFO = 1END IF** Check scaling for X = B / C*BNORM = ABS( B( 1, 1 ) ) + ABS( B( 1, 2 ) )IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*CNORM )$ SCALE = ONE / BNORMEND IF** Compute X*CALL DLADIV( SCALE*B( 1, 1 ), SCALE*B( 1, 2 ), CSR, CSI,$ X( 1, 1 ), X( 1, 2 ) )XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )END IF*ELSE** 2x2 System** Compute the real part of C = ca A - w D (or ca A' - w D )*CR( 1, 1 ) = CA*A( 1, 1 ) - WR*D1CR( 2, 2 ) = CA*A( 2, 2 ) - WR*D2IF( LTRANS ) THENCR( 1, 2 ) = CA*A( 2, 1 )CR( 2, 1 ) = CA*A( 1, 2 )ELSECR( 2, 1 ) = CA*A( 2, 1 )CR( 1, 2 ) = CA*A( 1, 2 )END IF*IF( NW.EQ.1 ) THEN** Real 2x2 system (w is real)** Find the largest element in C*CMAX = ZEROICMAX = 0*DO 10 J = 1, 4IF( ABS( CRV( J ) ).GT.CMAX ) THENCMAX = ABS( CRV( J ) )ICMAX = JEND IF10 CONTINUE** If norm(C) < SMINI, use SMINI*identity.*IF( CMAX.LT.SMINI ) THENBNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 2, 1 ) ) )IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*SMINI )$ SCALE = ONE / BNORMEND IFTEMP = SCALE / SMINIX( 1, 1 ) = TEMP*B( 1, 1 )X( 2, 1 ) = TEMP*B( 2, 1 )XNORM = TEMP*BNORMINFO = 1RETURNEND IF** Gaussian elimination with complete pivoting.*UR11 = CRV( ICMAX )CR21 = CRV( IPIVOT( 2, ICMAX ) )UR12 = CRV( IPIVOT( 3, ICMAX ) )CR22 = CRV( IPIVOT( 4, ICMAX ) )UR11R = ONE / UR11LR21 = UR11R*CR21UR22 = CR22 - UR12*LR21** If smaller pivot < SMINI, use SMINI*IF( ABS( UR22 ).LT.SMINI ) THENUR22 = SMINIINFO = 1END IFIF( RSWAP( ICMAX ) ) THENBR1 = B( 2, 1 )BR2 = B( 1, 1 )ELSEBR1 = B( 1, 1 )BR2 = B( 2, 1 )END IFBR2 = BR2 - LR21*BR1BBND = MAX( ABS( BR1*( UR22*UR11R ) ), ABS( BR2 ) )IF( BBND.GT.ONE .AND. ABS( UR22 ).LT.ONE ) THENIF( BBND.GE.BIGNUM*ABS( UR22 ) )$ SCALE = ONE / BBNDEND IF*XR2 = ( BR2*SCALE ) / UR22XR1 = ( SCALE*BR1 )*UR11R - XR2*( UR11R*UR12 )IF( ZSWAP( ICMAX ) ) THENX( 1, 1 ) = XR2X( 2, 1 ) = XR1ELSEX( 1, 1 ) = XR1X( 2, 1 ) = XR2END IFXNORM = MAX( ABS( XR1 ), ABS( XR2 ) )** Further scaling if norm(A) norm(X) > overflow*IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THENIF( XNORM.GT.BIGNUM / CMAX ) THENTEMP = CMAX / BIGNUMX( 1, 1 ) = TEMP*X( 1, 1 )X( 2, 1 ) = TEMP*X( 2, 1 )XNORM = TEMP*XNORMSCALE = TEMP*SCALEEND IFEND IFELSE** Complex 2x2 system (w is complex)** Find the largest element in C*CI( 1, 1 ) = -WI*D1CI( 2, 1 ) = ZEROCI( 1, 2 ) = ZEROCI( 2, 2 ) = -WI*D2CMAX = ZEROICMAX = 0*DO 20 J = 1, 4IF( ABS( CRV( J ) )+ABS( CIV( J ) ).GT.CMAX ) THENCMAX = ABS( CRV( J ) ) + ABS( CIV( J ) )ICMAX = JEND IF20 CONTINUE** If norm(C) < SMINI, use SMINI*identity.*IF( CMAX.LT.SMINI ) THENBNORM = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),$ ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*SMINI )$ SCALE = ONE / BNORMEND IFTEMP = SCALE / SMINIX( 1, 1 ) = TEMP*B( 1, 1 )X( 2, 1 ) = TEMP*B( 2, 1 )X( 1, 2 ) = TEMP*B( 1, 2 )X( 2, 2 ) = TEMP*B( 2, 2 )XNORM = TEMP*BNORMINFO = 1RETURNEND IF** Gaussian elimination with complete pivoting.*UR11 = CRV( ICMAX )UI11 = CIV( ICMAX )CR21 = CRV( IPIVOT( 2, ICMAX ) )CI21 = CIV( IPIVOT( 2, ICMAX ) )UR12 = CRV( IPIVOT( 3, ICMAX ) )UI12 = CIV( IPIVOT( 3, ICMAX ) )CR22 = CRV( IPIVOT( 4, ICMAX ) )CI22 = CIV( IPIVOT( 4, ICMAX ) )IF( ICMAX.EQ.1 .OR. ICMAX.EQ.4 ) THEN** Code when off-diagonals of pivoted C are real*IF( ABS( UR11 ).GT.ABS( UI11 ) ) THENTEMP = UI11 / UR11UR11R = ONE / ( UR11*( ONE+TEMP**2 ) )UI11R = -TEMP*UR11RELSETEMP = UR11 / UI11UI11R = -ONE / ( UI11*( ONE+TEMP**2 ) )UR11R = -TEMP*UI11REND IFLR21 = CR21*UR11RLI21 = CR21*UI11RUR12S = UR12*UR11RUI12S = UR12*UI11RUR22 = CR22 - UR12*LR21UI22 = CI22 - UR12*LI21ELSE** Code when diagonals of pivoted C are real*UR11R = ONE / UR11UI11R = ZEROLR21 = CR21*UR11RLI21 = CI21*UR11RUR12S = UR12*UR11RUI12S = UI12*UR11RUR22 = CR22 - UR12*LR21 + UI12*LI21UI22 = -UR12*LI21 - UI12*LR21END IFU22ABS = ABS( UR22 ) + ABS( UI22 )** If smaller pivot < SMINI, use SMINI*IF( U22ABS.LT.SMINI ) THENUR22 = SMINIUI22 = ZEROINFO = 1END IFIF( RSWAP( ICMAX ) ) THENBR2 = B( 1, 1 )BR1 = B( 2, 1 )BI2 = B( 1, 2 )BI1 = B( 2, 2 )ELSEBR1 = B( 1, 1 )BR2 = B( 2, 1 )BI1 = B( 1, 2 )BI2 = B( 2, 2 )END IFBR2 = BR2 - LR21*BR1 + LI21*BI1BI2 = BI2 - LI21*BR1 - LR21*BI1BBND = MAX( ( ABS( BR1 )+ABS( BI1 ) )*$ ( U22ABS*( ABS( UR11R )+ABS( UI11R ) ) ),$ ABS( BR2 )+ABS( BI2 ) )IF( BBND.GT.ONE .AND. U22ABS.LT.ONE ) THENIF( BBND.GE.BIGNUM*U22ABS ) THENSCALE = ONE / BBNDBR1 = SCALE*BR1BI1 = SCALE*BI1BR2 = SCALE*BR2BI2 = SCALE*BI2END IFEND IF*CALL DLADIV( BR2, BI2, UR22, UI22, XR2, XI2 )XR1 = UR11R*BR1 - UI11R*BI1 - UR12S*XR2 + UI12S*XI2XI1 = UI11R*BR1 + UR11R*BI1 - UI12S*XR2 - UR12S*XI2IF( ZSWAP( ICMAX ) ) THENX( 1, 1 ) = XR2X( 2, 1 ) = XR1X( 1, 2 ) = XI2X( 2, 2 ) = XI1ELSEX( 1, 1 ) = XR1X( 2, 1 ) = XR2X( 1, 2 ) = XI1X( 2, 2 ) = XI2END IFXNORM = MAX( ABS( XR1 )+ABS( XI1 ), ABS( XR2 )+ABS( XI2 ) )** Further scaling if norm(A) norm(X) > overflow*IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THENIF( XNORM.GT.BIGNUM / CMAX ) THENTEMP = CMAX / BIGNUMX( 1, 1 ) = TEMP*X( 1, 1 )X( 2, 1 ) = TEMP*X( 2, 1 )X( 1, 2 ) = TEMP*X( 1, 2 )X( 2, 2 ) = TEMP*X( 2, 2 )XNORM = TEMP*XNORMSCALE = TEMP*SCALEEND IFEND IFEND IFEND IF*RETURN** End of DLALN2*ENDDOUBLE PRECISION FUNCTION DLAMCH( CMACH )** -- LAPACK auxiliary 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 ..CHARACTER CMACH* ..** Purpose* =======** DLAMCH determines double precision machine parameters.** Arguments* =========** CMACH (input) CHARACTER*1* Specifies the value to be returned by DLAMCH:* = 'E' or 'e', DLAMCH := eps* = 'S' or 's , DLAMCH := sfmin* = 'B' or 'b', DLAMCH := base* = 'P' or 'p', DLAMCH := eps*base* = 'N' or 'n', DLAMCH := t* = 'R' or 'r', DLAMCH := rnd* = 'M' or 'm', DLAMCH := emin* = 'U' or 'u', DLAMCH := rmin* = 'L' or 'l', DLAMCH := emax* = 'O' or 'o', DLAMCH := rmax** where** eps = relative machine precision* sfmin = safe minimum, such that 1/sfmin does not overflow* base = base of the machine* prec = eps*base* t = number of (base) digits in the mantissa* rnd = 1.0 when rounding occurs in addition, 0.0 otherwise* emin = minimum exponent before (gradual) underflow* rmin = underflow threshold - base**(emin-1)* emax = largest exponent before overflow* rmax = overflow threshold - (base**emax)*(1-eps)** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL FIRST, LRNDINTEGER BETA, IMAX, IMIN, ITDOUBLE PRECISION BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN,$ RND, SFMIN, SMALL, T* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLAMC2* ..* .. Save statement ..SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN,$ EMAX, RMAX, PREC* ..* .. Data statements ..DATA FIRST / .TRUE. /* ..* .. Executable Statements ..*IF( FIRST ) THENFIRST = .FALSE.CALL DLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX )BASE = BETAT = ITIF( LRND ) THENRND = ONEEPS = ( BASE**( 1-IT ) ) / 2ELSERND = ZEROEPS = BASE**( 1-IT )END IFPREC = EPS*BASEEMIN = IMINEMAX = IMAXSFMIN = RMINSMALL = ONE / RMAXIF( SMALL.GE.SFMIN ) THEN** Use SMALL plus a bit, to avoid the possibility of rounding* causing overflow when computing 1/sfmin.*SFMIN = SMALL*( ONE+EPS )END IFEND IF*IF( LSAME( CMACH, 'E' ) ) THENRMACH = EPSELSE IF( LSAME( CMACH, 'S' ) ) THENRMACH = SFMINELSE IF( LSAME( CMACH, 'B' ) ) THENRMACH = BASEELSE IF( LSAME( CMACH, 'P' ) ) THENRMACH = PRECELSE IF( LSAME( CMACH, 'N' ) ) THENRMACH = TELSE IF( LSAME( CMACH, 'R' ) ) THENRMACH = RNDELSE IF( LSAME( CMACH, 'M' ) ) THENRMACH = EMINELSE IF( LSAME( CMACH, 'U' ) ) THENRMACH = RMINELSE IF( LSAME( CMACH, 'L' ) ) THENRMACH = EMAXELSE IF( LSAME( CMACH, 'O' ) ) THENRMACH = RMAXEND IF*DLAMCH = RMACHRETURN** End of DLAMCH*END**************************************************************************SUBROUTINE DLAMC1( BETA, T, RND, IEEE1 )** -- LAPACK auxiliary 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 ..LOGICAL IEEE1, RNDINTEGER BETA, T* ..** Purpose* =======** DLAMC1 determines the machine parameters given by BETA, T, RND, and* IEEE1.** Arguments* =========** BETA (output) INTEGER* The base of the machine.** T (output) INTEGER* The number of ( BETA ) digits in the mantissa.** RND (output) LOGICAL* Specifies whether proper rounding ( RND = .TRUE. ) or* chopping ( RND = .FALSE. ) occurs in addition. This may not* be a reliable guide to the way in which the machine performs* its arithmetic.** IEEE1 (output) LOGICAL* Specifies whether rounding appears to be done in the IEEE* 'round to nearest' style.** Further Details* ===============** The routine is based on the routine ENVRON by Malcolm and* incorporates suggestions by Gentleman and Marovich. See** Malcolm M. A. (1972) Algorithms to reveal properties of* floating-point arithmetic. Comms. of the ACM, 15, 949-951.** Gentleman W. M. and Marovich S. B. (1974) More on algorithms* that reveal properties of floating point arithmetic units.* Comms. of the ACM, 17, 276-277.** =====================================================================** .. Local Scalars ..LOGICAL FIRST, LIEEE1, LRNDINTEGER LBETA, LTDOUBLE PRECISION A, B, C, F, ONE, QTR, SAVEC, T1, T2* ..* .. External Functions ..DOUBLE PRECISION DLAMC3EXTERNAL DLAMC3* ..* .. Save statement ..SAVE FIRST, LIEEE1, LBETA, LRND, LT* ..* .. Data statements ..DATA FIRST / .TRUE. /* ..* .. Executable Statements ..*IF( FIRST ) THENFIRST = .FALSE.ONE = 1** LBETA, LIEEE1, LT and LRND are the local values of BETA,* IEEE1, T and RND.** Throughout this routine we use the function DLAMC3 to ensure* that relevant values are stored and not held in registers, or* are not affected by optimizers.** Compute a = 2.0**m with the smallest positive integer m such* that** fl( a + 1.0 ) = a.*A = 1C = 1**+ WHILE( C.EQ.ONE )LOOP10 CONTINUEIF( C.EQ.ONE ) THENA = 2*AC = DLAMC3( A, ONE )C = DLAMC3( C, -A )GO TO 10END IF*+ END WHILE** Now compute b = 2.0**m with the smallest positive integer m* such that** fl( a + b ) .gt. a.*B = 1C = DLAMC3( A, B )**+ WHILE( C.EQ.A )LOOP20 CONTINUEIF( C.EQ.A ) THENB = 2*BC = DLAMC3( A, B )GO TO 20END IF*+ END WHILE** Now compute the base. a and c are neighbouring floating point* numbers in the interval ( beta**t, beta**( t + 1 ) ) and so* their difference is beta. Adding 0.25 to c is to ensure that it* is truncated to beta and not ( beta - 1 ).*QTR = ONE / 4SAVEC = CC = DLAMC3( C, -A )LBETA = C + QTR** Now determine whether rounding or chopping occurs, by adding a* bit less than beta/2 and a bit more than beta/2 to a.*B = LBETAF = DLAMC3( B / 2, -B / 100 )C = DLAMC3( F, A )IF( C.EQ.A ) THENLRND = .TRUE.ELSELRND = .FALSE.END IFF = DLAMC3( B / 2, B / 100 )C = DLAMC3( F, A )IF( ( LRND ) .AND. ( C.EQ.A ) )$ LRND = .FALSE.** Try and decide whether rounding is done in the IEEE 'round to* nearest' style. B/2 is half a unit in the last place of the two* numbers A and SAVEC. Furthermore, A is even, i.e. has last bit* zero, and SAVEC is odd. Thus adding B/2 to A should not change* A, but adding B/2 to SAVEC should change SAVEC.*T1 = DLAMC3( B / 2, A )T2 = DLAMC3( B / 2, SAVEC )LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND** Now find the mantissa, t. It should be the integer part of* log to the base beta of a, however it is safer to determine t* by powering. So we find t as the smallest positive integer for* which** fl( beta**t + 1.0 ) = 1.0.*LT = 0A = 1C = 1**+ WHILE( C.EQ.ONE )LOOP30 CONTINUEIF( C.EQ.ONE ) THENLT = LT + 1A = A*LBETAC = DLAMC3( A, ONE )C = DLAMC3( C, -A )GO TO 30END IF*+ END WHILE*END IF*BETA = LBETAT = LTRND = LRNDIEEE1 = LIEEE1RETURN** End of DLAMC1*END**************************************************************************SUBROUTINE DLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )** -- LAPACK auxiliary 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 ..LOGICAL RNDINTEGER BETA, EMAX, EMIN, TDOUBLE PRECISION EPS, RMAX, RMIN* ..** Purpose* =======** DLAMC2 determines the machine parameters specified in its argument* list.** Arguments* =========** BETA (output) INTEGER* The base of the machine.** T (output) INTEGER* The number of ( BETA ) digits in the mantissa.** RND (output) LOGICAL* Specifies whether proper rounding ( RND = .TRUE. ) or* chopping ( RND = .FALSE. ) occurs in addition. This may not* be a reliable guide to the way in which the machine performs* its arithmetic.** EPS (output) DOUBLE PRECISION* The smallest positive number such that** fl( 1.0 - EPS ) .LT. 1.0,** where fl denotes the computed value.** EMIN (output) INTEGER* The minimum exponent before (gradual) underflow occurs.** RMIN (output) DOUBLE PRECISION* The smallest normalized number for the machine, given by* BASE**( EMIN - 1 ), where BASE is the floating point value* of BETA.** EMAX (output) INTEGER* The maximum exponent before overflow occurs.** RMAX (output) DOUBLE PRECISION* The largest positive number for the machine, given by* BASE**EMAX * ( 1 - EPS ), where BASE is the floating point* value of BETA.** Further Details* ===============** The computation of EPS is based on a routine PARANOIA by* W. Kahan of the University of California at Berkeley.** =====================================================================** .. Local Scalars ..LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRNDINTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,$ NGNMIN, NGPMINDOUBLE PRECISION A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,$ SIXTH, SMALL, THIRD, TWO, ZERO* ..* .. External Functions ..DOUBLE PRECISION DLAMC3EXTERNAL DLAMC3* ..* .. External Subroutines ..EXTERNAL DLAMC1, DLAMC4, DLAMC5* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Save statement ..SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,$ LRMIN, LT* ..* .. Data statements ..DATA FIRST / .TRUE. / , IWARN / .FALSE. /* ..* .. Executable Statements ..*IF( FIRST ) THENFIRST = .FALSE.ZERO = 0ONE = 1TWO = 2** LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of* BETA, T, RND, EPS, EMIN and RMIN.** Throughout this routine we use the function DLAMC3 to ensure* that relevant values are stored and not held in registers, or* are not affected by optimizers.** DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1.*CALL DLAMC1( LBETA, LT, LRND, LIEEE1 )** Start to find EPS.*B = LBETAA = B**( -LT )LEPS = A** Try some tricks to see whether or not this is the correct EPS.*B = TWO / 3HALF = ONE / 2SIXTH = DLAMC3( B, -HALF )THIRD = DLAMC3( SIXTH, SIXTH )B = DLAMC3( THIRD, -HALF )B = DLAMC3( B, SIXTH )B = ABS( B )IF( B.LT.LEPS )$ B = LEPS*LEPS = 1**+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP10 CONTINUEIF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THENLEPS = BC = DLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )C = DLAMC3( HALF, -C )B = DLAMC3( HALF, C )C = DLAMC3( HALF, -B )B = DLAMC3( HALF, C )GO TO 10END IF*+ END WHILE*IF( A.LT.LEPS )$ LEPS = A** Computation of EPS complete.** Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)).* Keep dividing A by BETA until (gradual) underflow occurs. This* is detected when we cannot recover the previous A.*RBASE = ONE / LBETASMALL = ONEDO 20 I = 1, 3SMALL = DLAMC3( SMALL*RBASE, ZERO )20 CONTINUEA = DLAMC3( ONE, SMALL )CALL DLAMC4( NGPMIN, ONE, LBETA )CALL DLAMC4( NGNMIN, -ONE, LBETA )CALL DLAMC4( GPMIN, A, LBETA )CALL DLAMC4( GNMIN, -A, LBETA )IEEE = .FALSE.*IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THENIF( NGPMIN.EQ.GPMIN ) THENLEMIN = NGPMIN* ( Non twos-complement machines, no gradual underflow;* e.g., VAX )ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THENLEMIN = NGPMIN - 1 + LTIEEE = .TRUE.* ( Non twos-complement machines, with gradual underflow;* e.g., IEEE standard followers )ELSELEMIN = MIN( NGPMIN, GPMIN )* ( A guess; no known machine )IWARN = .TRUE.END IF*ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THENIF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THENLEMIN = MAX( NGPMIN, NGNMIN )* ( Twos-complement machines, no gradual underflow;* e.g., CYBER 205 )ELSELEMIN = MIN( NGPMIN, NGNMIN )* ( A guess; no known machine )IWARN = .TRUE.END IF*ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.$ ( GPMIN.EQ.GNMIN ) ) THENIF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THENLEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT* ( Twos-complement machines with gradual underflow;* no known machine )ELSELEMIN = MIN( NGPMIN, NGNMIN )* ( A guess; no known machine )IWARN = .TRUE.END IF*ELSELEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )* ( A guess; no known machine )IWARN = .TRUE.END IF**** Comment out this if block if EMIN is okIF( IWARN ) THENFIRST = .TRUE.WRITE( 6, FMT = 9999 )LEMINEND IF***** Assume IEEE arithmetic if we found denormalised numbers above,* or if arithmetic seems to round in the IEEE style, determined* in routine DLAMC1. A true IEEE machine should have both things* true; however, faulty machines may have one or the other.*IEEE = IEEE .OR. LIEEE1** Compute RMIN by successive division by BETA. We could compute* RMIN as BASE**( EMIN - 1 ), but some machines underflow during* this computation.*LRMIN = 1DO 30 I = 1, 1 - LEMINLRMIN = DLAMC3( LRMIN*RBASE, ZERO )30 CONTINUE** Finally, call DLAMC5 to compute EMAX and RMAX.*CALL DLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX )END IF*BETA = LBETAT = LTRND = LRNDEPS = LEPSEMIN = LEMINRMIN = LRMINEMAX = LEMAXRMAX = LRMAX*RETURN*9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',$ ' EMIN = ', I8, /$ ' If, after inspection, the value EMIN looks',$ ' acceptable please comment out ',$ / ' the IF block as marked within the code of routine',$ ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / )** End of DLAMC2*END**************************************************************************DOUBLE PRECISION FUNCTION DLAMC3( A, B )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION A, B* ..** Purpose* =======** DLAMC3 is intended to force A and B to be stored prior to doing* the addition of A and B , for use in situations where optimizers* might hold one of these in a register.** Arguments* =========** A, B (input) DOUBLE PRECISION* The values A and B.** =====================================================================** .. Executable Statements ..*DLAMC3 = A + B*RETURN** End of DLAMC3*END**************************************************************************SUBROUTINE DLAMC4( EMIN, START, BASE )** -- LAPACK auxiliary 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 BASE, EMINDOUBLE PRECISION START* ..** Purpose* =======** DLAMC4 is a service routine for DLAMC2.** Arguments* =========** EMIN (output) EMIN* The minimum exponent before (gradual) underflow, computed by* setting A = START and dividing by BASE until the previous A* can not be recovered.** START (input) DOUBLE PRECISION* The starting point for determining EMIN.** BASE (input) INTEGER* The base of the machine.** =====================================================================** .. Local Scalars ..INTEGER IDOUBLE PRECISION A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO* ..* .. External Functions ..DOUBLE PRECISION DLAMC3EXTERNAL DLAMC3* ..* .. Executable Statements ..*A = STARTONE = 1RBASE = ONE / BASEZERO = 0EMIN = 1B1 = DLAMC3( A*RBASE, ZERO )C1 = AC2 = AD1 = AD2 = A*+ WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND.* $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP10 CONTINUEIF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND.$ ( D2.EQ.A ) ) THENEMIN = EMIN - 1A = B1B1 = DLAMC3( A / BASE, ZERO )C1 = DLAMC3( B1*BASE, ZERO )D1 = ZERODO 20 I = 1, BASED1 = D1 + B120 CONTINUEB2 = DLAMC3( A*RBASE, ZERO )C2 = DLAMC3( B2 / RBASE, ZERO )D2 = ZERODO 30 I = 1, BASED2 = D2 + B230 CONTINUEGO TO 10END IF*+ END WHILE*RETURN** End of DLAMC4*END**************************************************************************SUBROUTINE DLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX )** -- LAPACK auxiliary 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 ..LOGICAL IEEEINTEGER BETA, EMAX, EMIN, PDOUBLE PRECISION RMAX* ..** Purpose* =======** DLAMC5 attempts to compute RMAX, the largest machine floating-point* number, without overflow. It assumes that EMAX + abs(EMIN) sum* approximately to a power of 2. It will fail on machines where this* assumption does not hold, for example, the Cyber 205 (EMIN = -28625,* EMAX = 28718). It will also fail if the value supplied for EMIN is* too large (i.e. too close to zero), probably with overflow.** Arguments* =========** BETA (input) INTEGER* The base of floating-point arithmetic.** P (input) INTEGER* The number of base BETA digits in the mantissa of a* floating-point value.** EMIN (input) INTEGER* The minimum exponent before (gradual) underflow.** IEEE (input) LOGICAL* A logical flag specifying whether or not the arithmetic* system is thought to comply with the IEEE standard.** EMAX (output) INTEGER* The largest exponent before overflow** RMAX (output) DOUBLE PRECISION* The largest machine floating-point number.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXPDOUBLE PRECISION OLDY, RECBAS, Y, Z* ..* .. External Functions ..DOUBLE PRECISION DLAMC3EXTERNAL DLAMC3* ..* .. Intrinsic Functions ..INTRINSIC MOD* ..* .. Executable Statements ..** First compute LEXP and UEXP, two powers of 2 that bound* abs(EMIN). We then assume that EMAX + abs(EMIN) will sum* approximately to the bound that is closest to abs(EMIN).* (EMAX is the exponent of the required number RMAX).*LEXP = 1EXBITS = 110 CONTINUETRY = LEXP*2IF( TRY.LE.( -EMIN ) ) THENLEXP = TRYEXBITS = EXBITS + 1GO TO 10END IFIF( LEXP.EQ.-EMIN ) THENUEXP = LEXPELSEUEXP = TRYEXBITS = EXBITS + 1END IF** Now -LEXP is less than or equal to EMIN, and -UEXP is greater* than or equal to EMIN. EXBITS is the number of bits needed to* store the exponent.*IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THENEXPSUM = 2*LEXPELSEEXPSUM = 2*UEXPEND IF** EXPSUM is the exponent range, approximately equal to* EMAX - EMIN + 1 .*EMAX = EXPSUM + EMIN - 1NBITS = 1 + EXBITS + P** NBITS is the total number of bits needed to store a* floating-point number.*IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN** Either there are an odd number of bits used to store a* floating-point number, which is unlikely, or some bits are* not used in the representation of numbers, which is possible,* (e.g. Cray machines) or the mantissa has an implicit bit,* (e.g. IEEE machines, Dec Vax machines), which is perhaps the* most likely. We have to assume the last alternative.* If this is true, then we need to reduce EMAX by one because* there must be some way of representing zero in an implicit-bit* system. On machines like Cray, we are reducing EMAX by one* unnecessarily.*EMAX = EMAX - 1END IF*IF( IEEE ) THEN** Assume we are on an IEEE machine which reserves one exponent* for infinity and NaN.*EMAX = EMAX - 1END IF** Now create RMAX, the largest machine number, which should* be equal to (1.0 - BETA**(-P)) * BETA**EMAX .** First compute 1.0 - BETA**(-P), being careful that the* result is less than 1.0 .*RECBAS = ONE / BETAZ = BETA - ONEY = ZERODO 20 I = 1, PZ = Z*RECBASIF( Y.LT.ONE )$ OLDY = YY = DLAMC3( Y, Z )20 CONTINUEIF( Y.GE.ONE )$ Y = OLDY** Now multiply by BETA**EMAX to get RMAX.*DO 30 I = 1, EMAXY = DLAMC3( Y*BETA, ZERO )30 CONTINUE*RMAX = YRETURN** End of DLAMC5*ENDDOUBLE PRECISION FUNCTION DLANGE( NORM, M, N, A, LDA, WORK )** -- LAPACK auxiliary 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 ..CHARACTER NORMINTEGER LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** Purpose* =======** DLANGE returns the value of the one norm, or the Frobenius norm, or* the infinity norm, or the element of largest absolute value of a* real matrix A.** Description* ===========** DLANGE returns the value** DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'* (* ( norm1(A), NORM = '1', 'O' or 'o'* (* ( normI(A), NORM = 'I' or 'i'* (* ( normF(A), NORM = 'F', 'f', 'E' or 'e'** where norm1 denotes the one norm of a matrix (maximum column sum),* normI denotes the infinity norm of a matrix (maximum row sum) and* normF denotes the Frobenius norm of a matrix (square root of sum of* squares). Note that max(abs(A(i,j))) is not a matrix norm.** Arguments* =========** NORM (input) CHARACTER*1* Specifies the value to be returned in DLANGE as described* above.** M (input) INTEGER* The number of rows of the matrix A. M >= 0. When M = 0,* DLANGE is set to zero.** N (input) INTEGER* The number of columns of the matrix A. N >= 0. When N = 0,* DLANGE is set to zero.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The m by n matrix A.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(M,1).** WORK (workspace) DOUBLE PRECISION array, dimension (LWORK),* where LWORK >= M when NORM = 'I'; otherwise, WORK is not* referenced.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*IF( MIN( M, N ).EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZERODO 20 J = 1, NDO 10 I = 1, MVALUE = MAX( VALUE, ABS( A( I, J ) ) )10 CONTINUE20 CONTINUEELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZERODO 40 J = 1, NSUM = ZERODO 30 I = 1, MSUM = SUM + ABS( A( I, J ) )30 CONTINUEVALUE = MAX( VALUE, SUM )40 CONTINUEELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*DO 50 I = 1, MWORK( I ) = ZERO50 CONTINUEDO 70 J = 1, NDO 60 I = 1, MWORK( I ) = WORK( I ) + ABS( A( I, J ) )60 CONTINUE70 CONTINUEVALUE = ZERODO 80 I = 1, MVALUE = MAX( VALUE, WORK( I ) )80 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEDO 90 J = 1, NCALL DLASSQ( M, A( 1, J ), 1, SCALE, SUM )90 CONTINUEVALUE = SCALE*SQRT( SUM )END IF*DLANGE = VALUERETURN** End of DLANGE*ENDDOUBLE PRECISION FUNCTION DLANHS( NORM, N, A, LDA, WORK )** -- LAPACK auxiliary 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 ..CHARACTER NORMINTEGER LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** Purpose* =======** DLANHS returns the value of the one norm, or the Frobenius norm, or* the infinity norm, or the element of largest absolute value of a* Hessenberg matrix A.** Description* ===========** DLANHS returns the value** DLANHS = ( max(abs(A(i,j))), NORM = 'M' or 'm'* (* ( norm1(A), NORM = '1', 'O' or 'o'* (* ( normI(A), NORM = 'I' or 'i'* (* ( normF(A), NORM = 'F', 'f', 'E' or 'e'** where norm1 denotes the one norm of a matrix (maximum column sum),* normI denotes the infinity norm of a matrix (maximum row sum) and* normF denotes the Frobenius norm of a matrix (square root of sum of* squares). Note that max(abs(A(i,j))) is not a matrix norm.** Arguments* =========** NORM (input) CHARACTER*1* Specifies the value to be returned in DLANHS as described* above.** N (input) INTEGER* The order of the matrix A. N >= 0. When N = 0, DLANHS is* set to zero.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The n by n upper Hessenberg matrix A; the part of A below the* first sub-diagonal is not referenced.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(N,1).** WORK (workspace) DOUBLE PRECISION array, dimension (LWORK),* where LWORK >= N when NORM = 'I'; otherwise, WORK is not* referenced.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZERODO 20 J = 1, NDO 10 I = 1, MIN( N, J+1 )VALUE = MAX( VALUE, ABS( A( I, J ) ) )10 CONTINUE20 CONTINUEELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZERODO 40 J = 1, NSUM = ZERODO 30 I = 1, MIN( N, J+1 )SUM = SUM + ABS( A( I, J ) )30 CONTINUEVALUE = MAX( VALUE, SUM )40 CONTINUEELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*DO 50 I = 1, NWORK( I ) = ZERO50 CONTINUEDO 70 J = 1, NDO 60 I = 1, MIN( N, J+1 )WORK( I ) = WORK( I ) + ABS( A( I, J ) )60 CONTINUE70 CONTINUEVALUE = ZERODO 80 I = 1, NVALUE = MAX( VALUE, WORK( I ) )80 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEDO 90 J = 1, NCALL DLASSQ( MIN( N, J+1 ), A( 1, J ), 1, SCALE, SUM )90 CONTINUEVALUE = SCALE*SQRT( SUM )END IF*DLANHS = VALUERETURN** End of DLANHS*ENDDOUBLE PRECISION FUNCTION DLANST( NORM, N, D, E )** -- LAPACK auxiliary 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 N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * )* ..** Purpose* =======** DLANST returns the value of the one norm, or the Frobenius norm, or* the infinity norm, or the element of largest absolute value of a* real symmetric tridiagonal matrix A.** Description* ===========** DLANST returns the value** DLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm'* (* ( norm1(A), NORM = '1', 'O' or 'o'* (* ( normI(A), NORM = 'I' or 'i'* (* ( normF(A), NORM = 'F', 'f', 'E' or 'e'** where norm1 denotes the one norm of a matrix (maximum column sum),* normI denotes the infinity norm of a matrix (maximum row sum) and* normF denotes the Frobenius norm of a matrix (square root of sum of* squares). Note that max(abs(A(i,j))) is not a matrix norm.** Arguments* =========** NORM (input) CHARACTER*1* Specifies the value to be returned in DLANST as described* above.** N (input) INTEGER* The order of the matrix A. N >= 0. When N = 0, DLANST is* set to zero.** D (input) DOUBLE PRECISION array, dimension (N)* The diagonal elements of A.** E (input) DOUBLE PRECISION array, dimension (N-1)* The (n-1) sub-diagonal or super-diagonal elements of A.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION ANORM, SCALE, SUM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*IF( N.LE.0 ) THENANORM = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*ANORM = ABS( D( N ) )DO 10 I = 1, N - 1ANORM = MAX( ANORM, ABS( D( I ) ) )ANORM = MAX( ANORM, ABS( E( I ) ) )10 CONTINUEELSE IF( LSAME( NORM, 'O' ) .OR. NORM.EQ.'1' .OR.$ LSAME( NORM, 'I' ) ) THEN** Find norm1(A).*IF( N.EQ.1 ) THENANORM = ABS( D( 1 ) )ELSEANORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),$ ABS( E( N-1 ) )+ABS( D( N ) ) )DO 20 I = 2, N - 1ANORM = MAX( ANORM, ABS( D( I ) )+ABS( E( I ) )+$ ABS( E( I-1 ) ) )20 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEIF( N.GT.1 ) THENCALL DLASSQ( N-1, E, 1, SCALE, SUM )SUM = 2*SUMEND IFCALL DLASSQ( N, D, 1, SCALE, SUM )ANORM = SCALE*SQRT( SUM )END IF*DLANST = ANORMRETURN** End of DLANST*ENDDOUBLE PRECISION FUNCTION DLANSY( NORM, UPLO, N, A, LDA, WORK )** -- LAPACK auxiliary 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 ..CHARACTER NORM, UPLOINTEGER LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** Purpose* =======** DLANSY returns the value of the one norm, or the Frobenius norm, or* the infinity norm, or the element of largest absolute value of a* real symmetric matrix A.** Description* ===========** DLANSY returns the value** DLANSY = ( max(abs(A(i,j))), NORM = 'M' or 'm'* (* ( norm1(A), NORM = '1', 'O' or 'o'* (* ( normI(A), NORM = 'I' or 'i'* (* ( normF(A), NORM = 'F', 'f', 'E' or 'e'** where norm1 denotes the one norm of a matrix (maximum column sum),* normI denotes the infinity norm of a matrix (maximum row sum) and* normF denotes the Frobenius norm of a matrix (square root of sum of* squares). Note that max(abs(A(i,j))) is not a matrix norm.** Arguments* =========** NORM (input) CHARACTER*1* Specifies the value to be returned in DLANSY as described* above.** UPLO (input) CHARACTER*1* Specifies whether the upper or lower triangular part of the* symmetric matrix A is to be referenced.* = 'U': Upper triangular part of A is referenced* = 'L': Lower triangular part of A is referenced** N (input) INTEGER* The order of the matrix A. N >= 0. When N = 0, DLANSY is* set to zero.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The symmetric matrix A. If UPLO = 'U', the leading n by n* upper triangular part of A contains the upper triangular part* of the matrix A, and the strictly lower triangular part of A* is not referenced. If UPLO = 'L', the leading n by n lower* triangular part of A contains the lower triangular part of* the matrix A, and the strictly upper triangular part of A is* not referenced.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(N,1).** WORK (workspace) DOUBLE PRECISION array, dimension (LWORK),* where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,* WORK is not referenced.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION ABSA, SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = 1, JVALUE = MAX( VALUE, ABS( A( I, J ) ) )10 CONTINUE20 CONTINUEELSEDO 40 J = 1, NDO 30 I = J, NVALUE = MAX( VALUE, ABS( A( I, J ) ) )30 CONTINUE40 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.$ ( NORM.EQ.'1' ) ) THEN** Find normI(A) ( = norm1(A), since A is symmetric).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NSUM = ZERODO 50 I = 1, J - 1ABSA = ABS( A( I, J ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSA50 CONTINUEWORK( J ) = SUM + ABS( A( J, J ) )60 CONTINUEDO 70 I = 1, NVALUE = MAX( VALUE, WORK( I ) )70 CONTINUEELSEDO 80 I = 1, NWORK( I ) = ZERO80 CONTINUEDO 100 J = 1, NSUM = WORK( J ) + ABS( A( J, J ) )DO 90 I = J + 1, NABSA = ABS( A( I, J ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSA90 CONTINUEVALUE = MAX( VALUE, SUM )100 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEIF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 2, NCALL DLASSQ( J-1, A( 1, J ), 1, SCALE, SUM )110 CONTINUEELSEDO 120 J = 1, N - 1CALL DLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM )120 CONTINUEEND IFSUM = 2*SUMCALL DLASSQ( N, A, LDA+1, SCALE, SUM )VALUE = SCALE*SQRT( SUM )END IF*DLANSY = VALUERETURN** End of DLANSY*ENDSUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )** -- LAPACK driver 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 ..DOUBLE PRECISION A, B, C, CS, D, RT1I, RT1R, RT2I, RT2R, SN* ..** Purpose* =======** DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric* matrix in standard form:** [ A B ] = [ CS -SN ] [ AA BB ] [ CS SN ]* [ C D ] [ SN CS ] [ CC DD ] [-SN CS ]** where either* 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or* 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex* conjugate eigenvalues.** Arguments* =========** A (input/output) DOUBLE PRECISION* B (input/output) DOUBLE PRECISION* C (input/output) DOUBLE PRECISION* D (input/output) DOUBLE PRECISION* On entry, the elements of the input matrix.* On exit, they are overwritten by the elements of the* standardised Schur form.** RT1R (output) DOUBLE PRECISION* RT1I (output) DOUBLE PRECISION* RT2R (output) DOUBLE PRECISION* RT2I (output) DOUBLE PRECISION* The real and imaginary parts of the eigenvalues. If the* eigenvalues are a complex conjugate pair, RT1I > 0.** CS (output) DOUBLE PRECISION* SN (output) DOUBLE PRECISION* Parameters of the rotation matrix.** Further Details* ===============** Modified by V. Sima, Research Institute for Informatics, Bucharest,* Romania, to reduce the risk of cancellation errors,* when computing real eigenvalues, and to ensure, if possible, that* abs(RT1R) >= abs(RT2R).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )DOUBLE PRECISION MULTPLPARAMETER ( MULTPL = 4.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, BB, BCMAX, BCMIS, CC, CS1, DD, EPS, P, SAB,$ SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL DLAMCH, DLAPY2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..*EPS = DLAMCH( 'P' )IF( C.EQ.ZERO ) THENCS = ONESN = ZEROGO TO 10*ELSE IF( B.EQ.ZERO ) THEN** Swap rows and columns*CS = ZEROSN = ONETEMP = DD = AA = TEMPB = -CC = ZEROGO TO 10ELSE IF( ( A-D ).EQ.ZERO .AND. SIGN( ONE, B ).NE.SIGN( ONE, C ) )$ THENCS = ONESN = ZEROGO TO 10ELSE*TEMP = A - DP = HALF*TEMPBCMAX = MAX( ABS( B ), ABS( C ) )BCMIS = MIN( ABS( B ), ABS( C ) )*SIGN( ONE, B )*SIGN( ONE, C )SCALE = MAX( ABS( P ), BCMAX )Z = ( P / SCALE )*P + ( BCMAX / SCALE )*BCMIS** If Z is of the order of the machine accuracy, postpone the* decision on the nature of eigenvalues*IF( Z.GE.MULTPL*EPS ) THEN** Real eigenvalues. Compute A and D.*Z = P + SIGN( SQRT( SCALE )*SQRT( Z ), P )A = D + ZD = D - ( BCMAX / Z )*BCMIS** Compute B and the rotation matrix*TAU = DLAPY2( C, Z )CS = Z / TAUSN = C / TAUB = B - CC = ZEROELSE** Complex eigenvalues, or real (almost) equal eigenvalues.* Make diagonal elements equal.*SIGMA = B + CTAU = DLAPY2( SIGMA, TEMP )CS = SQRT( HALF*( ONE+ABS( SIGMA ) / TAU ) )SN = -( P / ( TAU*CS ) )*SIGN( ONE, SIGMA )** Compute [ AA BB ] = [ A B ] [ CS -SN ]* [ CC DD ] [ C D ] [ SN CS ]*AA = A*CS + B*SNBB = -A*SN + B*CSCC = C*CS + D*SNDD = -C*SN + D*CS** Compute [ A B ] = [ CS SN ] [ AA BB ]* [ C D ] [-SN CS ] [ CC DD ]*A = AA*CS + CC*SNB = BB*CS + DD*SNC = -AA*SN + CC*CSD = -BB*SN + DD*CS*TEMP = HALF*( A+D )A = TEMPD = TEMP*IF( C.NE.ZERO ) THENIF( B.NE.ZERO ) THENIF( SIGN( ONE, B ).EQ.SIGN( ONE, C ) ) THEN** Real eigenvalues: reduce to upper triangular form*SAB = SQRT( ABS( B ) )SAC = SQRT( ABS( C ) )P = SIGN( SAB*SAC, C )TAU = ONE / SQRT( ABS( B+C ) )A = TEMP + PD = TEMP - PB = B - CC = ZEROCS1 = SAB*TAUSN1 = SAC*TAUTEMP = CS*CS1 - SN*SN1SN = CS*SN1 + SN*CS1CS = TEMPEND IFELSEB = -CC = ZEROTEMP = CSCS = -SNSN = TEMPEND IFEND IFEND IF*END IF*10 CONTINUE** Store eigenvalues in (RT1R,RT1I) and (RT2R,RT2I).*RT1R = ART2R = DIF( C.EQ.ZERO ) THENRT1I = ZERORT2I = ZEROELSERT1I = SQRT( ABS( B ) )*SQRT( ABS( C ) )RT2I = -RT1IEND IFRETURN** End of DLANV2*ENDDOUBLE PRECISION FUNCTION DLAPY2( X, Y )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION X, Y* ..** Purpose* =======** DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary* overflow.** Arguments* =========** X (input) DOUBLE PRECISION* Y (input) DOUBLE PRECISION* X and Y specify the values x and y.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION W, XABS, YABS, Z* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*XABS = ABS( X )YABS = ABS( Y )W = MAX( XABS, YABS )Z = MIN( XABS, YABS )IF( Z.EQ.ZERO ) THENDLAPY2 = WELSEDLAPY2 = W*SQRT( ONE+( Z / W )**2 )END IFRETURN** End of DLAPY2*ENDSUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,$ INFO )** -- LAPACK auxiliary 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 ..LOGICAL LREAL, LTRANINTEGER INFO, LDT, NDOUBLE PRECISION SCALE, W* ..* .. Array Arguments ..DOUBLE PRECISION B( * ), T( LDT, * ), WORK( * ), X( * )* ..** Purpose* =======** DLAQTR solves the real quasi-triangular system** op(T)*p = scale*c, if LREAL = .TRUE.** or the complex quasi-triangular systems** op(T + iB)*(p+iq) = scale*(c+id), if LREAL = .FALSE.** in real arithmetic, where T is upper quasi-triangular.* If LREAL = .FALSE., then the first diagonal block of T must be* 1 by 1, B is the specially structured matrix** B = [ b(1) b(2) ... b(n) ]* [ w ]* [ w ]* [ . ]* [ w ]** op(A) = A or A', A' denotes the conjugate transpose of* matrix A.** On input, X = [ c ]. On output, X = [ p ].* [ d ] [ q ]** This subroutine is designed for the condition number estimation* in routine DTRSNA.** Arguments* =========** LTRAN (input) LOGICAL* On entry, LTRAN specifies the option of conjugate transpose:* = .FALSE., op(T+i*B) = T+i*B,* = .TRUE., op(T+i*B) = (T+i*B)'.** LREAL (input) LOGICAL* On entry, LREAL specifies the input matrix structure:* = .FALSE., the input is complex* = .TRUE., the input is real** N (input) INTEGER* On entry, N specifies the order of T+i*B. N >= 0.** T (input) DOUBLE PRECISION array, dimension (LDT,N)* On entry, T contains a matrix in Schur canonical form.* If LREAL = .FALSE., then the first diagonal block of T mu* be 1 by 1.** LDT (input) INTEGER* The leading dimension of the matrix T. LDT >= max(1,N).** B (input) DOUBLE PRECISION array, dimension (N)* On entry, B contains the elements to form the matrix* B as described above.* If LREAL = .TRUE., B is not referenced.** W (input) DOUBLE PRECISION* On entry, W is the diagonal element of the matrix B.* If LREAL = .TRUE., W is not referenced.** SCALE (output) DOUBLE PRECISION* On exit, SCALE is the scale factor.** X (input/output) DOUBLE PRECISION array, dimension (2*N)* On entry, X contains the right hand side of the system.* On exit, X is overwritten by the solution.** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* On exit, INFO is set to* 0: successful exit.* 1: the some diagonal 1 by 1 block has been perturbed by* a small number SMIN to keep nonsingularity.* 2: the some diagonal 2 by 2 block has been perturbed by* a small number in DLALN2 to keep nonsingularity.* NOTE: In the interests of speed, this routine does not* check the inputs for errors.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANINTEGER I, IERR, J, J1, J2, JNEXT, K, N1, N2DOUBLE PRECISION BIGNUM, EPS, REC, SCALOC, SI, SMIN, SMINW,$ SMLNUM, SR, TJJ, TMP, XJ, XMAX, XNORM, Z* ..* .. Local Arrays ..DOUBLE PRECISION D( 2, 2 ), V( 2, 2 )* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DASUM, DDOT, DLAMCH, DLANGEEXTERNAL IDAMAX, DASUM, DDOT, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DAXPY, DLADIV, DLALN2, DSCAL* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Do not test the input parameters for errors*NOTRAN = .NOT.LTRANINFO = 0** Quick return if possible*IF( N.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUM*XNORM = DLANGE( 'M', N, N, T, LDT, D )IF( .NOT.LREAL )$ XNORM = MAX( XNORM, ABS( W ), DLANGE( 'M', N, 1, B, N, D ) )SMIN = MAX( SMLNUM, EPS*XNORM )** Compute 1-norm of each column of strictly upper triangular* part of T to control overflow in triangular solver.*WORK( 1 ) = ZERODO 10 J = 2, NWORK( J ) = DASUM( J-1, T( 1, J ), 1 )10 CONTINUE*IF( .NOT.LREAL ) THENDO 20 I = 2, NWORK( I ) = WORK( I ) + ABS( B( I ) )20 CONTINUEEND IF*N2 = 2*NN1 = NIF( .NOT.LREAL )$ N1 = N2K = IDAMAX( N1, X, 1 )XMAX = ABS( X( K ) )SCALE = ONE*IF( XMAX.GT.BIGNUM ) THENSCALE = BIGNUM / XMAXCALL DSCAL( N1, SCALE, X, 1 )XMAX = BIGNUMEND IF*IF( LREAL ) THEN*IF( NOTRAN ) THEN** Solve T*p = scale*c*JNEXT = NDO 30 J = N, 1, -1IF( J.GT.JNEXT )$ GO TO 30J1 = JJ2 = JJNEXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNEXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** Meet 1 by 1 diagonal block** Scale to avoid overflow when computing* x(j) = b(j)/T(j,j)*XJ = ABS( X( J1 ) )TJJ = ABS( T( J1, J1 ) )TMP = T( J1, J1 )IF( TJJ.LT.SMIN ) THENTMP = SMINTJJ = SMININFO = 1END IF*IF( XJ.EQ.ZERO )$ GO TO 30*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J1 ) = X( J1 ) / TMPXJ = ABS( X( J1 ) )** Scale x if necessary to avoid overflow when adding a* multiple of column j1 of T.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFEND IFIF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )K = IDAMAX( J1-1, X, 1 )XMAX = ABS( X( K ) )END IF*ELSE** Meet 2 by 2 diagonal block** Call 2 by 2 linear system solve, to take* care of possible overflow by scaling factor.*D( 1, 1 ) = X( J1 )D( 2, 1 ) = X( J2 )CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( N, SCALOC, X, 1 )SCALE = SCALE*SCALOCEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )** Scale V(1,1) (= X(J1)) and/or V(2,1) (=X(J2))* to avoid overflow in updating right-hand side.*XJ = MAX( ABS( V( 1, 1 ) ), ABS( V( 2, 1 ) ) )IF( XJ.GT.ONE ) THENREC = ONE / XJIF( MAX( WORK( J1 ), WORK( J2 ) ).GT.$ ( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFEND IF** Update right-hand side*IF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )K = IDAMAX( J1-1, X, 1 )XMAX = ABS( X( K ) )END IF*END IF*30 CONTINUE*ELSE** Solve T'*p = scale*c*JNEXT = 1DO 40 J = 1, NIF( J.LT.JNEXT )$ GO TO 40J1 = JJ2 = JJNEXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNEXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1 by 1 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side element by inner product.*XJ = ABS( X( J1 ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )*XJ = ABS( X( J1 ) )TJJ = ABS( T( J1, J1 ) )TMP = T( J1, J1 )IF( TJJ.LT.SMIN ) THENTMP = SMINTJJ = SMININFO = 1END IF*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J1 ) = X( J1 ) / TMPXMAX = MAX( XMAX, ABS( X( J1 ) ) )*ELSE** 2 by 2 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side elements by inner product.*XJ = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( MAX( WORK( J2 ), WORK( J1 ) ).GT.( BIGNUM-XJ )*$ REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,$ 1 )D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,$ 1 )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( N, SCALOC, X, 1 )SCALE = SCALE*SCALOCEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )XMAX = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ), XMAX )*END IF40 CONTINUEEND IF*ELSE*SMINW = MAX( EPS*ABS( W ), SMIN )IF( NOTRAN ) THEN** Solve (T + iB)*(p+iq) = c+id*JNEXT = NDO 70 J = N, 1, -1IF( J.GT.JNEXT )$ GO TO 70J1 = JJ2 = JJNEXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNEXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1 by 1 diagonal block** Scale if necessary to avoid overflow in division*Z = WIF( J1.EQ.1 )$ Z = B( 1 )XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )TJJ = ABS( T( J1, J1 ) ) + ABS( Z )TMP = T( J1, J1 )IF( TJJ.LT.SMINW ) THENTMP = SMINWTJJ = SMINWINFO = 1END IF*IF( XJ.EQ.ZERO )$ GO TO 70*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFCALL DLADIV( X( J1 ), X( N+J1 ), TMP, Z, SR, SI )X( J1 ) = SRX( N+J1 ) = SIXJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )** Scale x if necessary to avoid overflow when adding a* multiple of column j1 of T.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECEND IFEND IF*IF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,$ X( N+1 ), 1 )*X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 )X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 )*XMAX = ZERODO 50 K = 1, J1 - 1XMAX = MAX( XMAX, ABS( X( K ) )+$ ABS( X( K+N ) ) )50 CONTINUEEND IF*ELSE** Meet 2 by 2 diagonal block*D( 1, 1 ) = X( J1 )D( 2, 1 ) = X( J2 )D( 1, 2 ) = X( N+J1 )D( 2, 2 ) = X( N+J2 )CALL DLALN2( .FALSE., 2, 2, SMINW, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, -W, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( 2*N, SCALOC, X, 1 )SCALE = SCALOC*SCALEEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )X( N+J1 ) = V( 1, 2 )X( N+J2 ) = V( 2, 2 )** Scale X(J1), .... to avoid overflow in* updating right hand side.*XJ = MAX( ABS( V( 1, 1 ) )+ABS( V( 1, 2 ) ),$ ABS( V( 2, 1 ) )+ABS( V( 2, 2 ) ) )IF( XJ.GT.ONE ) THENREC = ONE / XJIF( MAX( WORK( J1 ), WORK( J2 ) ).GT.$ ( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECEND IFEND IF** Update the right-hand side.*IF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )*CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,$ X( N+1 ), 1 )CALL DAXPY( J1-1, -X( N+J2 ), T( 1, J2 ), 1,$ X( N+1 ), 1 )*X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 ) +$ B( J2 )*X( N+J2 )X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 ) -$ B( J2 )*X( J2 )*XMAX = ZERODO 60 K = 1, J1 - 1XMAX = MAX( ABS( X( K ) )+ABS( X( K+N ) ),$ XMAX )60 CONTINUEEND IF*END IF70 CONTINUE*ELSE** Solve (T + iB)'*(p+iq) = c+id*JNEXT = 1DO 80 J = 1, NIF( J.LT.JNEXT )$ GO TO 80J1 = JJ2 = JJNEXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNEXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1 by 1 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side element by inner product.*XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )X( N+J1 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,$ X( N+1 ), 1 )IF( J1.GT.1 ) THENX( J1 ) = X( J1 ) - B( J1 )*X( N+1 )X( N+J1 ) = X( N+J1 ) + B( J1 )*X( 1 )END IFXJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )*Z = WIF( J1.EQ.1 )$ Z = B( 1 )** Scale if necessary to avoid overflow in* complex division*TJJ = ABS( T( J1, J1 ) ) + ABS( Z )TMP = T( J1, J1 )IF( TJJ.LT.SMINW ) THENTMP = SMINWTJJ = SMINWINFO = 1END IF*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFCALL DLADIV( X( J1 ), X( N+J1 ), TMP, -Z, SR, SI )X( J1 ) = SRX( J1+N ) = SIXMAX = MAX( ABS( X( J1 ) )+ABS( X( J1+N ) ), XMAX )*ELSE** 2 by 2 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side element by inner product.*XJ = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),$ ABS( X( J2 ) )+ABS( X( N+J2 ) ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( MAX( WORK( J1 ), WORK( J2 ) ).GT.$ ( BIGNUM-XJ ) / XMAX ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,$ 1 )D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,$ 1 )D( 1, 2 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,$ X( N+1 ), 1 )D( 2, 2 ) = X( N+J2 ) - DDOT( J1-1, T( 1, J2 ), 1,$ X( N+1 ), 1 )D( 1, 1 ) = D( 1, 1 ) - B( J1 )*X( N+1 )D( 2, 1 ) = D( 2, 1 ) - B( J2 )*X( N+1 )D( 1, 2 ) = D( 1, 2 ) + B( J1 )*X( 1 )D( 2, 2 ) = D( 2, 2 ) + B( J2 )*X( 1 )*CALL DLALN2( .TRUE., 2, 2, SMINW, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, W, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( N2, SCALOC, X, 1 )SCALE = SCALOC*SCALEEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )X( N+J1 ) = V( 1, 2 )X( N+J2 ) = V( 2, 2 )XMAX = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),$ ABS( X( J2 ) )+ABS( X( N+J2 ) ), XMAX )*END IF*80 CONTINUE*END IF*END IF*RETURN** End of DLAQTR*ENDSUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )** -- LAPACK auxiliary 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 C( LDC, * ), V( * ), WORK( * )* ..** Purpose* =======** DLARF 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.** 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.** V (input) DOUBLE PRECISION array, dimension* (1 + (M-1)*abs(INCV)) if SIDE = 'L'* or (1 + (N-1)*abs(INCV)) if SIDE = 'R'* The vector v in the representation of H. 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'** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C*IF( TAU.NE.ZERO ) THEN** w := C' * v*CALL DGEMV( 'Transpose', M, N, ONE, C, LDC, V, INCV, ZERO,$ WORK, 1 )** C := C - v * w'*CALL DGER( M, N, -TAU, V, INCV, WORK, 1, C, LDC )END IFELSE** Form C * H*IF( TAU.NE.ZERO ) THEN** w := C * v*CALL DGEMV( 'No transpose', M, N, ONE, C, LDC, V, INCV,$ ZERO, WORK, 1 )** C := C - w * v'*CALL DGER( M, N, -TAU, WORK, 1, V, INCV, C, LDC )END IFEND IFRETURN** End of DLARF*ENDSUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,$ T, LDT, C, LDC, WORK, LDWORK )** -- LAPACK auxiliary 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 DIRECT, SIDE, STOREV, TRANSINTEGER K, LDC, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),$ WORK( LDWORK, * )* ..** Purpose* =======** DLARFB applies a real block reflector H or its transpose H' to a* real m by n matrix C, from either the left or the right.** 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)* = 'T': 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)* = '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* = '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).** V (input) DOUBLE PRECISION array, dimension* (LDV,K) if STOREV = 'C'* (LDV,M) if STOREV = 'R' and SIDE = 'L'* (LDV,N) if STOREV = 'R' and SIDE = 'R'* The matrix V. See further details.** LDV (input) INTEGER* The leading dimension of the array V.* If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);* if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);* 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. LDA >= 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).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..CHARACTER TRANSTINTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DTRMM* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 )$ RETURN*IF( LSAME( TRANS, 'N' ) ) THENTRANST = 'T'ELSETRANST = 'N'END IF*IF( LSAME( STOREV, 'C' ) ) THEN*IF( LSAME( DIRECT, 'F' ) ) THEN** Let V = ( V1 ) (first K rows)* ( V2 )* where V1 is unit lower triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H' * C where C = ( C1 )* ( C2 )** W := C' * V = (C1'*V1 + C2'*V2) (stored in WORK)** W := C1'*DO 10 J = 1, KCALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )10 CONTINUE** W := W * V1*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,$ K, ONE, V, LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C2'*V2*CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K,$ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,$ ONE, WORK, LDWORK )END IF** W := W * T' or W * T*CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V * W'*IF( M.GT.K ) THEN** C2 := C2 - V2 * W'*CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K,$ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,$ C( K+1, 1 ), LDC )END IF** W := W * V1'*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,$ ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W'*DO 30 J = 1, KDO 20 I = 1, NC( J, I ) = C( J, I ) - WORK( I, J )20 CONTINUE30 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H' where C = ( C1 C2 )** W := C * V = (C1*V1 + C2*V2) (stored in WORK)** W := C1*DO 40 J = 1, KCALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )40 CONTINUE** W := W * V1*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,$ K, ONE, V, LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C2 * V2*CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K,$ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,$ ONE, WORK, LDWORK )END IF** W := W * T or W * T'*CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V'*IF( N.GT.K ) THEN** C2 := C2 - W * V2'*CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,$ C( 1, K+1 ), LDC )END IF** W := W * V1'*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,$ ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W*DO 60 J = 1, KDO 50 I = 1, MC( I, J ) = C( I, J ) - WORK( I, J )50 CONTINUE60 CONTINUEEND IF*ELSE** Let V = ( V1 )* ( V2 ) (last K rows)* where V2 is unit upper triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H' * C where C = ( C1 )* ( C2 )** W := C' * V = (C1'*V1 + C2'*V2) (stored in WORK)** W := C2'*DO 70 J = 1, KCALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )70 CONTINUE** W := W * V2*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,$ K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C1'*V1*CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K,$ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T' or W * T*CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V * W'*IF( M.GT.K ) THEN** C1 := C1 - V1 * W'*CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K,$ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )END IF** W := W * V2'*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,$ ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )** C2 := C2 - W'*DO 90 J = 1, KDO 80 I = 1, NC( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )80 CONTINUE90 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H' where C = ( C1 C2 )** W := C * V = (C1*V1 + C2*V2) (stored in WORK)** W := C2*DO 100 J = 1, KCALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )100 CONTINUE** W := W * V2*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,$ K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C1 * V1*CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K,$ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T or W * T'*CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V'*IF( N.GT.K ) THEN** C1 := C1 - W * V1'*CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )END IF** W := W * V2'*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,$ ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )** C2 := C2 - W*DO 120 J = 1, KDO 110 I = 1, MC( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )110 CONTINUE120 CONTINUEEND IFEND IF*ELSE IF( LSAME( STOREV, 'R' ) ) THEN*IF( LSAME( DIRECT, 'F' ) ) THEN** Let V = ( V1 V2 ) (V1: first K columns)* where V1 is unit upper triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H' * C where C = ( C1 )* ( C2 )** W := C' * V' = (C1'*V1' + C2'*V2') (stored in WORK)** W := C1'*DO 130 J = 1, KCALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )130 CONTINUE** W := W * V1'*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,$ ONE, V, LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C2'*V2'*CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,$ C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,$ WORK, LDWORK )END IF** W := W * T' or W * T*CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V' * W'*IF( M.GT.K ) THEN** C2 := C2 - V2' * W'*CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,$ V( 1, K+1 ), LDV, WORK, LDWORK, ONE,$ C( K+1, 1 ), LDC )END IF** W := W * V1*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,$ K, ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W'*DO 150 J = 1, KDO 140 I = 1, NC( J, I ) = C( J, I ) - WORK( I, J )140 CONTINUE150 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H' where C = ( C1 C2 )** W := C * V' = (C1*V1' + C2*V2') (stored in WORK)** W := C1*DO 160 J = 1, KCALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )160 CONTINUE** W := W * V1'*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,$ ONE, V, LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C2 * V2'*CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K,$ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,$ ONE, WORK, LDWORK )END IF** W := W * T or W * T'*CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V*IF( N.GT.K ) THEN** C2 := C2 - W * V2*CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE,$ C( 1, K+1 ), LDC )END IF** W := W * V1*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,$ K, ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W*DO 180 J = 1, KDO 170 I = 1, MC( I, J ) = C( I, J ) - WORK( I, J )170 CONTINUE180 CONTINUE*END IF*ELSE** Let V = ( V1 V2 ) (V2: last K columns)* where V2 is unit lower triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H' * C where C = ( C1 )* ( C2 )** W := C' * V' = (C1'*V1' + C2'*V2') (stored in WORK)** W := C2'*DO 190 J = 1, KCALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )190 CONTINUE** W := W * V2'*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,$ ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C1'*V1'*CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,$ C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T' or W * T*CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V' * W'*IF( M.GT.K ) THEN** C1 := C1 - V1' * W'*CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,$ V, LDV, WORK, LDWORK, ONE, C, LDC )END IF** W := W * V2*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,$ K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )** C2 := C2 - W'*DO 210 J = 1, KDO 200 I = 1, NC( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )200 CONTINUE210 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H' where C = ( C1 C2 )** W := C * V' = (C1*V1' + C2*V2') (stored in WORK)** W := C2*DO 220 J = 1, KCALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )220 CONTINUE** W := W * V2'*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,$ ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C1 * V1'*CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K,$ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T or W * T'*CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V*IF( N.GT.K ) THEN** C1 := C1 - W * V1*CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )END IF** W := W * V2*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,$ K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )** C1 := C1 - W*DO 240 J = 1, KDO 230 I = 1, MC( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )230 CONTINUE240 CONTINUE*END IF*END IFEND IF*RETURN** End of DLARFB*ENDSUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU )** -- LAPACK auxiliary 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 INCX, NDOUBLE PRECISION ALPHA, TAU* ..* .. Array Arguments ..DOUBLE PRECISION X( * )* ..** Purpose* =======** DLARFG generates a real elementary reflector H of order n, such* that** H * ( alpha ) = ( beta ), H' * H = I.* ( x ) ( 0 )** where alpha and beta are scalars, and x is an (n-1)-element real* vector. H is represented in the form** H = I - tau * ( 1 ) * ( 1 v' ) ,* ( v )** where tau is a real scalar and v is a real (n-1)-element* vector.** If the elements of x are all zero, then tau = 0 and H is taken to be* the unit matrix.** Otherwise 1 <= tau <= 2.** Arguments* =========** N (input) INTEGER* The order of the elementary reflector.** ALPHA (input/output) DOUBLE PRECISION* On entry, the value alpha.* On exit, it is overwritten with the value beta.** X (input/output) DOUBLE PRECISION array, dimension* (1+(N-2)*abs(INCX))* On entry, the vector x.* On exit, it is overwritten with the vector v.** INCX (input) INTEGER* The increment between elements of X. INCX > 0.** TAU (output) DOUBLE PRECISION* The value tau.** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER J, KNTDOUBLE PRECISION BETA, RSAFMN, SAFMIN, XNORM* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2, DNRM2EXTERNAL DLAMCH, DLAPY2, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN* ..* .. External Subroutines ..EXTERNAL DSCAL* ..* .. Executable Statements ..*IF( N.LE.1 ) THENTAU = ZERORETURNEND IF*XNORM = DNRM2( N-1, X, INCX )*IF( XNORM.EQ.ZERO ) THEN** H = I*TAU = ZEROELSE** general case*BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' )IF( ABS( BETA ).LT.SAFMIN ) THEN** XNORM, BETA may be inaccurate; scale X and recompute them*RSAFMN = ONE / SAFMINKNT = 010 CONTINUEKNT = KNT + 1CALL DSCAL( N-1, RSAFMN, X, INCX )BETA = BETA*RSAFMNALPHA = ALPHA*RSAFMNIF( ABS( BETA ).LT.SAFMIN )$ GO TO 10** New BETA is at most 1, at least SAFMIN*XNORM = DNRM2( N-1, X, INCX )BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )TAU = ( BETA-ALPHA ) / BETACALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )** If ALPHA is subnormal, it may lose relative accuracy*ALPHA = BETADO 20 J = 1, KNTALPHA = ALPHA*SAFMIN20 CONTINUEELSETAU = ( BETA-ALPHA ) / BETACALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )ALPHA = BETAEND IFEND IF*RETURN** End of DLARFG*ENDSUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )** -- LAPACK auxiliary 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 DIRECT, STOREVINTEGER K, LDT, LDV, N* ..* .. Array Arguments ..DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )* ..** Purpose* =======** DLARFT 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** 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)* = '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* = '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* ===============** 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 = ( 1 ) V = ( 1 v1 v1 v1 v1 )* ( v1 1 ) ( 1 v2 v2 v2 )* ( v1 v2 1 ) ( 1 v3 v3 )* ( v1 v2 v3 )* ( v1 v2 v3 )** DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':** V = ( v1 v2 v3 ) V = ( v1 v1 1 )* ( v1 v2 v3 ) ( v2 v2 v2 1 )* ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )* ( 1 v3 )* ( 1 )** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION VII* ..* .. External Subroutines ..EXTERNAL DGEMV, DTRMV* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( LSAME( DIRECT, 'F' ) ) THENDO 20 I = 1, KIF( TAU( I ).EQ.ZERO ) THEN** H(i) = I*DO 10 J = 1, IT( J, I ) = ZERO10 CONTINUEELSE** general case*VII = V( I, I )V( I, I ) = ONEIF( LSAME( STOREV, 'C' ) ) THEN** T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i)*CALL DGEMV( 'Transpose', N-I+1, I-1, -TAU( I ),$ V( I, 1 ), LDV, V( I, I ), 1, ZERO,$ T( 1, I ), 1 )ELSE** T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)'*CALL DGEMV( 'No transpose', I-1, N-I+1, -TAU( I ),$ V( 1, I ), LDV, V( I, I ), LDV, ZERO,$ T( 1, I ), 1 )END IFV( I, I ) = VII** T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)*CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,$ LDT, T( 1, I ), 1 )T( I, I ) = TAU( I )END IF20 CONTINUEELSEDO 40 I = K, 1, -1IF( TAU( I ).EQ.ZERO ) THEN** H(i) = I*DO 30 J = I, KT( J, I ) = ZERO30 CONTINUEELSE** general case*IF( I.LT.K ) THENIF( LSAME( STOREV, 'C' ) ) THENVII = V( N-K+I, I )V( N-K+I, I ) = ONE** T(i+1:k,i) :=* - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i)*CALL DGEMV( 'Transpose', N-K+I, K-I, -TAU( I ),$ V( 1, I+1 ), LDV, V( 1, I ), 1, ZERO,$ T( I+1, I ), 1 )V( N-K+I, I ) = VIIELSEVII = V( I, N-K+I )V( I, N-K+I ) = ONE** T(i+1:k,i) :=* - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)'*CALL DGEMV( 'No transpose', K-I, N-K+I, -TAU( I ),$ V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,$ T( I+1, I ), 1 )V( I, N-K+I ) = VIIEND IF** 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 IF40 CONTINUEEND IFRETURN** End of DLARFT*ENDSUBROUTINE DLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )** -- LAPACK auxiliary 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 LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..** Purpose* =======** DLARFX 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** This version uses inline code if H has order < 11.** 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.** V (input) DOUBLE PRECISION array, dimension (M) if SIDE = 'L'* or (N) if SIDE = 'R'* The vector v in the representation of H.** 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. LDA >= (1,M).** WORK (workspace) DOUBLE PRECISION array, dimension* (N) if SIDE = 'L'* or (M) if SIDE = 'R'* WORK is not referenced if H has order < 11.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER JDOUBLE PRECISION SUM, T1, T10, T2, T3, T4, T5, T6, T7, T8, T9,$ V1, V10, V2, V3, V4, V5, V6, V7, V8, V9* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER* ..* .. Executable Statements ..*IF( TAU.EQ.ZERO )$ RETURNIF( LSAME( SIDE, 'L' ) ) THEN** Form H * C, where H has order m.*GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,$ 170, 190 )M** Code for general M** w := C'*v*CALL DGEMV( 'Transpose', M, N, ONE, C, LDC, V, 1, ZERO, WORK,$ 1 )** C := C - tau * v * w'*CALL DGER( M, N, -TAU, V, 1, WORK, 1, C, LDC )GO TO 41010 CONTINUE** Special code for 1 x 1 Householder*T1 = ONE - TAU*V( 1 )*V( 1 )DO 20 J = 1, NC( 1, J ) = T1*C( 1, J )20 CONTINUEGO TO 41030 CONTINUE** Special code for 2 x 2 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2DO 40 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T240 CONTINUEGO TO 41050 CONTINUE** Special code for 3 x 3 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3DO 60 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T360 CONTINUEGO TO 41070 CONTINUE** Special code for 4 x 4 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4DO 80 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T480 CONTINUEGO TO 41090 CONTINUE** Special code for 5 x 5 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5DO 100 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5100 CONTINUEGO TO 410110 CONTINUE** Special code for 6 x 6 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6DO 120 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6120 CONTINUEGO TO 410130 CONTINUE** Special code for 7 x 7 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7DO 140 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7140 CONTINUEGO TO 410150 CONTINUE** Special code for 8 x 8 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8DO 160 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J ) + V8*C( 8, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7C( 8, J ) = C( 8, J ) - SUM*T8160 CONTINUEGO TO 410170 CONTINUE** Special code for 9 x 9 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9DO 180 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7C( 8, J ) = C( 8, J ) - SUM*T8C( 9, J ) = C( 9, J ) - SUM*T9180 CONTINUEGO TO 410190 CONTINUE** Special code for 10 x 10 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9V10 = V( 10 )T10 = TAU*V10DO 200 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J ) +$ V10*C( 10, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7C( 8, J ) = C( 8, J ) - SUM*T8C( 9, J ) = C( 9, J ) - SUM*T9C( 10, J ) = C( 10, J ) - SUM*T10200 CONTINUEGO TO 410ELSE** Form C * H, where H has order n.*GO TO ( 210, 230, 250, 270, 290, 310, 330, 350,$ 370, 390 )N** Code for general N** w := C * v*CALL DGEMV( 'No transpose', M, N, ONE, C, LDC, V, 1, ZERO,$ WORK, 1 )** C := C - tau * w * v'*CALL DGER( M, N, -TAU, WORK, 1, V, 1, C, LDC )GO TO 410210 CONTINUE** Special code for 1 x 1 Householder*T1 = ONE - TAU*V( 1 )*V( 1 )DO 220 J = 1, MC( J, 1 ) = T1*C( J, 1 )220 CONTINUEGO TO 410230 CONTINUE** Special code for 2 x 2 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2DO 240 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2240 CONTINUEGO TO 410250 CONTINUE** Special code for 3 x 3 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3DO 260 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3260 CONTINUEGO TO 410270 CONTINUE** Special code for 4 x 4 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4DO 280 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4280 CONTINUEGO TO 410290 CONTINUE** Special code for 5 x 5 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5DO 300 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5300 CONTINUEGO TO 410310 CONTINUE** Special code for 6 x 6 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6DO 320 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6320 CONTINUEGO TO 410330 CONTINUE** Special code for 7 x 7 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7DO 340 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7340 CONTINUEGO TO 410350 CONTINUE** Special code for 8 x 8 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8DO 360 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 ) + V8*C( J, 8 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7C( J, 8 ) = C( J, 8 ) - SUM*T8360 CONTINUEGO TO 410370 CONTINUE** Special code for 9 x 9 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9DO 380 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7C( J, 8 ) = C( J, 8 ) - SUM*T8C( J, 9 ) = C( J, 9 ) - SUM*T9380 CONTINUEGO TO 410390 CONTINUE** Special code for 10 x 10 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9V10 = V( 10 )T10 = TAU*V10DO 400 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 ) +$ V10*C( J, 10 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7C( J, 8 ) = C( J, 8 ) - SUM*T8C( J, 9 ) = C( J, 9 ) - SUM*T9C( J, 10 ) = C( J, 10 ) - SUM*T10400 CONTINUEGO TO 410END IF410 CONTINUERETURN** End of DLARFX*ENDSUBROUTINE DLARTG( F, G, CS, SN, R )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION CS, F, G, R, SN* ..** Purpose* =======** DLARTG generate a plane rotation so that** [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1.* [ -SN CS ] [ G ] [ 0 ]** This is a slower, more accurate version of the BLAS1 routine DROTG,* with the following other differences:* F and G are unchanged on return.* If G=0, then CS=1 and SN=0.* If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any* floating point operations (saves work in DBDSQR when* there are zeros on the diagonal).** If F exceeds G in magnitude, CS will be positive.** Arguments* =========** F (input) DOUBLE PRECISION* The first component of vector to be rotated.** G (input) DOUBLE PRECISION* The second component of vector to be rotated.** CS (output) DOUBLE PRECISION* The cosine of the rotation.** SN (output) DOUBLE PRECISION* The sine of the rotation.** R (output) DOUBLE PRECISION* The nonzero component of the rotated vector.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..LOGICAL FIRSTINTEGER COUNT, IDOUBLE PRECISION EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, SQRT* ..* .. Save statement ..SAVE FIRST, SAFMX2, SAFMIN, SAFMN2* ..* .. Data statements ..DATA FIRST / .TRUE. /* ..* .. Executable Statements ..*IF( FIRST ) THENFIRST = .FALSE.SAFMIN = DLAMCH( 'S' )EPS = DLAMCH( 'E' )SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /$ LOG( DLAMCH( 'B' ) ) / TWO )SAFMX2 = ONE / SAFMN2END IFIF( G.EQ.ZERO ) THENCS = ONESN = ZEROR = FELSE IF( F.EQ.ZERO ) THENCS = ZEROSN = ONER = GELSEF1 = FG1 = GSCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.GE.SAFMX2 ) THENCOUNT = 010 CONTINUECOUNT = COUNT + 1F1 = F1*SAFMN2G1 = G1*SAFMN2SCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.GE.SAFMX2 )$ GO TO 10R = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / RDO 20 I = 1, COUNTR = R*SAFMX220 CONTINUEELSE IF( SCALE.LE.SAFMN2 ) THENCOUNT = 030 CONTINUECOUNT = COUNT + 1F1 = F1*SAFMX2G1 = G1*SAFMX2SCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.LE.SAFMN2 )$ GO TO 30R = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / RDO 40 I = 1, COUNTR = R*SAFMN240 CONTINUEELSER = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / REND IFIF( ABS( F ).GT.ABS( G ) .AND. CS.LT.ZERO ) THENCS = -CSSN = -SNR = -REND IFEND IFRETURN** End of DLARTG*ENDSUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION F, G, H, SSMAX, SSMIN* ..** Purpose* =======** DLAS2 computes the singular values of the 2-by-2 matrix* [ F G ]* [ 0 H ].* On return, SSMIN is the smaller singular value and SSMAX is the* larger singular value.** Arguments* =========** F (input) DOUBLE PRECISION* The (1,1) element of the 2-by-2 matrix.** G (input) DOUBLE PRECISION* The (1,2) element of the 2-by-2 matrix.** H (input) DOUBLE PRECISION* The (2,2) element of the 2-by-2 matrix.** SSMIN (output) DOUBLE PRECISION* The smaller singular value.** SSMAX (output) DOUBLE PRECISION* The larger singular value.** Further Details* ===============** Barring over/underflow, all output quantities are correct to within* a few units in the last place (ulps), even in the absence of a guard* digit in addition/subtraction.** In IEEE arithmetic, the code works correctly if one matrix element is* infinite.** Overflow will not occur unless the largest singular value itself* overflows, or is within a few ulps of overflow. (On machines with* partial overflow, like the Cray, overflow may occur if the largest* singular value is within a factor of 2 of overflow.)** Underflow is harmless if underflow is gradual. Otherwise, results* may correspond to a matrix modified by perturbations of size near* the underflow threshold.** ====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION AS, AT, AU, C, FA, FHMN, FHMX, GA, HA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*FA = ABS( F )GA = ABS( G )HA = ABS( H )FHMN = MIN( FA, HA )FHMX = MAX( FA, HA )IF( FHMN.EQ.ZERO ) THENSSMIN = ZEROIF( FHMX.EQ.ZERO ) THENSSMAX = GAELSESSMAX = MAX( FHMX, GA )*SQRT( ONE+$ ( MIN( FHMX, GA ) / MAX( FHMX, GA ) )**2 )END IFELSEIF( GA.LT.FHMX ) THENAS = ONE + FHMN / FHMXAT = ( FHMX-FHMN ) / FHMXAU = ( GA / FHMX )**2C = TWO / ( SQRT( AS*AS+AU )+SQRT( AT*AT+AU ) )SSMIN = FHMN*CSSMAX = FHMX / CELSEAU = FHMX / GAIF( AU.EQ.ZERO ) THEN** Avoid possible harmful underflow if exponent range* asymmetric (true SSMIN may not underflow even if* AU underflows)*SSMIN = ( FHMN*FHMX ) / GASSMAX = GAELSEAS = ONE + FHMN / FHMXAT = ( FHMX-FHMN ) / FHMXC = ONE / ( SQRT( ONE+( AS*AU )**2 )+$ SQRT( ONE+( AT*AU )**2 ) )SSMIN = ( FHMN*C )*AUSSMIN = SSMIN + SSMINSSMAX = GA / ( C+C )END IFEND IFEND IFRETURN** End of DLAS2*ENDSUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )** -- LAPACK auxiliary 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 TYPEINTEGER INFO, KL, KU, LDA, M, NDOUBLE PRECISION CFROM, CTO* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** Purpose* =======** DLASCL multiplies the M by N real matrix A by the real scalar* CTO/CFROM. This is done without over/underflow as long as the final* result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that* A may be full, upper triangular, lower triangular, upper Hessenberg,* or banded.** Arguments* =========** TYPE (input) CHARACTER*1* TYPE indices the storage type of the input matrix.* = 'G': A is a full matrix.* = 'L': A is a lower triangular matrix.* = 'U': A is an upper triangular matrix.* = 'H': A is an upper Hessenberg matrix.* = 'B': A is a symmetric band matrix with lower bandwidth KL* and upper bandwidth KU and with the only the lower* half stored.* = 'Q': A is a symmetric band matrix with lower bandwidth KL* and upper bandwidth KU and with the only the upper* half stored.* = 'Z': A is a band matrix with lower bandwidth KL and upper* bandwidth KU.** KL (input) INTEGER* The lower bandwidth of A. Referenced only if TYPE = 'B',* 'Q' or 'Z'.** KU (input) INTEGER* The upper bandwidth of A. Referenced only if TYPE = 'B',* 'Q' or 'Z'.** CFROM (input) DOUBLE PRECISION* CTO (input) DOUBLE PRECISION* The matrix A is multiplied by CTO/CFROM. A(I,J) is computed* without over/underflow if the final result CTO*A(I,J)/CFROM* can be represented without over/underflow. CFROM must be* nonzero.** 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,M)* The matrix to be multiplied by CTO/CFROM. See TYPE for the* storage type.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** 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.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL DONEINTEGER I, ITYPE, J, K1, K2, K3, K4DOUBLE PRECISION BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM* ..* .. 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 = 0*IF( LSAME( TYPE, 'G' ) ) THENITYPE = 0ELSE IF( LSAME( TYPE, 'L' ) ) THENITYPE = 1ELSE IF( LSAME( TYPE, 'U' ) ) THENITYPE = 2ELSE IF( LSAME( TYPE, 'H' ) ) THENITYPE = 3ELSE IF( LSAME( TYPE, 'B' ) ) THENITYPE = 4ELSE IF( LSAME( TYPE, 'Q' ) ) THENITYPE = 5ELSE IF( LSAME( TYPE, 'Z' ) ) THENITYPE = 6ELSEITYPE = -1END IF*IF( ITYPE.EQ.-1 ) THENINFO = -1ELSE IF( CFROM.EQ.ZERO ) THENINFO = -4ELSE IF( M.LT.0 ) THENINFO = -6ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.$ ( ITYPE.EQ.5 .AND. N.NE.M ) ) THENINFO = -7ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THENINFO = -9ELSE IF( ITYPE.GE.4 ) THENIF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THENINFO = -2ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.$ ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )$ THENINFO = -3ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.$ ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.$ ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THENINFO = -9END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DLASCL', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. M.EQ.0 )$ RETURN** Get machine parameters*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUM*CFROMC = CFROMCTOC = CTO*10 CONTINUECFROM1 = CFROMC*SMLNUMCTO1 = CTOC / BIGNUMIF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THENMUL = SMLNUMDONE = .FALSE.CFROMC = CFROM1ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THENMUL = BIGNUMDONE = .FALSE.CTOC = CTO1ELSEMUL = CTOC / CFROMCDONE = .TRUE.END IF*IF( ITYPE.EQ.0 ) THEN** Full matrix*DO 30 J = 1, NDO 20 I = 1, MA( I, J ) = A( I, J )*MUL20 CONTINUE30 CONTINUE*ELSE IF( ITYPE.EQ.1 ) THEN** Lower triangular matrix*DO 50 J = 1, NDO 40 I = J, MA( I, J ) = A( I, J )*MUL40 CONTINUE50 CONTINUE*ELSE IF( ITYPE.EQ.2 ) THEN** Upper triangular matrix*DO 70 J = 1, NDO 60 I = 1, MIN( J, M )A( I, J ) = A( I, J )*MUL60 CONTINUE70 CONTINUE*ELSE IF( ITYPE.EQ.3 ) THEN** Upper Hessenberg matrix*DO 90 J = 1, NDO 80 I = 1, MIN( J+1, M )A( I, J ) = A( I, J )*MUL80 CONTINUE90 CONTINUE*ELSE IF( ITYPE.EQ.4 ) THEN** Lower half of a symmetric band matrix*K3 = KL + 1K4 = N + 1DO 110 J = 1, NDO 100 I = 1, MIN( K3, K4-J )A( I, J ) = A( I, J )*MUL100 CONTINUE110 CONTINUE*ELSE IF( ITYPE.EQ.5 ) THEN** Upper half of a symmetric band matrix*K1 = KU + 2K3 = KU + 1DO 130 J = 1, NDO 120 I = MAX( K1-J, 1 ), K3A( I, J ) = A( I, J )*MUL120 CONTINUE130 CONTINUE*ELSE IF( ITYPE.EQ.6 ) THEN** Band matrix*K1 = KL + KU + 2K2 = KL + 1K3 = 2*KL + KU + 1K4 = KL + KU + 1 + MDO 150 J = 1, NDO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )A( I, J ) = A( I, J )*MUL140 CONTINUE150 CONTINUE*END IF*IF( .NOT.DONE )$ GO TO 10*RETURN** End of DLASCL*ENDSUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA )** -- LAPACK auxiliary 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 ..CHARACTER UPLOINTEGER LDA, M, NDOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** Purpose* =======** DLASET initializes an m-by-n matrix A to BETA on the diagonal and* ALPHA on the offdiagonals.** Arguments* =========** UPLO (input) CHARACTER*1* Specifies the part of the matrix A to be set.* = 'U': Upper triangular part is set; the strictly lower* triangular part of A is not changed.* = 'L': Lower triangular part is set; the strictly upper* triangular part of A is not changed.* Otherwise: All of the matrix A is set.** 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.** ALPHA (input) DOUBLE PRECISION* The constant to which the offdiagonal elements are to be set.** BETA (input) DOUBLE PRECISION* The constant to which the diagonal elements are to be set.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On exit, the leading m-by-n submatrix of A is set as follows:** if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n,* if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n,* otherwise, A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j,** and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n).** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( LSAME( UPLO, 'U' ) ) THEN** Set the strictly upper triangular or trapezoidal part of the* array to ALPHA.*DO 20 J = 2, NDO 10 I = 1, MIN( J-1, M )A( I, J ) = ALPHA10 CONTINUE20 CONTINUE*ELSE IF( LSAME( UPLO, 'L' ) ) THEN** Set the strictly lower triangular or trapezoidal part of the* array to ALPHA.*DO 40 J = 1, MIN( M, N )DO 30 I = J + 1, MA( I, J ) = ALPHA30 CONTINUE40 CONTINUE*ELSE** Set the leading m-by-n submatrix to ALPHA.*DO 60 J = 1, NDO 50 I = 1, MA( I, J ) = ALPHA50 CONTINUE60 CONTINUEEND IF** Set the first min(M,N) diagonal elements to BETA.*DO 70 I = 1, MIN( M, N )A( I, I ) = BETA70 CONTINUE*RETURN** End of DLASET*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* June 30, 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* dqds", LAPACK technical report.** Note : DLASQ1 works only on machines which follow ieee-754* floating-point standard in their handling of infinities and NaNs.* Normal execution of DLASQ1 may create NaNs and infinities and hence* may abort due to a floating point exception in environments which* do not conform to the ieee standard.** 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, SFMIN, SIGMN, SIGMX* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAS2, DLASCL, 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 )GO TO 50END 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' )SFMIN = DLAMCH( 'Safe minimum' )SCALE = SQRT( EPS / SFMIN )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*50 CONTINUERETURN** End of DLASQ1*ENDSUBROUTINE DLASQ2( N, Z, INFO )** -- LAPACK auxiliary 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 ..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 works only on machines which follow ieee-754* floating-point standard in their handling of infinities and NaNs.* Normal execution of DLASQ2 may create NaNs and infinities and hence* may abort due to a floating point exception in environments which* do not conform to the ieee standard.** 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, Z( 2*N+2 ) holds the sum of the eigenvalues, 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, TEN, HNDRDPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0,$ TWO = 2.0D0, FOUR = 4.0D0, TEN = 10.0D0,$ HNDRD = 100.0D0 )* ..* .. Local Scalars ..INTEGER I0, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, K,$ N0, NBIG, NDIV, NFAIL, PP, SPLTDOUBLE PRECISION D, DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, E,$ EMAX, EMIN, EPS, EPS2, OLDEMN, QMAX, QMIN, S,$ SIGMA, T, TAU, TEMP, TRACE, ZMAX* ..* .. External Subroutines ..EXTERNAL DLASQ3, DLASQ5, DLASRT, XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments.* (in case DLASQ2 is not called by DLASQ1)*INFO = 0EPS = DLAMCH( 'Precision' )*TENEPS2 = EPS**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 )*EPS2 ) 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 )Z( 7 ) = ZEROZ( 8 ) = ZEROZ( 9 ) = ZERORETURNEND IF** Check for negative data and compute sums of q's and e's.*Z( 2*N ) = ZEROEMIN = Z( 2 )QMAX = ZEROD = ZEROE = ZERO*DO 10 K = 1, NIF( Z( K ).LT.ZERO ) THENINFO = -( 200+K )CALL XERBLA( 'DLASQ2', 2 )RETURNELSE IF( Z( N+K ).LT.ZERO ) THENINFO = -( 200+N+K )CALL XERBLA( 'DLASQ2', 2 )RETURNEND IFD = D + Z( K )E = E + Z( N+K )QMAX = MAX( QMAX, Z( K ) )10 CONTINUEZMAX = QMAXDO 20 K = 1, N - 1EMIN = MIN( EMIN, Z( N+K ) )ZMAX = MAX( ZMAX, Z( N+K ) )20 CONTINUE** Check for diagonality.*IF( E.EQ.ZERO ) THENCALL DLASRT( 'D', N, Z, IINFO )Z( 2*N-1 ) = DRETURNEND IF*TRACE = D + EI0 = 1N0 = N** Check for zero data.*IF( TRACE.EQ.ZERO ) THENZ( 2*N-1 ) = ZERORETURNEND IF** 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** 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*IF( EMIN.LE.EPS2*QMAX ) THEN** Li's reverse test.*D = Z( 4*N0+PP-3 )DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4IF( Z( I4-1 ).LE.EPS2*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, 4IF( Z( I4-1 ).LE.EPS2*D ) THENZ( I4-1 ) = -ZEROZ( I4-2*PP-2 ) = DZ( I4-2*PP ) = ZEROD = Z( I4+1 )EMIN = ZEROELSEZ( I4-2*PP-2 ) = D + Z( I4-1 )Z( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) /$ Z( I4-2*PP-2 ) )D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) )EMIN = MIN( EMIN, Z( I4-2*PP ) )END IF60 CONTINUEZ( 4*N0-PP-2 ) = DELSETAU = ZEROCALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,$ DN1, DN2 )*EMIN = Z( 4*N0 )END IF** 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 )*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.EPS2*QMAX .OR. Z( 4*N0-1 ).LE.EPS2*$ 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.EPS2*Z( I4-3 ) .OR. Z( I4-1 ).LE.$ EPS2*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 ) = HNDRD*NFAIL / DBLE( ITER )RETURN** End of DLASQ2*ENDSUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,$ ITER, NDIV )** -- LAPACK auxiliary 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 I0, ITER, N0, NDIV, NFAIL, PPDOUBLE PRECISION DESIG, DMIN, QMAX, SIGMA* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** Purpose* =======* DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.* In case of failure it changes shifts, and tries again until output* is positive.** Arguments* =========** I0 (input) INTEGER* First index.** N0 (input) INTEGER* Last index.** Z (input) DOUBLE PRECISION array, dimension ( 4*N )* Z holds the qd array.** PP (input) INTEGER* PP=0 for ping, PP=1 for pong.** DMIN (output) DOUBLE PRECISION* Minimum value of d.** SIGMA (output) DOUBLE PRECISION* Sum of shifts used in current segment.** DESIG (input/output) DOUBLE PRECISION* Lower order part of SIGMA** QMAX (input) DOUBLE PRECISION* Maximum value of q.** NFAIL (output) INTEGER* Number of times shift was too big.** ITER (output) INTEGER* Number of iterations.** NDIV (output) INTEGER* Number of divisions.** TTYPE (output) INTEGER* Shift type.** =====================================================================** .. Parameters ..DOUBLE PRECISION CBIASPARAMETER ( CBIAS = 1.50D0 )DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, TENPARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,$ ONE = 1.0D0, TWO = 2.0D0, TEN = 10.0D0 )* ..* .. Local Scalars ..INTEGER IPN4, J4, N0IN, NN, TTYPEDOUBLE PRECISION DMIN1, DMIN2, DN, DN1, DN2, EPS, EPS2, S,$ SFMIN, T, TAU, TEMP* ..* .. External Subroutines ..EXTERNAL DLASQ4, DLASQ5, DLASQ6* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Save statement ..SAVE TTYPE, DMIN1, DMIN2, DN, DN1, DN2, TAU* ..* .. Data statements ..DATA TTYPE / 0 /DATA DMIN1 / ZERO / , DMIN2 / ZERO / , DN / ZERO / ,$ DN1 / ZERO / , DN2 / ZERO / , TAU / ZERO /* ..* .. Executable Statements ..*N0IN = N0EPS = DLAMCH( 'Precision' )*TENSFMIN = DLAMCH( 'Safe minimum' )EPS2 = EPS**2** Check for deflation.*10 CONTINUE*IF( N0.LT.I0 )$ RETURNIF( N0.EQ.I0 )$ GO TO 20NN = 4*N0 + PPIF( N0.EQ.( I0+1 ) )$ GO TO 40** Check whether E(N0-1) is negligible, 1-by-1 case.*IF( Z( NN-5 ).GT.EPS2*( SIGMA+Z( NN-3 ) ) .AND. Z( NN-2*PP-4 ).GT.$ EPS2*Z( NN-7 ) )GO TO 30*20 CONTINUE*Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMAN0 = N0 - 1GO TO 10** Check whether E(N0-2) is negligible, 2-by-2 case.*30 CONTINUE*IF( Z( NN-9 ).GT.EPS2*SIGMA .AND. Z( NN-2*PP-8 ).GT.EPS2*$ Z( NN-11 ) )GO TO 50*40 CONTINUE*IF( Z( NN-3 ).GT.Z( NN-7 ) ) THENS = Z( NN-3 )Z( NN-3 ) = Z( NN-7 )Z( NN-7 ) = SEND IFIF( Z( NN-5 ).GT.Z( NN-3 )*EPS2 ) THENT = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )S = Z( NN-3 )*( Z( NN-5 ) / T )IF( S.LE.T ) THENS = Z( NN-3 )*( Z( NN-5 ) / ( T*( ONE+SQRT( ONE+S /$ T ) ) ) )ELSES = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )END IFT = Z( NN-7 ) + ( S+Z( NN-5 ) )Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )Z( NN-7 ) = TEND IFZ( 4*N0-7 ) = Z( NN-7 ) + SIGMAZ( 4*N0-3 ) = Z( NN-3 ) + SIGMAN0 = N0 - 2GO TO 10*50 CONTINUE** Reverse the qd-array, if warranted.*IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THENIF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THENIPN4 = 4*( I0+N0 )DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4TEMP = Z( J4-3 )Z( J4-3 ) = Z( IPN4-J4-3 )Z( IPN4-J4-3 ) = TEMPTEMP = Z( J4-2 )Z( J4-2 ) = Z( IPN4-J4-2 )Z( IPN4-J4-2 ) = TEMPTEMP = Z( J4-1 )Z( J4-1 ) = Z( IPN4-J4-5 )Z( IPN4-J4-5 ) = TEMPTEMP = Z( J4 )Z( J4 ) = Z( IPN4-J4-4 )Z( IPN4-J4-4 ) = TEMP60 CONTINUEIF( N0-I0.LE.4 ) THENZ( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )Z( 4*N0-PP ) = Z( 4*I0-PP )END IFDMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),$ Z( 4*I0+PP+3 ) )Z( 4*I0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),$ Z( 4*I0-PP+4 ) )QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )DMIN = -ZEROEND IFEND IF*70 CONTINUE*IF( DMIN.LT.ZERO .OR. SFMIN*QMAX.LE.$ MIN( Z( 4*N0+PP-1 ), Z( 4*N0+PP-9 ), DMIN2+Z( 4*N0-PP ) ) )$ THEN** Choose a shift.*CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,$ DN2, TAU, TTYPE )** Call dqds until DMIN > 0.*80 CONTINUE*CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN, DN1,$ DN2 )*ITER = ITER + 1NDIV = NDIV + ( N0-I0+2 )** Check for NaN: "DMIN.NE.DMIN"*IF( DMIN.NE.DMIN ) THENZ( 4*N0+PP-1 ) = ZEROTAU = ZEROGO TO 70END IF** Check for convergence hidden by negative DN.*IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.$ Z( 4*( N0-1 )-PP ).LT.EPS*( SIGMA+DN1 ) .AND. ABS( DN ).LT.$ EPS*SIGMA ) THENZ( 4*( N0-1 )-PP+2 ) = ZERODMIN = ABS( DMIN )END IF*IF( DMIN.LT.ZERO ) THEN** Failure. Select new TAU and try again.*NFAIL = NFAIL + 1** Failed twice. Play it safe.*IF( TTYPE.LT.-22 ) THENTAU = ZEROGO TO 80END IF*IF( DMIN1.GT.ZERO ) THEN** Late failure. Gives excellent shift.*TAU = ( TAU+DMIN )*( ONE-TWO*EPS )TTYPE = TTYPE - 11ELSE** Early failure. Divide by 4.*TAU = QURTR*TAUTTYPE = TTYPE - 12END IFGO TO 80END IFELSECALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )ITER = ITER + 1NDIV = NDIV + ( N0-I0 )TAU = ZEROEND IF*IF( TAU.LT.SIGMA ) THENDESIG = DESIG + TAUT = SIGMA + DESIGDESIG = DESIG - ( T-SIGMA )ELSET = SIGMA + TAUDESIG = SIGMA - ( T-TAU ) + DESIGEND IFSIGMA = T*RETURN** End of DLASQ3*ENDSUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,$ DN1, DN2, TAU, TTYPE )** -- LAPACK auxiliary 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 I0, N0, N0IN, PP, TTYPEDOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DN1, DN2, TAU* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** Purpose* =======* DLASQ4 computes an approximation TAU to the smallest eigenvalue* using values of d from the previous transform.** I0 (input) INTEGER* First index.** N0 (input) INTEGER* Last index.** Z (input) DOUBLE PRECISION array, dimension ( 4*N )* Z holds the qd array.** PP (input) INTEGER* PP=0 for ping, PP=1 for pong.** NOIN (input) INTEGER* The value of N0 at start of EIGTEST.** DMIN (input) DOUBLE PRECISION* Minimum value of d.** DMIN1 (input) DOUBLE PRECISION* Minimum value of d, excluding D( N0 ).** DMIN2 (input) DOUBLE PRECISION* Minimum value of d, excluding D( N0 ) and D( N0-1 ).** DN (input) DOUBLE PRECISION* d(N)** DN1 (input) DOUBLE PRECISION* d(N-1)** DN2 (input) DOUBLE PRECISION* d(N-2)** TAU (output) DOUBLE PRECISION* This is the shift.** TTYPE (output) INTEGER* Shift type.** Further Details* ===============* CNST1 = 9/16** =====================================================================** .. Parameters ..DOUBLE PRECISION CNST1, CNST2, CNST3PARAMETER ( CNST1 = 0.5630D0, CNST2 = 1.010D0,$ CNST3 = 1.050D0 )DOUBLE PRECISION QURTR, THIRD, HALF, ZERO, ONE, TWO, HNDRDPARAMETER ( QURTR = 0.250D0, THIRD = 0.3330D0,$ HALF = 0.50D0, ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, HNDRD = 100.0D0 )* ..* .. Local Scalars ..INTEGER I4, NN, NPDOUBLE PRECISION A2, B1, B2, G, GAM, GAP1, GAP2, S* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Save statement ..SAVE G* ..* .. Data statements ..DATA G / ZERO /* ..* .. Executable Statements ..** A negative DMIN forces the shift to take that absolute value* TTYPE records the type of shift.*IF( DMIN.LE.ZERO ) THENTAU = -DMINTTYPE = -1RETURNEND IF*NN = 4*N0 + PPIF( N0IN.EQ.N0 ) THEN** No eigenvalues deflated.*IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN*B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )A2 = Z( NN-7 ) + Z( NN-5 )** Cases 2 and 3.*IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THENGAP2 = DMIN2 - A2 - DMIN2*QURTRIF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THENGAP1 = A2 - DN - ( B2 / GAP2 )*B2ELSEGAP1 = A2 - DN - ( B1+B2 )END IFIF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THENS = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )TTYPE = -2ELSES = ZEROIF( DN.GT.B1 )$ S = DN - B1IF( A2.GT.( B1+B2 ) )$ S = MIN( S, A2-( B1+B2 ) )S = MAX( S, THIRD*DMIN )TTYPE = -3END IFELSE** Case 4.*IF( DMIN.EQ.DN ) THENGAM = DNA2 = ZEROB2 = Z( NN-5 ) / Z( NN-7 )NP = NN - 9ELSENP = NN - 2*PPB2 = Z( NP-2 )GAM = DN1A2 = Z( NP-4 ) / Z( NP-2 )B2 = Z( NN-9 ) / Z( NN-11 )NP = NN - 13END IF** Approximate contribution to norm squared from I < NN-1.*IF( B2.EQ.ZERO )$ GO TO 20A2 = A2 + B2DO 10 I4 = NP, 4*I0 - 1 + PP, -4B1 = B2B2 = B2*( Z( I4 ) / Z( I4-2 ) )A2 = A2 + B2IF( HNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 )$ GO TO 2010 CONTINUE20 CONTINUEA2 = CNST3*A2** Rayleigh quotient residual bound.*IF( A2.LT.CNST1 ) THENS = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )ELSES = QURTR*GAMEND IFTTYPE = -4END IFELSE IF( DMIN.EQ.DN2 ) THEN** Case 5.** Compute contribution to norm squared from I > NN-2.*NP = NN - 2*PPB1 = Z( NP-2 )B2 = Z( NP-6 )GAM = DN2A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )** Approximate contribution to norm squared from I < NN-2.*IF( N0-I0.GT.2 ) THENB2 = Z( NN-13 ) / Z( NN-15 )IF( B2.EQ.ZERO )$ GO TO 40A2 = A2 + B2DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4B1 = B2B2 = B2*( Z( I4 ) / Z( I4-2 ) )A2 = A2 + B2IF( HNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 )$ GO TO 4030 CONTINUE40 CONTINUEA2 = CNST3*A2END IF*IF( A2.LT.CNST1 ) THENS = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )ELSES = QURTR*GAM / ( ONE+A2 )END IFTTYPE = -5ELSE** Case 6, no information to guide us.*IF( TTYPE.EQ.-6 ) THENG = G + THIRD*( ONE-G )ELSE IF( TTYPE.EQ.-18 ) THENG = QURTR*THIRDELSEG = QURTREND IFS = G*DMINTTYPE = -6END IF*ELSE IF( N0IN.EQ.( N0+1 ) ) THEN** One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.*IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN** Cases 7 and 8.*B1 = Z( NN-5 ) / Z( NN-7 )B2 = B1IF( B2.EQ.ZERO )$ GO TO 60DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4A2 = B1B1 = B1*( Z( I4 ) / Z( I4-2 ) )B2 = B2 + B1IF( HNDRD*MAX( B1, A2 ).LT.B2 )$ GO TO 6050 CONTINUE60 CONTINUEB2 = SQRT( CNST3*B2 )A2 = DMIN1 / ( ONE+B2**2 )GAP2 = HALF*DMIN2 - A2IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THENS = MAX( A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ),$ THIRD*DMIN1 )TTYPE = -7ELSES = MAX( A2*( ONE-CNST2*B2 ), THIRD*DMIN1 )TTYPE = -8END IFELSE** Case 9.*S = QURTR*DMIN1IF( DMIN1.EQ.DN1 )$ S = HALF*DMIN1TTYPE = -9END IF*ELSE IF( N0IN.EQ.( N0+2 ) ) THEN** Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.** Cases 10 and 11.*IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THENB1 = Z( NN-5 ) / Z( NN-7 )B2 = B1IF( B2.EQ.ZERO )$ GO TO 80DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4B1 = B1*( Z( I4 ) / Z( I4-2 ) )B2 = B2 + B1IF( HNDRD*B1.LT.B2 )$ GO TO 8070 CONTINUE80 CONTINUEB2 = SQRT( CNST3*B2 )A2 = DMIN2 / ( ONE+B2**2 )GAP2 = Z( NN-7 ) + Z( NN-9 ) -$ SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THENS = MAX( A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ),$ THIRD*DMIN2 )ELSES = MAX( A2*( ONE-CNST2*B2 ), THIRD*DMIN2 )END IFTTYPE = -10ELSES = QURTR*DMIN2TTYPE = -11END IFELSE IF( N0IN.GT.( N0+2 ) ) THEN** Case 12, more than two eigenvalues deflated. No information.*S = ZEROTTYPE = -12END IF*TAU = SRETURN** End of DLASQ4*ENDSUBROUTINE DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,$ DNM1, DNM2 )** -- LAPACK auxiliary 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 I0, N0, PPDOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** Purpose* =======* DLASQ5 computes one dqds transform in ping-pong form.** Arguments* =========** I0 (input) INTEGER* First index.** N0 (input) INTEGER* Last index.** Z (input) DOUBLE PRECISION array, dimension ( 4*N )* Z holds the qd array. EMIN is stored in Z(4*N0) to avoid* an extra argument.** PP (input) INTEGER* PP=0 for ping, PP=1 for pong.** TAU (input) DOUBLE PRECISION* This is the shift.** DMIN (output) DOUBLE PRECISION* Minimum value of d.** DMIN1 (output) DOUBLE PRECISION* Minimum value of d, excluding D( N0 ).** DMIN2 (output) DOUBLE PRECISION* Minimum value of d, excluding D( N0 ) and D( N0-1 ).** DN (output) DOUBLE PRECISION* d(N0), the last value of d.** DNM1 (output) DOUBLE PRECISION* d(N0-1).** DNM2 (output) DOUBLE PRECISION* d(N0-2).** =====================================================================** .. Local Scalars ..INTEGER J4, J4P2DOUBLE PRECISION D, EMIN, TEMP* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( ( N0-I0-1 ).LE.0 )$ RETURN*J4 = 4*I0 + PP - 3EMIN = Z( J4+4 )D = Z( J4 ) - TAUDMIN = D*IF( PP.EQ.0 ) THENDO 10 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-2 ) = D + Z( J4-1 )TEMP = Z( J4+1 ) / Z( J4-2 )D = D*TEMP - TAUDMIN = MIN( DMIN, D )Z( J4 ) = Z( J4-1 )*TEMPEMIN = MIN( Z( J4 ), EMIN )10 CONTINUEELSEDO 20 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-3 ) = D + Z( J4 )TEMP = Z( J4+2 ) / Z( J4-3 )D = D*TEMP - TAUDMIN = MIN( DMIN, D )Z( J4-1 ) = Z( J4 )*TEMPEMIN = MIN( Z( J4-1 ), EMIN )20 CONTINUEEND IF** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAUDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAUDMIN = MIN( DMIN, DN )*Z( J4+2 ) = DNZ( 4*N0-PP ) = EMINRETURN** End of DLASQ5*ENDSUBROUTINE DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DNM1,$ DNM2 )** -- LAPACK auxiliary 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 I0, N0, PPDOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** Purpose* =======* DLASQ6 computes one dqds transform in ping-pong form.** Arguments* =========** I0 (input) INTEGER* First index.** N0 (input) INTEGER* Last index.** Z (input) DOUBLE PRECISION array, dimension ( 4*N )* Z holds the qd array. EMIN is stored in Z(4*N0) to avoid* an extra argument.** PP (input) INTEGER* PP=0 for ping, PP=1 for pong.** DMIN (output) DOUBLE PRECISION* Minimum value of d.** DMIN1 (output) DOUBLE PRECISION* Minimum value of d, excluding D( N0 ).** DMIN2 (output) DOUBLE PRECISION* Minimum value of d, excluding D( N0 ) and D( N0-1 ).** DN (output) DOUBLE PRECISION* d(N0), the last value of d.** DNM1 (output) DOUBLE PRECISION* d(N0-1).** DNM2 (output) DOUBLE PRECISION* d(N0-2).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER J4, J4P2DOUBLE PRECISION D, EMIN, SFMIN, TEMP* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( ( N0-I0-1 ).LE.0 )$ RETURN*SFMIN = DLAMCH( 'Safe minimum' )J4 = 4*I0 + PP - 3EMIN = Z( J4+4 )D = Z( J4 )DMIN = D*DO 10 J4 = 4*I0 - PP, 4*( N0-3 ) - PP, 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = D + Z( J4P2 )IF( Z( J4-2 ).EQ.ZERO ) THENZ( J4 ) = ZEROD = Z( J4P2+2 )DMIN = DEMIN = ZEROELSE IF( SFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) ) THENTEMP = Z( J4P2+2 ) / Z( J4-2 )Z( J4 ) = Z( J4P2 )*TEMPD = D*TEMPELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )D = Z( J4P2+2 )*( D / Z( J4-2 ) )END IFDMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4 ) )10 CONTINUE** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )IF( Z( J4-2 ).EQ.ZERO ) THENZ( J4 ) = ZERODNM1 = Z( J4P2+2 )DMIN = DNM1EMIN = ZEROELSE IF( SFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) ) THENTEMP = Z( J4P2+2 ) / Z( J4-2 )Z( J4 ) = Z( J4P2 )*TEMPDNM1 = DNM2*TEMPELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) )END IFDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )IF( Z( J4-2 ).EQ.ZERO ) THENZ( J4 ) = ZERODN = Z( J4P2+2 )DMIN = DNEMIN = ZEROELSE IF( SFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) ) THENTEMP = Z( J4P2+2 ) / Z( J4-2 )Z( J4 ) = Z( J4P2 )*TEMPDN = DNM1*TEMPELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) )END IFDMIN = MIN( DMIN, DN )*Z( J4+2 ) = DNZ( 4*N0-PP ) = EMINRETURN** End of DLASQ6*ENDSUBROUTINE DLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )** -- LAPACK auxiliary 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 ..CHARACTER DIRECT, PIVOT, SIDEINTEGER LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * ), S( * )* ..** Purpose* =======** DLASR performs the transformation** A := P*A, when SIDE = 'L' or 'l' ( Left-hand side )** A := A*P', when SIDE = 'R' or 'r' ( Right-hand side )** where A is an m by n real matrix and P is an orthogonal matrix,* consisting of a sequence of plane rotations determined by the* parameters PIVOT and DIRECT as follows ( z = m when SIDE = 'L' or 'l'* and z = n when SIDE = 'R' or 'r' ):** When DIRECT = 'F' or 'f' ( Forward sequence ) then** P = P( z - 1 )*...*P( 2 )*P( 1 ),** and when DIRECT = 'B' or 'b' ( Backward sequence ) then** P = P( 1 )*P( 2 )*...*P( z - 1 ),** where P( k ) is a plane rotation matrix for the following planes:** when PIVOT = 'V' or 'v' ( Variable pivot ),* the plane ( k, k + 1 )** when PIVOT = 'T' or 't' ( Top pivot ),* the plane ( 1, k + 1 )** when PIVOT = 'B' or 'b' ( Bottom pivot ),* the plane ( k, z )** c( k ) and s( k ) must contain the cosine and sine that define the* matrix P( k ). The two by two plane rotation part of the matrix* P( k ), R( k ), is assumed to be of the form** R( k ) = ( c( k ) s( k ) ).* ( -s( k ) c( k ) )** This version vectorises across rows of the array A when SIDE = 'L'.** Arguments* =========** SIDE (input) CHARACTER*1* Specifies whether the plane rotation matrix P is applied to* A on the left or the right.* = 'L': Left, compute A := P*A* = 'R': Right, compute A:= A*P'** DIRECT (input) CHARACTER*1* Specifies whether P is a forward or backward sequence of* plane rotations.* = 'F': Forward, P = P( z - 1 )*...*P( 2 )*P( 1 )* = 'B': Backward, P = P( 1 )*P( 2 )*...*P( z - 1 )** PIVOT (input) CHARACTER*1* Specifies the plane for which P(k) is a plane rotation* matrix.* = 'V': Variable pivot, the plane (k,k+1)* = 'T': Top pivot, the plane (1,k+1)* = 'B': Bottom pivot, the plane (k,z)** M (input) INTEGER* The number of rows of the matrix A. If m <= 1, an immediate* return is effected.** N (input) INTEGER* The number of columns of the matrix A. If n <= 1, an* immediate return is effected.** C, S (input) DOUBLE PRECISION arrays, dimension* (M-1) if SIDE = 'L'* (N-1) if SIDE = 'R'* c(k) and s(k) contain the cosine and sine that define the* matrix P(k). The two by two plane rotation part of the* matrix P(k), R(k), is assumed to be of the form* R( k ) = ( c( k ) s( k ) ).* ( -s( k ) c( k ) )** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* The m by n matrix A. On exit, A is overwritten by P*A if* SIDE = 'R' or by A*P' if SIDE = 'L'.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, INFO, JDOUBLE PRECISION CTEMP, STEMP, TEMP* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THENINFO = 1ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT,$ 'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THENINFO = 2ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) )$ THENINFO = 3ELSE IF( M.LT.0 ) THENINFO = 4ELSE IF( N.LT.0 ) THENINFO = 5ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = 9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASR ', INFO )RETURNEND IF** Quick return if possible*IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )$ RETURNIF( LSAME( SIDE, 'L' ) ) THEN** Form P * A*IF( LSAME( PIVOT, 'V' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 20 J = 1, M - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 10 I = 1, NTEMP = A( J+1, I )A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )10 CONTINUEEND IF20 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 40 J = M - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 30 I = 1, NTEMP = A( J+1, I )A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )30 CONTINUEEND IF40 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'T' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 60 J = 2, MCTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 50 I = 1, NTEMP = A( J, I )A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )50 CONTINUEEND IF60 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 80 J = M, 2, -1CTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 70 I = 1, NTEMP = A( J, I )A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )70 CONTINUEEND IF80 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'B' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 100 J = 1, M - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 90 I = 1, NTEMP = A( J, I )A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMPA( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP90 CONTINUEEND IF100 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 120 J = M - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 110 I = 1, NTEMP = A( J, I )A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMPA( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP110 CONTINUEEND IF120 CONTINUEEND IFEND IFELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form A * P'*IF( LSAME( PIVOT, 'V' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 140 J = 1, N - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 130 I = 1, MTEMP = A( I, J+1 )A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )130 CONTINUEEND IF140 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 160 J = N - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 150 I = 1, MTEMP = A( I, J+1 )A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )150 CONTINUEEND IF160 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'T' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 180 J = 2, NCTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 170 I = 1, MTEMP = A( I, J )A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )170 CONTINUEEND IF180 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 200 J = N, 2, -1CTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 190 I = 1, MTEMP = A( I, J )A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )190 CONTINUEEND IF200 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'B' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 220 J = 1, N - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 210 I = 1, MTEMP = A( I, J )A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMPA( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP210 CONTINUEEND IF220 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 240 J = N - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 230 I = 1, MTEMP = A( I, J )A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMPA( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP230 CONTINUEEND IF240 CONTINUEEND IFEND IFEND IF*RETURN** End of DLASR*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 DLASSQ( N, X, INCX, SCALE, SUMSQ )** -- LAPACK auxiliary 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 INCX, NDOUBLE PRECISION SCALE, SUMSQ* ..* .. Array Arguments ..DOUBLE PRECISION X( * )* ..** Purpose* =======** DLASSQ returns the values scl and smsq such that** ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,** where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is* assumed to be non-negative and scl returns the value** scl = max( scale, abs( x( i ) ) ).** scale and sumsq must be supplied in SCALE and SUMSQ and* scl and smsq are overwritten on SCALE and SUMSQ respectively.** The routine makes only one pass through the vector x.** Arguments* =========** N (input) INTEGER* The number of elements to be used from the vector X.** X (input) DOUBLE PRECISION array, dimension (N)* The vector for which a scaled sum of squares is computed.* x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.** INCX (input) INTEGER* The increment between successive values of the vector X.* INCX > 0.** SCALE (input/output) DOUBLE PRECISION* On entry, the value scale in the equation above.* On exit, SCALE is overwritten with scl , the scaling factor* for the sum of squares.** SUMSQ (input/output) DOUBLE PRECISION* On entry, the value sumsq in the equation above.* On exit, SUMSQ is overwritten with smsq , the basic sum of* squares from which scl has been factored out.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IXDOUBLE PRECISION ABSXI* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*IF( N.GT.0 ) THENDO 10 IX = 1, 1 + ( N-1 )*INCX, INCXIF( X( IX ).NE.ZERO ) THENABSXI = ABS( X( IX ) )IF( SCALE.LT.ABSXI ) THENSUMSQ = 1 + SUMSQ*( SCALE / ABSXI )**2SCALE = ABSXIELSESUMSQ = SUMSQ + ( ABSXI / SCALE )**2END IFEND IF10 CONTINUEEND IFRETURN** End of DLASSQ*ENDSUBROUTINE DLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL )** -- LAPACK auxiliary 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 ..DOUBLE PRECISION CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN* ..** Purpose* =======** DLASV2 computes the singular value decomposition of a 2-by-2* triangular matrix* [ F G ]* [ 0 H ].* On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the* smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and* right singular vectors for abs(SSMAX), giving the decomposition** [ CSL SNL ] [ F G ] [ CSR -SNR ] = [ SSMAX 0 ]* [-SNL CSL ] [ 0 H ] [ SNR CSR ] [ 0 SSMIN ].** Arguments* =========** F (input) DOUBLE PRECISION* The (1,1) element of the 2-by-2 matrix.** G (input) DOUBLE PRECISION* The (1,2) element of the 2-by-2 matrix.** H (input) DOUBLE PRECISION* The (2,2) element of the 2-by-2 matrix.** SSMIN (output) DOUBLE PRECISION* abs(SSMIN) is the smaller singular value.** SSMAX (output) DOUBLE PRECISION* abs(SSMAX) is the larger singular value.** SNL (output) DOUBLE PRECISION* CSL (output) DOUBLE PRECISION* The vector (CSL, SNL) is a unit left singular vector for the* singular value abs(SSMAX).** SNR (output) DOUBLE PRECISION* CSR (output) DOUBLE PRECISION* The vector (CSR, SNR) is a unit right singular vector for the* singular value abs(SSMAX).** Further Details* ===============** Any input parameter may be aliased with any output parameter.** Barring over/underflow and assuming a guard digit in subtraction, all* output quantities are correct to within a few units in the last* place (ulps).** In IEEE arithmetic, the code works correctly if one matrix element is* infinite.** Overflow will not occur unless the largest singular value itself* overflows or is within a few ulps of overflow. (On machines with* partial overflow, like the Cray, overflow may occur if the largest* singular value is within a factor of 2 of overflow.)** Underflow is harmless if underflow is gradual. Otherwise, results* may correspond to a matrix modified by perturbations of size near* the underflow threshold.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )DOUBLE PRECISION FOURPARAMETER ( FOUR = 4.0D0 )* ..* .. Local Scalars ..LOGICAL GASMAL, SWAPINTEGER PMAXDOUBLE PRECISION A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M,$ MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN, SQRT* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Executable Statements ..*FT = FFA = ABS( FT )HT = HHA = ABS( H )** PMAX points to the maximum absolute element of matrix* PMAX = 1 if F largest in absolute values* PMAX = 2 if G largest in absolute values* PMAX = 3 if H largest in absolute values*PMAX = 1SWAP = ( HA.GT.FA )IF( SWAP ) THENPMAX = 3TEMP = FTFT = HTHT = TEMPTEMP = FAFA = HAHA = TEMP** Now FA .ge. HA*END IFGT = GGA = ABS( GT )IF( GA.EQ.ZERO ) THEN** Diagonal matrix*SSMIN = HASSMAX = FACLT = ONECRT = ONESLT = ZEROSRT = ZEROELSEGASMAL = .TRUE.IF( GA.GT.FA ) THENPMAX = 2IF( ( FA / GA ).LT.DLAMCH( 'EPS' ) ) THEN** Case of very large GA*GASMAL = .FALSE.SSMAX = GAIF( HA.GT.ONE ) THENSSMIN = FA / ( GA / HA )ELSESSMIN = ( FA / GA )*HAEND IFCLT = ONESLT = HT / GTSRT = ONECRT = FT / GTEND IFEND IFIF( GASMAL ) THEN** Normal case*D = FA - HAIF( D.EQ.FA ) THEN** Copes with infinite F or H*L = ONEELSEL = D / FAEND IF** Note that 0 .le. L .le. 1*M = GT / FT** Note that abs(M) .le. 1/macheps*T = TWO - L** Note that T .ge. 1*MM = M*MTT = T*TS = SQRT( TT+MM )** Note that 1 .le. S .le. 1 + 1/macheps*IF( L.EQ.ZERO ) THENR = ABS( M )ELSER = SQRT( L*L+MM )END IF** Note that 0 .le. R .le. 1 + 1/macheps*A = HALF*( S+R )** Note that 1 .le. A .le. 1 + abs(M)*SSMIN = HA / ASSMAX = FA*AIF( MM.EQ.ZERO ) THEN** Note that M is very tiny*IF( L.EQ.ZERO ) THENT = SIGN( TWO, FT )*SIGN( ONE, GT )ELSET = GT / SIGN( D, FT ) + M / TEND IFELSET = ( M / ( S+T )+M / ( R+L ) )*( ONE+A )END IFL = SQRT( T*T+FOUR )CRT = TWO / LSRT = T / LCLT = ( CRT+SRT*M ) / ASLT = ( HT / FT )*SRT / AEND IFEND IFIF( SWAP ) THENCSL = SRTSNL = CRTCSR = SLTSNR = CLTELSECSL = CLTSNL = SLTCSR = CRTSNR = SRTEND IF** Correct signs of SSMAX and SSMIN*IF( PMAX.EQ.1 )$ TSIGN = SIGN( ONE, CSR )*SIGN( ONE, CSL )*SIGN( ONE, F )IF( PMAX.EQ.2 )$ TSIGN = SIGN( ONE, SNR )*SIGN( ONE, CSL )*SIGN( ONE, G )IF( PMAX.EQ.3 )$ TSIGN = SIGN( ONE, SNR )*SIGN( ONE, SNL )*SIGN( ONE, H )SSMAX = SIGN( SSMAX, TSIGN )SSMIN = SIGN( SSMIN, TSIGN*SIGN( ONE, F )*SIGN( ONE, H ) )RETURN** End of DLASV2*ENDSUBROUTINE DLASWP( N, A, LDA, K1, K2, IPIV, INCX )** -- LAPACK auxiliary 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 INCX, K1, K2, LDA, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** Purpose* =======** DLASWP performs a series of row interchanges on the matrix A.* One row interchange is initiated for each of rows K1 through K2 of A.** Arguments* =========** N (input) INTEGER* The number of columns of the matrix A.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the matrix of column dimension N to which the row* interchanges will be applied.* On exit, the permuted matrix.** LDA (input) INTEGER* The leading dimension of the array A.** K1 (input) INTEGER* The first element of IPIV for which a row interchange will* be done.** K2 (input) INTEGER* The last element of IPIV for which a row interchange will* be done.** IPIV (input) INTEGER array, dimension (M*abs(INCX))* The vector of pivot indices. Only the elements in positions* K1 through K2 of IPIV are accessed.* IPIV(K) = L implies rows K and L are to be interchanged.** INCX (input) INTEGER* The increment between successive values of IPIV. If IPIV* is negative, the pivots are applied in reverse order.** Further Details* ===============** Modified by* R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA** =====================================================================** .. Local Scalars ..INTEGER I, I1, I2, INC, IP, IX, IX0, J, K, N32DOUBLE PRECISION TEMP* ..* .. Executable Statements ..** Interchange row I with row IPIV(I) for each of rows K1 through K2.*IF( INCX.GT.0 ) THENIX0 = K1I1 = K1I2 = K2INC = 1ELSE IF( INCX.LT.0 ) THENIX0 = 1 + ( 1-K2 )*INCXI1 = K2I2 = K1INC = -1ELSERETURNEND IF*N32 = ( N / 32 )*32IF( N32.NE.0 ) THENDO 30 J = 1, N32, 32IX = IX0DO 20 I = I1, I2, INCIP = IPIV( IX )IF( IP.NE.I ) THENDO 10 K = J, J + 31TEMP = A( I, K )A( I, K ) = A( IP, K )A( IP, K ) = TEMP10 CONTINUEEND IFIX = IX + INCX20 CONTINUE30 CONTINUEEND IFIF( N32.NE.N ) THENN32 = N32 + 1IX = IX0DO 50 I = I1, I2, INCIP = IPIV( IX )IF( IP.NE.I ) THENDO 40 K = N32, NTEMP = A( I, K )A( I, K ) = A( IP, K )A( IP, K ) = TEMP40 CONTINUEEND IFIX = IX + INCX50 CONTINUEEND IF*RETURN** End of DLASWP*ENDSUBROUTINE DLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,$ LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )** -- LAPACK auxiliary 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 ..LOGICAL LTRANL, LTRANRINTEGER INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2DOUBLE PRECISION SCALE, XNORM* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),$ X( LDX, * )* ..** Purpose* =======** DLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in** op(TL)*X + ISGN*X*op(TR) = SCALE*B,** where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or* -1. op(T) = T or T', where T' denotes the transpose of T.** Arguments* =========** LTRANL (input) LOGICAL* On entry, LTRANL specifies the op(TL):* = .FALSE., op(TL) = TL,* = .TRUE., op(TL) = TL'.** LTRANR (input) LOGICAL* On entry, LTRANR specifies the op(TR):* = .FALSE., op(TR) = TR,* = .TRUE., op(TR) = TR'.** ISGN (input) INTEGER* On entry, ISGN specifies the sign of the equation* as described before. ISGN may only be 1 or -1.** N1 (input) INTEGER* On entry, N1 specifies the order of matrix TL.* N1 may only be 0, 1 or 2.** N2 (input) INTEGER* On entry, N2 specifies the order of matrix TR.* N2 may only be 0, 1 or 2.** TL (input) DOUBLE PRECISION array, dimension (LDTL,2)* On entry, TL contains an N1 by N1 matrix.** LDTL (input) INTEGER* The leading dimension of the matrix TL. LDTL >= max(1,N1).** TR (input) DOUBLE PRECISION array, dimension (LDTR,2)* On entry, TR contains an N2 by N2 matrix.** LDTR (input) INTEGER* The leading dimension of the matrix TR. LDTR >= max(1,N2).** B (input) DOUBLE PRECISION array, dimension (LDB,2)* On entry, the N1 by N2 matrix B contains the right-hand* side of the equation.** LDB (input) INTEGER* The leading dimension of the matrix B. LDB >= max(1,N1).** SCALE (output) DOUBLE PRECISION* On exit, SCALE contains the scale factor. SCALE is chosen* less than or equal to 1 to prevent the solution overflowing.** X (output) DOUBLE PRECISION array, dimension (LDX,2)* On exit, X contains the N1 by N2 solution.** LDX (input) INTEGER* The leading dimension of the matrix X. LDX >= max(1,N1).** XNORM (output) DOUBLE PRECISION* On exit, XNORM is the infinity-norm of the solution.** INFO (output) INTEGER* On exit, INFO is set to* 0: successful exit.* 1: TL and TR have too close eigenvalues, so TL or* TR is perturbed to get a nonsingular equation.* NOTE: In the interests of speed, this routine does not* check the inputs for errors.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TWO, HALF, EIGHTPARAMETER ( TWO = 2.0D+0, HALF = 0.5D+0, EIGHT = 8.0D+0 )* ..* .. Local Scalars ..LOGICAL BSWAP, XSWAPINTEGER I, IP, IPIV, IPSV, J, JP, JPSV, KDOUBLE PRECISION BET, EPS, GAM, L21, SGN, SMIN, SMLNUM, TAU1,$ TEMP, U11, U12, U22, XMAX* ..* .. Local Arrays ..LOGICAL BSWPIV( 4 ), XSWPIV( 4 )INTEGER JPIV( 4 ), LOCL21( 4 ), LOCU12( 4 ),$ LOCU22( 4 )DOUBLE PRECISION BTMP( 4 ), T16( 4, 4 ), TMP( 4 ), X2( 2 )* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DCOPY, DSWAP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Data statements ..DATA LOCU12 / 3, 4, 1, 2 / , LOCL21 / 2, 1, 4, 3 / ,$ LOCU22 / 4, 3, 2, 1 /DATA XSWPIV / .FALSE., .FALSE., .TRUE., .TRUE. /DATA BSWPIV / .FALSE., .TRUE., .FALSE., .TRUE. /* ..* .. Executable Statements ..** Do not check the input parameters for errors*INFO = 0** Quick return if possible*IF( N1.EQ.0 .OR. N2.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSSGN = ISGN*K = N1 + N1 + N2 - 2GO TO ( 10, 20, 30, 50 )K** 1 by 1: TL11*X + SGN*X*TR11 = B11*10 CONTINUETAU1 = TL( 1, 1 ) + SGN*TR( 1, 1 )BET = ABS( TAU1 )IF( BET.LE.SMLNUM ) THENTAU1 = SMLNUMBET = SMLNUMINFO = 1END IF*SCALE = ONEGAM = ABS( B( 1, 1 ) )IF( SMLNUM*GAM.GT.BET )$ SCALE = ONE / GAM*X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / TAU1XNORM = ABS( X( 1, 1 ) )RETURN** 1 by 2:* TL11*[X11 X12] + ISGN*[X11 X12]*op[TR11 TR12] = [B11 B12]* [TR21 TR22]*20 CONTINUE*SMIN = MAX( EPS*MAX( ABS( TL( 1, 1 ) ), ABS( TR( 1, 1 ) ),$ ABS( TR( 1, 2 ) ), ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) ),$ SMLNUM )TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )TMP( 4 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )IF( LTRANR ) THENTMP( 2 ) = SGN*TR( 2, 1 )TMP( 3 ) = SGN*TR( 1, 2 )ELSETMP( 2 ) = SGN*TR( 1, 2 )TMP( 3 ) = SGN*TR( 2, 1 )END IFBTMP( 1 ) = B( 1, 1 )BTMP( 2 ) = B( 1, 2 )GO TO 40** 2 by 1:* op[TL11 TL12]*[X11] + ISGN* [X11]*TR11 = [B11]* [TL21 TL22] [X21] [X21] [B21]*30 CONTINUESMIN = MAX( EPS*MAX( ABS( TR( 1, 1 ) ), ABS( TL( 1, 1 ) ),$ ABS( TL( 1, 2 ) ), ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) ),$ SMLNUM )TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )TMP( 4 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )IF( LTRANL ) THENTMP( 2 ) = TL( 1, 2 )TMP( 3 ) = TL( 2, 1 )ELSETMP( 2 ) = TL( 2, 1 )TMP( 3 ) = TL( 1, 2 )END IFBTMP( 1 ) = B( 1, 1 )BTMP( 2 ) = B( 2, 1 )40 CONTINUE** Solve 2 by 2 system using complete pivoting.* Set pivots less than SMIN to SMIN.*IPIV = IDAMAX( 4, TMP, 1 )U11 = TMP( IPIV )IF( ABS( U11 ).LE.SMIN ) THENINFO = 1U11 = SMINEND IFU12 = TMP( LOCU12( IPIV ) )L21 = TMP( LOCL21( IPIV ) ) / U11U22 = TMP( LOCU22( IPIV ) ) - U12*L21XSWAP = XSWPIV( IPIV )BSWAP = BSWPIV( IPIV )IF( ABS( U22 ).LE.SMIN ) THENINFO = 1U22 = SMINEND IFIF( BSWAP ) THENTEMP = BTMP( 2 )BTMP( 2 ) = BTMP( 1 ) - L21*TEMPBTMP( 1 ) = TEMPELSEBTMP( 2 ) = BTMP( 2 ) - L21*BTMP( 1 )END IFSCALE = ONEIF( ( TWO*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( U22 ) .OR.$ ( TWO*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( U11 ) ) THENSCALE = HALF / MAX( ABS( BTMP( 1 ) ), ABS( BTMP( 2 ) ) )BTMP( 1 ) = BTMP( 1 )*SCALEBTMP( 2 ) = BTMP( 2 )*SCALEEND IFX2( 2 ) = BTMP( 2 ) / U22X2( 1 ) = BTMP( 1 ) / U11 - ( U12 / U11 )*X2( 2 )IF( XSWAP ) THENTEMP = X2( 2 )X2( 2 ) = X2( 1 )X2( 1 ) = TEMPEND IFX( 1, 1 ) = X2( 1 )IF( N1.EQ.1 ) THENX( 1, 2 ) = X2( 2 )XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )ELSEX( 2, 1 ) = X2( 2 )XNORM = MAX( ABS( X( 1, 1 ) ), ABS( X( 2, 1 ) ) )END IFRETURN** 2 by 2:* op[TL11 TL12]*[X11 X12] +ISGN* [X11 X12]*op[TR11 TR12] = [B11 B12]* [TL21 TL22] [X21 X22] [X21 X22] [TR21 TR22] [B21 B22]** Solve equivalent 4 by 4 system using complete pivoting.* Set pivots less than SMIN to SMIN.*50 CONTINUESMIN = MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),$ ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )SMIN = MAX( SMIN, ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),$ ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )SMIN = MAX( EPS*SMIN, SMLNUM )BTMP( 1 ) = ZEROCALL DCOPY( 16, BTMP, 0, T16, 1 )T16( 1, 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )T16( 2, 2 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )T16( 3, 3 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )T16( 4, 4 ) = TL( 2, 2 ) + SGN*TR( 2, 2 )IF( LTRANL ) THENT16( 1, 2 ) = TL( 2, 1 )T16( 2, 1 ) = TL( 1, 2 )T16( 3, 4 ) = TL( 2, 1 )T16( 4, 3 ) = TL( 1, 2 )ELSET16( 1, 2 ) = TL( 1, 2 )T16( 2, 1 ) = TL( 2, 1 )T16( 3, 4 ) = TL( 1, 2 )T16( 4, 3 ) = TL( 2, 1 )END IFIF( LTRANR ) THENT16( 1, 3 ) = SGN*TR( 1, 2 )T16( 2, 4 ) = SGN*TR( 1, 2 )T16( 3, 1 ) = SGN*TR( 2, 1 )T16( 4, 2 ) = SGN*TR( 2, 1 )ELSET16( 1, 3 ) = SGN*TR( 2, 1 )T16( 2, 4 ) = SGN*TR( 2, 1 )T16( 3, 1 ) = SGN*TR( 1, 2 )T16( 4, 2 ) = SGN*TR( 1, 2 )END IFBTMP( 1 ) = B( 1, 1 )BTMP( 2 ) = B( 2, 1 )BTMP( 3 ) = B( 1, 2 )BTMP( 4 ) = B( 2, 2 )** Perform elimination*DO 100 I = 1, 3XMAX = ZERODO 70 IP = I, 4DO 60 JP = I, 4IF( ABS( T16( IP, JP ) ).GE.XMAX ) THENXMAX = ABS( T16( IP, JP ) )IPSV = IPJPSV = JPEND IF60 CONTINUE70 CONTINUEIF( IPSV.NE.I ) THENCALL DSWAP( 4, T16( IPSV, 1 ), 4, T16( I, 1 ), 4 )TEMP = BTMP( I )BTMP( I ) = BTMP( IPSV )BTMP( IPSV ) = TEMPEND IFIF( JPSV.NE.I )$ CALL DSWAP( 4, T16( 1, JPSV ), 1, T16( 1, I ), 1 )JPIV( I ) = JPSVIF( ABS( T16( I, I ) ).LT.SMIN ) THENINFO = 1T16( I, I ) = SMINEND IFDO 90 J = I + 1, 4T16( J, I ) = T16( J, I ) / T16( I, I )BTMP( J ) = BTMP( J ) - T16( J, I )*BTMP( I )DO 80 K = I + 1, 4T16( J, K ) = T16( J, K ) - T16( J, I )*T16( I, K )80 CONTINUE90 CONTINUE100 CONTINUEIF( ABS( T16( 4, 4 ) ).LT.SMIN )$ T16( 4, 4 ) = SMINSCALE = ONEIF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.$ ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.$ ( EIGHT*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T16( 3, 3 ) ) .OR.$ ( EIGHT*SMLNUM )*ABS( BTMP( 4 ) ).GT.ABS( T16( 4, 4 ) ) ) THENSCALE = ( ONE / EIGHT ) / MAX( ABS( BTMP( 1 ) ),$ ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ), ABS( BTMP( 4 ) ) )BTMP( 1 ) = BTMP( 1 )*SCALEBTMP( 2 ) = BTMP( 2 )*SCALEBTMP( 3 ) = BTMP( 3 )*SCALEBTMP( 4 ) = BTMP( 4 )*SCALEEND IFDO 120 I = 1, 4K = 5 - ITEMP = ONE / T16( K, K )TMP( K ) = BTMP( K )*TEMPDO 110 J = K + 1, 4TMP( K ) = TMP( K ) - ( TEMP*T16( K, J ) )*TMP( J )110 CONTINUE120 CONTINUEDO 130 I = 1, 3IF( JPIV( 4-I ).NE.4-I ) THENTEMP = TMP( 4-I )TMP( 4-I ) = TMP( JPIV( 4-I ) )TMP( JPIV( 4-I ) ) = TEMPEND IF130 CONTINUEX( 1, 1 ) = TMP( 1 )X( 2, 1 ) = TMP( 2 )X( 1, 2 ) = TMP( 3 )X( 2, 2 ) = TMP( 4 )XNORM = MAX( ABS( TMP( 1 ) )+ABS( TMP( 3 ) ),$ ABS( TMP( 2 ) )+ABS( TMP( 4 ) ) )RETURN** End of DLASY2*ENDSUBROUTINE DLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,$ JPIV )** -- LAPACK auxiliary 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 IJOB, LDZ, NDOUBLE PRECISION RDSCAL, RDSUM* ..* .. Array Arguments ..INTEGER IPIV( * ), JPIV( * )DOUBLE PRECISION RHS( * ), Z( LDZ, * )* ..** Purpose* =======** DLATDF uses the LU factorization of the n-by-n matrix Z computed by* DGETC2 and computes a contribution to the reciprocal Dif-estimate* by solving Z * x = b for x, and choosing the r.h.s. b such that* the norm of x is as large as possible. On entry RHS = b holds the* contribution from earlier solved sub-systems, and on return RHS = x.** The factorization of Z returned by DGETC2 has the form Z = P*L*U*Q,* where P and Q are permutation matrices. L is lower triangular with* unit diagonal elements and U is upper triangular.** Arguments* =========** IJOB (input) INTEGER* IJOB = 2: First compute an approximative null-vector e* of Z using DGECON, e is normalized and solve for* Zx = +-e - f with the sign giving the greater value* of 2-norm(x). About 5 times as expensive as Default.* IJOB .ne. 2: Local look ahead strategy where all entries of* the r.h.s. b is choosen as either +1 or -1 (Default).** N (input) INTEGER* The number of columns of the matrix Z.** Z (input) DOUBLE PRECISION array, dimension (LDZ, N)* On entry, the LU part of the factorization of the n-by-n* matrix Z computed by DGETC2: Z = P * L * U * Q** LDZ (input) INTEGER* The leading dimension of the array Z. LDA >= max(1, N).** RHS (input/output) DOUBLE PRECISION array, dimension N.* On entry, RHS contains contributions from other subsystems.* On exit, RHS contains the solution of the subsystem with* entries acoording to the value of IJOB (see above).** RDSUM (input/output) DOUBLE PRECISION* On entry, the sum of squares of computed contributions to* the Dif-estimate under computation by DTGSYL, where the* scaling factor RDSCAL (see below) has been factored out.* On exit, the corresponding sum of squares updated with the* contributions from the current sub-system.* If TRANS = 'T' RDSUM is not touched.* NOTE: RDSUM only makes sense when DTGSY2 is called by STGSYL.** RDSCAL (input/output) DOUBLE PRECISION* On entry, scaling factor used to prevent overflow in RDSUM.* On exit, RDSCAL is updated w.r.t. the current contributions* in RDSUM.* If TRANS = 'T', RDSCAL is not touched.* NOTE: RDSCAL only makes sense when DTGSY2 is called by* DTGSYL.** IPIV (input) INTEGER array, dimension (N).* The pivot indices; for 1 <= i <= N, row i of the* matrix has been interchanged with row IPIV(i).** JPIV (input) INTEGER array, dimension (N).* The pivot indices; for 1 <= j <= N, column j of the* matrix has been interchanged with column JPIV(j).** Further Details* ===============** Based on contributions by* Bo Kagstrom and Peter Poromaa, Department of Computing Science,* Umea University, S-901 87 Umea, Sweden.** This routine is a further developed implementation of algorithm* BSOLVE in [1] using complete pivoting in the LU factorization.** [1] Bo Kagstrom and Lars Westin,* Generalized Schur Methods with Condition Estimators for* Solving the Generalized Sylvester Equation, IEEE Transactions* on Automatic Control, Vol. 34, No. 7, July 1989, pp 745-751.** [2] Peter Poromaa,* On Efficient and Robust Estimators for the Separation* between two Regular Matrix Pairs with Applications in* Condition Estimation. Report IMINF-95.05, Departement of* Computing Science, Umea University, S-901 87 Umea, Sweden, 1995.** =====================================================================** .. Parameters ..INTEGER MAXDIMPARAMETER ( MAXDIM = 8 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, INFO, J, KDOUBLE PRECISION BM, BP, PMONE, SMINU, SPLUS, TEMP* ..* .. Local Arrays ..INTEGER IWORK( MAXDIM )DOUBLE PRECISION WORK( 4*MAXDIM ), XM( MAXDIM ), XP( MAXDIM )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGECON, DGESC2, DLASSQ, DLASWP,$ DSCAL* ..* .. External Functions ..DOUBLE PRECISION DASUM, DDOTEXTERNAL DASUM, DDOT* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( IJOB.NE.2 ) THEN** Apply permutations IPIV to RHS*CALL DLASWP( 1, RHS, LDZ, 1, N-1, IPIV, 1 )** Solve for L-part choosing RHS either to +1 or -1.*PMONE = -ONE*DO 10 J = 1, N - 1BP = RHS( J ) + ONEBM = RHS( J ) - ONESPLUS = ONE** Look-ahead for L-part RHS(1:N-1) = + or -1, SPLUS and* SMIN computed more efficiently than in BSOLVE [1].*SPLUS = SPLUS + DDOT( N-J, Z( J+1, J ), 1, Z( J+1, J ), 1 )SMINU = DDOT( N-J, Z( J+1, J ), 1, RHS( J+1 ), 1 )SPLUS = SPLUS*RHS( J )IF( SPLUS.GT.SMINU ) THENRHS( J ) = BPELSE IF( SMINU.GT.SPLUS ) THENRHS( J ) = BMELSE** In this case the updating sums are equal and we can* choose RHS(J) +1 or -1. The first time this happens* we choose -1, thereafter +1. This is a simple way to* get good estimates of matrices like Byers well-known* example (see [1]). (Not done in BSOLVE.)*RHS( J ) = RHS( J ) + PMONEPMONE = ONEEND IF** Compute the remaining r.h.s.*TEMP = -RHS( J )CALL DAXPY( N-J, TEMP, Z( J+1, J ), 1, RHS( J+1 ), 1 )*10 CONTINUE** Solve for U-part, look-ahead for RHS(N) = +-1. This is not done* in BSOLVE and will hopefully give us a better estimate because* any ill-conditioning of the original matrix is transfered to U* and not to L. U(N, N) is an approximation to sigma_min(LU).*CALL DCOPY( N-1, RHS, 1, XP, 1 )XP( N ) = RHS( N ) + ONERHS( N ) = RHS( N ) - ONESPLUS = ZEROSMINU = ZERODO 30 I = N, 1, -1TEMP = ONE / Z( I, I )XP( I ) = XP( I )*TEMPRHS( I ) = RHS( I )*TEMPDO 20 K = I + 1, NXP( I ) = XP( I ) - XP( K )*( Z( I, K )*TEMP )RHS( I ) = RHS( I ) - RHS( K )*( Z( I, K )*TEMP )20 CONTINUESPLUS = SPLUS + ABS( XP( I ) )SMINU = SMINU + ABS( RHS( I ) )30 CONTINUEIF( SPLUS.GT.SMINU )$ CALL DCOPY( N, XP, 1, RHS, 1 )** Apply the permutations JPIV to the computed solution (RHS)*CALL DLASWP( 1, RHS, LDZ, 1, N-1, JPIV, -1 )** Compute the sum of squares*CALL DLASSQ( N, RHS, 1, RDSCAL, RDSUM )*ELSE** IJOB = 2, Compute approximate nullvector XM of Z*CALL DGECON( 'I', N, Z, LDZ, ONE, TEMP, WORK, IWORK, INFO )CALL DCOPY( N, WORK( N+1 ), 1, XM, 1 )** Compute RHS*CALL DLASWP( 1, XM, LDZ, 1, N-1, IPIV, -1 )TEMP = ONE / SQRT( DDOT( N, XM, 1, XM, 1 ) )CALL DSCAL( N, TEMP, XM, 1 )CALL DCOPY( N, XM, 1, XP, 1 )CALL DAXPY( N, ONE, RHS, 1, XP, 1 )CALL DAXPY( N, -ONE, XM, 1, RHS, 1 )CALL DGESC2( N, Z, LDZ, RHS, IPIV, JPIV, TEMP )CALL DGESC2( N, Z, LDZ, XP, IPIV, JPIV, TEMP )IF( DASUM( N, XP, 1 ).GT.DASUM( N, RHS, 1 ) )$ CALL DCOPY( N, XP, 1, RHS, 1 )** Compute the sum of squares*CALL DLASSQ( N, RHS, 1, RDSCAL, RDSUM )*END IF*RETURN** End of DLATDF*ENDSUBROUTINE DLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )** -- LAPACK auxiliary 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 ..CHARACTER UPLOINTEGER LDA, LDW, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), E( * ), TAU( * ), W( LDW, * )* ..** Purpose* =======** DLATRD reduces NB rows and columns of a real symmetric matrix A to* symmetric tridiagonal form by an orthogonal similarity* transformation Q' * A * Q, and returns the matrices V and W which are* needed to apply the transformation to the unreduced part of A.** If UPLO = 'U', DLATRD reduces the last NB rows and columns of a* matrix, of which the upper triangle is supplied;* if UPLO = 'L', DLATRD reduces the first NB rows and columns of a* matrix, of which the lower triangle is supplied.** This is an auxiliary routine called by DSYTRD.** Arguments* =========** UPLO (input) CHARACTER* Specifies whether the upper or lower triangular part of the* symmetric matrix A is stored:* = 'U': Upper triangular* = 'L': Lower triangular** N (input) INTEGER* The order of the matrix A.** NB (input) INTEGER* The number of rows and columns to be reduced.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the symmetric matrix A. If UPLO = 'U', the leading* n-by-n upper triangular part of A contains the upper* triangular part of the matrix A, and the strictly lower* triangular part of A is not referenced. If UPLO = 'L', the* leading n-by-n lower triangular part of A contains the lower* triangular part of the matrix A, and the strictly upper* triangular part of A is not referenced.* On exit:* if UPLO = 'U', the last NB columns have been reduced to* tridiagonal form, with the diagonal elements overwriting* the diagonal elements of A; the elements above the diagonal* with the array TAU, represent the orthogonal matrix Q as a* product of elementary reflectors;* if UPLO = 'L', the first NB columns have been reduced to* tridiagonal form, with the diagonal elements overwriting* the diagonal elements of A; 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 >= (1,N).** E (output) DOUBLE PRECISION array, dimension (N-1)* If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal* elements of the last NB columns of the reduced matrix;* if UPLO = 'L', E(1:nb) contains the subdiagonal elements of* the first NB columns of the reduced matrix.** TAU (output) DOUBLE PRECISION array, dimension (N-1)* The scalar factors of the elementary reflectors, stored in* TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'.* See Further Details.** W (output) DOUBLE PRECISION array, dimension (LDW,NB)* The n-by-nb matrix W required to update the unreduced part* of A.** LDW (input) INTEGER* The leading dimension of the array W. LDW >= max(1,N).** Further Details* ===============** If UPLO = 'U', the matrix Q is represented as a product of elementary* reflectors** Q = H(n) H(n-1) . . . H(n-nb+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(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i),* and tau in TAU(i-1).** If UPLO = 'L', the matrix Q is represented as a product of elementary* reflectors** Q = H(1) H(2) . . . H(nb).** 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 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),* and tau in TAU(i).** The elements of the vectors v together form the n-by-nb matrix V* which is needed, with W, to apply the transformation to the unreduced* part of the matrix, using a symmetric rank-2k update of the form:* A := A - V*W' - W*V'.** The contents of A on exit are illustrated by the following examples* with n = 5 and nb = 2:** if UPLO = 'U': if UPLO = 'L':** ( a a a v4 v5 ) ( d )* ( a a v4 v5 ) ( 1 d )* ( a 1 v5 ) ( v1 1 a )* ( d 1 ) ( v1 v2 a a )* ( d ) ( v1 v2 a a a )** where d denotes a diagonal element of the reduced matrix, a denotes* an element of the original matrix that is unchanged, and vi denotes* an element of the vector defining H(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, HALFPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )* ..* .. Local Scalars ..INTEGER I, IWDOUBLE PRECISION ALPHA* ..* .. External Subroutines ..EXTERNAL DAXPY, DGEMV, DLARFG, DSCAL, DSYMV* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 )$ RETURN*IF( LSAME( UPLO, 'U' ) ) THEN** Reduce last NB columns of upper triangle*DO 10 I = N, N - NB + 1, -1IW = I - N + NBIF( I.LT.N ) THEN** Update A(1:i,i)*CALL DGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ),$ LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 )CALL DGEMV( 'No transpose', I, N-I, -ONE, W( 1, IW+1 ),$ LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 )END IFIF( I.GT.1 ) THEN** Generate elementary reflector H(i) to annihilate* A(1:i-2,i)*CALL DLARFG( I-1, A( I-1, I ), A( 1, I ), 1, TAU( I-1 ) )E( I-1 ) = A( I-1, I )A( I-1, I ) = ONE** Compute W(1:i-1,i)*CALL DSYMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1,$ ZERO, W( 1, IW ), 1 )IF( I.LT.N ) THENCALL DGEMV( 'Transpose', I-1, N-I, ONE, W( 1, IW+1 ),$ LDW, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )CALL DGEMV( 'No transpose', I-1, N-I, -ONE,$ A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE,$ W( 1, IW ), 1 )CALL DGEMV( 'Transpose', I-1, N-I, ONE, A( 1, I+1 ),$ LDA, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )CALL DGEMV( 'No transpose', I-1, N-I, -ONE,$ W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE,$ W( 1, IW ), 1 )END IFCALL DSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 )ALPHA = -HALF*TAU( I-1 )*DDOT( I-1, W( 1, IW ), 1,$ A( 1, I ), 1 )CALL DAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 )END IF*10 CONTINUEELSE** Reduce first NB columns of lower triangle*DO 20 I = 1, NB** Update A(i:n,i)*CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ),$ LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 )CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ),$ LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 )IF( I.LT.N ) THEN** Generate elementary reflector H(i) to annihilate* A(i+2:n,i)*CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,$ TAU( I ) )E( I ) = A( I+1, I )A( I+1, I ) = ONE** Compute W(i+1:n,i)*CALL DSYMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA,$ A( I+1, I ), 1, ZERO, W( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I, I-1, ONE, W( I+1, 1 ), LDW,$ A( I+1, I ), 1, ZERO, W( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, 1 ),$ LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,$ A( I+1, I ), 1, ZERO, W( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, 1 ),$ LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 )CALL DSCAL( N-I, TAU( I ), W( I+1, I ), 1 )ALPHA = -HALF*TAU( I )*DDOT( N-I, W( I+1, I ), 1,$ A( I+1, I ), 1 )CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), 1 )END IF*20 CONTINUEEND IF*RETURN** End of DLATRD*ENDSUBROUTINE DLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,$ CNORM, INFO )** -- LAPACK auxiliary 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 ..CHARACTER DIAG, NORMIN, TRANS, UPLOINTEGER INFO, LDA, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), CNORM( * ), X( * )* ..** Purpose* =======** DLATRS solves one of the triangular systems** A *x = s*b or A'*x = s*b** with scaling to prevent overflow. Here A is an upper or lower* triangular matrix, A' denotes the transpose of A, x and b are* n-element vectors, and s is a scaling factor, usually less than* or equal to 1, chosen so that the components of x will be less than* the overflow threshold. If the unscaled problem will not cause* overflow, the Level 2 BLAS routine DTRSV is called. If the matrix A* is singular (A(j,j) = 0 for some j), then s is set to 0 and a* non-trivial solution to A*x = 0 is returned.** Arguments* =========** UPLO (input) CHARACTER*1* Specifies whether the matrix A is upper or lower triangular.* = 'U': Upper triangular* = 'L': Lower triangular** TRANS (input) CHARACTER*1* Specifies the operation applied to A.* = 'N': Solve A * x = s*b (No transpose)* = 'T': Solve A'* x = s*b (Transpose)* = 'C': Solve A'* x = s*b (Conjugate transpose = Transpose)** DIAG (input) CHARACTER*1* Specifies whether or not the matrix A is unit triangular.* = 'N': Non-unit triangular* = 'U': Unit triangular** NORMIN (input) CHARACTER*1* Specifies whether CNORM has been set or not.* = 'Y': CNORM contains the column norms on entry* = 'N': CNORM is not set on entry. On exit, the norms will* be computed and stored in CNORM.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* The triangular matrix A. If UPLO = 'U', the leading n by n* upper triangular part of the array A contains the upper* triangular matrix, and the strictly lower triangular part of* A is not referenced. If UPLO = 'L', the leading n by n lower* triangular part of the array A contains the lower triangular* matrix, and the strictly upper triangular part of A is not* referenced. If DIAG = 'U', the diagonal elements of A are* also not referenced and are assumed to be 1.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max (1,N).** X (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the right hand side b of the triangular system.* On exit, X is overwritten by the solution vector x.** SCALE (output) DOUBLE PRECISION* The scaling factor s for the triangular system* A * x = s*b or A'* x = s*b.* If SCALE = 0, the matrix A is singular or badly scaled, and* the vector x is an exact or approximate solution to A*x = 0.** CNORM (input or output) DOUBLE PRECISION array, dimension (N)** If NORMIN = 'Y', CNORM is an input argument and CNORM(j)* contains the norm of the off-diagonal part of the j-th column* of A. If TRANS = 'N', CNORM(j) must be greater than or equal* to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)* must be greater than or equal to the 1-norm.** If NORMIN = 'N', CNORM is an output argument and CNORM(j)* returns the 1-norm of the offdiagonal part of the j-th column* of A.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -k, the k-th argument had an illegal value** Further Details* ======= =======** A rough bound on x is computed; if that is less than overflow, DTRSV* is called, otherwise, specific code is used which checks for possible* overflow or divide-by-zero at every operation.** A columnwise scheme is used for solving A*x = b. The basic algorithm* if A is lower triangular is** x[1:n] := b[1:n]* for j = 1, ..., n* x(j) := x(j) / A(j,j)* x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]* end** Define bounds on the components of x after j iterations of the loop:* M(j) = bound on x[1:j]* G(j) = bound on x[j+1:n]* Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.** Then for iteration j+1 we have* M(j+1) <= G(j) / | A(j+1,j+1) |* G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |* <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )** where CNORM(j+1) is greater than or equal to the infinity-norm of* column j+1 of A, not counting the diagonal. Hence** G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )* 1<=i<=j* and** |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )* 1<=i< j** Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTRSV if the* reciprocal of the largest M(j), j=1,..,n, is larger than* max(underflow, 1/overflow).** The bound on x(j) is also used to determine when a step in the* columnwise method can be performed without fear of overflow. If* the computed bound is greater than a large constant, x is scaled to* prevent overflow, but if the bound overflows, x is set to 0, x(j) to* 1, and scale to 0, and a non-trivial solution to A*x = 0 is found.** Similarly, a row-wise scheme is used to solve A'*x = b. The basic* algorithm for A upper triangular is** for j = 1, ..., n* x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)* end** We simultaneously compute two bounds* G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j* M(j) = bound on x(i), 1<=i<=j** The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we* add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.* Then the bound on x(j) is** M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |** <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )* 1<=i<=j** and we can safely call DTRSV if 1/M(n) and 1/G(n) are both greater* than max(underflow, 1/overflow).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERINTEGER I, IMAX, J, JFIRST, JINC, JLASTDOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,$ TMAX, TSCAL, USCAL, XBND, XJ, XMAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DASUM, DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DASUM, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DTRSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )** Test the input parameters.*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.$ LSAME( NORMIN, 'N' ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLATRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine machine dependent parameters to control overflow.*SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )BIGNUM = ONE / SMLNUMSCALE = ONE*IF( LSAME( NORMIN, 'N' ) ) THEN** Compute the 1-norm of each column, not including the diagonal.*IF( UPPER ) THEN** A is upper triangular.*DO 10 J = 1, NCNORM( J ) = DASUM( J-1, A( 1, J ), 1 )10 CONTINUEELSE** A is lower triangular.*DO 20 J = 1, N - 1CNORM( J ) = DASUM( N-J, A( J+1, J ), 1 )20 CONTINUECNORM( N ) = ZEROEND IFEND IF** Scale the column norms by TSCAL if the maximum element in CNORM is* greater than BIGNUM.*IMAX = IDAMAX( N, CNORM, 1 )TMAX = CNORM( IMAX )IF( TMAX.LE.BIGNUM ) THENTSCAL = ONEELSETSCAL = ONE / ( SMLNUM*TMAX )CALL DSCAL( N, TSCAL, CNORM, 1 )END IF** Compute a bound on the computed solution vector to see if the* Level 2 BLAS routine DTRSV can be used.*J = IDAMAX( N, X, 1 )XMAX = ABS( X( J ) )XBND = XMAXIF( NOTRAN ) THEN** Compute the growth in A * x = b.*IF( UPPER ) THENJFIRST = NJLAST = 1JINC = -1ELSEJFIRST = 1JLAST = NJINC = 1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 50END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, G(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWDO 30 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** M(j) = G(j-1) / abs(A(j,j))*TJJ = ABS( A( J, J ) )XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN** G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )*GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )ELSE** G(j) could overflow, set GROW to 0.*GROW = ZEROEND IF30 CONTINUEGROW = XBNDELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 40 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** G(j) = G(j-1)*( 1 + CNORM(j) )*GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )40 CONTINUEEND IF50 CONTINUE*ELSE** Compute the growth in A' * x = b.*IF( UPPER ) THENJFIRST = 1JLAST = NJINC = 1ELSEJFIRST = NJLAST = 1JINC = -1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 80END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, M(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWDO 60 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )*XJ = ONE + CNORM( J )GROW = MIN( GROW, XBND / XJ )** M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))*TJJ = ABS( A( J, J ) )IF( XJ.GT.TJJ )$ XBND = XBND*( TJJ / XJ )60 CONTINUEGROW = MIN( GROW, XBND )ELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 70 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = ( 1 + CNORM(j) )*G(j-1)*XJ = ONE + CNORM( J )GROW = GROW / XJ70 CONTINUEEND IF80 CONTINUEEND IF*IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN** Use the Level 2 BLAS solve if the reciprocal of the bound on* elements of X is not too small.*CALL DTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )ELSE** Use a Level 1 BLAS solve, scaling intermediate results.*IF( XMAX.GT.BIGNUM ) THEN** Scale X so that its components are less than or equal to* BIGNUM in absolute value.*SCALE = BIGNUM / XMAXCALL DSCAL( N, SCALE, X, 1 )XMAX = BIGNUMEND IF*IF( NOTRAN ) THEN** Solve A * x = b*DO 110 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) / A(j,j), scaling x if necessary.*XJ = ABS( X( J ) )IF( NOUNIT ) THENTJJS = A( J, J )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 100END IFTJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by 1/b(j).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM* to avoid overflow when dividing by A(j,j).*REC = ( TJJ*BIGNUM ) / XJIF( CNORM( J ).GT.ONE ) THEN** Scale by 1/CNORM(j) to avoid overflow when* multiplying x(j) times column j.*REC = REC / CNORM( J )END IFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A*x = 0.*DO 90 I = 1, NX( I ) = ZERO90 CONTINUEX( J ) = ONEXJ = ONESCALE = ZEROXMAX = ZEROEND IF100 CONTINUE** Scale x if necessary to avoid overflow when adding a* multiple of column j of A.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN** Scale x by 1/(2*abs(x(j))).*REC = REC*HALFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN** Scale x by 1/2.*CALL DSCAL( N, HALF, X, 1 )SCALE = SCALE*HALFEND IF*IF( UPPER ) THENIF( J.GT.1 ) THEN** Compute the update* x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)*CALL DAXPY( J-1, -X( J )*TSCAL, A( 1, J ), 1, X,$ 1 )I = IDAMAX( J-1, X, 1 )XMAX = ABS( X( I ) )END IFELSEIF( J.LT.N ) THEN** Compute the update* x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)*CALL DAXPY( N-J, -X( J )*TSCAL, A( J+1, J ), 1,$ X( J+1 ), 1 )I = J + IDAMAX( N-J, X( J+1 ), 1 )XMAX = ABS( X( I ) )END IFEND IF110 CONTINUE*ELSE** Solve A' * x = b*DO 160 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) - sum A(k,j)*x(k).* k<>j*XJ = ABS( X( J ) )USCAL = TSCALREC = ONE / MAX( XMAX, ONE )IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN** If x(j) could overflow, scale x by 1/(2*XMAX).*REC = REC*HALFIF( NOUNIT ) THENTJJS = A( J, J )*TSCALELSETJJS = TSCALEND IFTJJ = ABS( TJJS )IF( TJJ.GT.ONE ) THEN** Divide by A(j,j) when scaling x if A(j,j) > 1.*REC = MIN( ONE, REC*TJJ )USCAL = USCAL / TJJSEND IFIF( REC.LT.ONE ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*SUMJ = ZEROIF( USCAL.EQ.ONE ) THEN** If the scaling needed for A in the dot product is 1,* call DDOT to perform the dot product.*IF( UPPER ) THENSUMJ = DDOT( J-1, A( 1, J ), 1, X, 1 )ELSE IF( J.LT.N ) THENSUMJ = DDOT( N-J, A( J+1, J ), 1, X( J+1 ), 1 )END IFELSE** Otherwise, use in-line code for the dot product.*IF( UPPER ) THENDO 120 I = 1, J - 1SUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )120 CONTINUEELSE IF( J.LT.N ) THENDO 130 I = J + 1, NSUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )130 CONTINUEEND IFEND IF*IF( USCAL.EQ.TSCAL ) THEN** Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)* was not used to scale the dotproduct.*X( J ) = X( J ) - SUMJXJ = ABS( X( J ) )IF( NOUNIT ) THENTJJS = A( J, J )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 150END IF** Compute x(j) = x(j) / A(j,j), scaling if necessary.*TJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale X by 1/abs(x(j)).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.*REC = ( TJJ*BIGNUM ) / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A'*x = 0.*DO 140 I = 1, NX( I ) = ZERO140 CONTINUEX( J ) = ONESCALE = ZEROXMAX = ZEROEND IF150 CONTINUEELSE** Compute x(j) := x(j) / A(j,j) - sumj if the dot* product has already been divided by 1/A(j,j).*X( J ) = X( J ) / TJJS - SUMJEND IFXMAX = MAX( XMAX, ABS( X( J ) ) )160 CONTINUEEND IFSCALE = SCALE / TSCALEND IF** Scale the column norms by 1/TSCAL for return.*IF( TSCAL.NE.ONE ) THENCALL DSCAL( N, ONE / TSCAL, CNORM, 1 )END IF*RETURN** End of DLATRS*ENDSUBROUTINE DORG2L( M, N, K, 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, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORG2L generates an m by n real matrix Q with orthonormal columns,* which is defined as the last n columns of a product of k elementary* reflectors of order m** Q = H(k) . . . H(2) H(1)** as returned by DGEQLF.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix Q. M >= 0.** N (input) INTEGER* The number of columns of the matrix Q. M >= N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines the* matrix Q. N >= K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the (n-k+i)-th column must contain the vector which* defines the elementary reflector H(i), for i = 1,2,...,k, as* returned by DGEQLF in the last k columns of its array* argument A.* On exit, the m by n matrix Q.** LDA (input) INTEGER* The first dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEQLF.** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument has an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, II, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORG2L', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN** Initialise columns 1:n-k to columns of the unit matrix*DO 20 J = 1, N - KDO 10 L = 1, MA( L, J ) = ZERO10 CONTINUEA( M-N+J, J ) = ONE20 CONTINUE*DO 40 I = 1, KII = N - K + I** Apply H(i) to A(1:m-k+i,1:n-k+i) from the left*A( M-N+II, II ) = ONECALL DLARF( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), A,$ LDA, WORK )CALL DSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 )A( M-N+II, II ) = ONE - TAU( I )** Set A(m-k+i+1:m,n-k+i) to zero*DO 30 L = M - N + II + 1, MA( L, II ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORG2L*ENDSUBROUTINE DORG2R( M, N, K, 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, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORG2R generates an m by n real matrix Q with orthonormal columns,* which is defined as the first n columns of a product of k elementary* reflectors of order m** Q = H(1) H(2) . . . H(k)** as returned by DGEQRF.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix Q. M >= 0.** N (input) INTEGER* The number of columns of the matrix Q. M >= N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines the* matrix Q. N >= K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the i-th column must contain the vector which* defines the elementary reflector H(i), for i = 1,2,...,k, as* returned by DGEQRF in the first k columns of its array* argument A.* On exit, the m-by-n matrix Q.** LDA (input) INTEGER* The first dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEQRF.** WORK (workspace) DOUBLE PRECISION array, dimension (N)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument has an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORG2R', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN** Initialise columns k+1:n to columns of the unit matrix*DO 20 J = K + 1, NDO 10 L = 1, MA( L, J ) = ZERO10 CONTINUEA( J, J ) = ONE20 CONTINUE*DO 40 I = K, 1, -1** Apply H(i) to A(i:m,i:n) from the left*IF( I.LT.N ) THENA( I, I ) = ONECALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK )END IFIF( I.LT.M )$ CALL DSCAL( M-I, -TAU( I ), A( I+1, I ), 1 )A( I, I ) = ONE - TAU( I )** Set A(1:i-1,i) to zero*DO 30 L = 1, I - 1A( L, I ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORG2R*ENDSUBROUTINE DORGBR( VECT, M, N, K, 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 ..CHARACTER VECTINTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORGBR generates one of the real orthogonal matrices Q or P**T* determined by DGEBRD when reducing a real matrix A to bidiagonal* form: A = Q * B * P**T. Q and P**T are defined as products of* elementary reflectors H(i) or G(i) respectively.** If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q* is of order M:* if m >= k, Q = H(1) H(2) . . . H(k) and DORGBR returns the first n* columns of Q, where m >= n >= k;* if m < k, Q = H(1) H(2) . . . H(m-1) and DORGBR returns Q as an* M-by-M matrix.** If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T* is of order N:* if k < n, P**T = G(k) . . . G(2) G(1) and DORGBR returns the first m* rows of P**T, where n >= m >= k;* if k >= n, P**T = G(n-1) . . . G(2) G(1) and DORGBR returns P**T as* an N-by-N matrix.** Arguments* =========** VECT (input) CHARACTER*1* Specifies whether the matrix Q or the matrix P**T is* required, as defined in the transformation applied by DGEBRD:* = 'Q': generate Q;* = 'P': generate P**T.** M (input) INTEGER* The number of rows of the matrix Q or P**T to be returned.* M >= 0.** N (input) INTEGER* The number of columns of the matrix Q or P**T to be returned.* N >= 0.* If VECT = 'Q', M >= N >= min(M,K);* if VECT = 'P', N >= M >= min(N,K).** K (input) INTEGER* If VECT = 'Q', the number of columns in the original M-by-K* matrix reduced by DGEBRD.* If VECT = 'P', the number of rows in the original K-by-N* matrix reduced by DGEBRD.* K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the vectors which define the elementary reflectors,* as returned by DGEBRD.* On exit, the M-by-N matrix Q or P**T.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension* (min(M,K)) if VECT = 'Q'* (min(N,K)) if VECT = 'P'* TAU(i) must contain the scalar factor of the elementary* reflector H(i) or G(i), which determines Q or P**T, as* returned by DGEBRD in its array argument TAUQ or TAUP.** 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,min(M,N)).* For optimum performance LWORK >= min(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** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WANTQINTEGER I, IINFO, J, LWKOPT, MN, NB* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORGLQ, DORGQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0WANTQ = LSAME( VECT, 'Q' )MN = MIN( M, N )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M,$ K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT.$ MIN( N, K ) ) ) ) THENINFO = -3ELSE IF( K.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THENINFO = -9END IF*IF( INFO.EQ.0 ) THENIF( WANTQ ) THENNB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 )ELSENB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 )END IFLWKOPT = MAX( 1, MN )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGBR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( WANTQ ) THEN** Form Q, determined by a call to DGEBRD to reduce an m-by-k* matrix*IF( M.GE.K ) THEN** If m >= k, assume m >= n >= k*CALL DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )*ELSE** If m < k, assume m = n** Shift the vectors which define the elementary reflectors one* column to the right, and set the first row and column of Q* to those of the unit matrix*DO 20 J = M, 2, -1A( 1, J ) = ZERODO 10 I = J + 1, MA( I, J ) = A( I, J-1 )10 CONTINUE20 CONTINUEA( 1, 1 ) = ONEDO 30 I = 2, MA( I, 1 ) = ZERO30 CONTINUEIF( M.GT.1 ) THEN** Form Q(2:m,2:m)*CALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,$ LWORK, IINFO )END IFEND IFELSE** Form P', determined by a call to DGEBRD to reduce a k-by-n* matrix*IF( K.LT.N ) THEN** If k < n, assume k <= m <= n*CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )*ELSE** If k >= n, assume m = n** Shift the vectors which define the elementary reflectors one* row downward, and set the first row and column of P' to* those of the unit matrix*A( 1, 1 ) = ONEDO 40 I = 2, NA( I, 1 ) = ZERO40 CONTINUEDO 60 J = 2, NDO 50 I = J - 1, 2, -1A( I, J ) = A( I-1, J )50 CONTINUEA( 1, J ) = ZERO60 CONTINUEIF( N.GT.1 ) THEN** Form P'(2:n,2:n)*CALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,$ LWORK, IINFO )END IFEND IFEND IFWORK( 1 ) = LWKOPTRETURN** End of DORGBR*ENDSUBROUTINE DORGHR( 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* =======** DORGHR generates a real orthogonal matrix Q which is defined as the* product of IHI-ILO elementary reflectors of order N, as returned by* DGEHRD:** Q = H(ilo) H(ilo+1) . . . H(ihi-1).** Arguments* =========** N (input) INTEGER* The order of the matrix Q. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* ILO and IHI must have the same values as in the previous call* of DGEHRD. Q is equal to the unit matrix except in the* submatrix Q(ilo+1:ihi,ilo+1:ihi).* 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 vectors which define the elementary reflectors,* as returned by DGEHRD.* On exit, the N-by-N orthogonal matrix Q.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** TAU (input) DOUBLE PRECISION array, dimension (N-1)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEHRD.** 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 >= IHI-ILO.* For optimum performance LWORK >= (IHI-ILO)*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** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IINFO, J, LWKOPT, NB, NH* ..* .. External Subroutines ..EXTERNAL DORGQR, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NH = IHI - ILOLQUERY = ( 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, NH ) .AND. .NOT.LQUERY ) THENINFO = -8END IF*IF( INFO.EQ.0 ) THENNB = ILAENV( 1, 'DORGQR', ' ', NH, NH, NH, -1 )LWKOPT = MAX( 1, NH )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGHR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF** Shift the vectors which define the elementary reflectors one* column to the right, and set the first ilo and the last n-ihi* rows and columns to those of the unit matrix*DO 40 J = IHI, ILO + 1, -1DO 10 I = 1, J - 1A( I, J ) = ZERO10 CONTINUEDO 20 I = J + 1, IHIA( I, J ) = A( I, J-1 )20 CONTINUEDO 30 I = IHI + 1, NA( I, J ) = ZERO30 CONTINUE40 CONTINUEDO 60 J = 1, ILODO 50 I = 1, NA( I, J ) = ZERO50 CONTINUEA( J, J ) = ONE60 CONTINUEDO 80 J = IHI + 1, NDO 70 I = 1, NA( I, J ) = ZERO70 CONTINUEA( J, J ) = ONE80 CONTINUE*IF( NH.GT.0 ) THEN** Generate Q(ilo+1:ihi,ilo+1:ihi)*CALL DORGQR( NH, NH, NH, A( ILO+1, ILO+1 ), LDA, TAU( ILO ),$ WORK, LWORK, IINFO )END IFWORK( 1 ) = LWKOPTRETURN** End of DORGHR*ENDSUBROUTINE DORGL2( M, N, K, 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* June 30, 1999** .. Scalar Arguments ..INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORGL2 generates an m by n real matrix Q with orthonormal rows,* which is defined as the first m rows of a product of k elementary* reflectors of order n** Q = H(k) . . . H(2) H(1)** as returned by DGELQF.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix Q. M >= 0.** N (input) INTEGER* The number of columns of the matrix Q. N >= M.** K (input) INTEGER* The number of elementary reflectors whose product defines the* matrix Q. M >= K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the i-th row must contain the vector which defines* the elementary reflector H(i), for i = 1,2,...,k, as returned* by DGELQF in the first k rows of its array argument A.* On exit, the m-by-n matrix Q.** LDA (input) INTEGER* The first dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGELQF.** WORK (workspace) DOUBLE PRECISION array, dimension (M)** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument has an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGL2', -INFO )RETURNEND IF** Quick return if possible*IF( M.LE.0 )$ RETURN*IF( K.LT.M ) THEN** Initialise rows k+1:m to rows of the unit matrix*DO 20 J = 1, NDO 10 L = K + 1, MA( L, J ) = ZERO10 CONTINUEIF( J.GT.K .AND. J.LE.M )$ A( J, J ) = ONE20 CONTINUEEND IF*DO 40 I = K, 1, -1** Apply H(i) to A(i:m,i:n) from the right*IF( I.LT.N ) THENIF( I.LT.M ) THENA( I, I ) = ONECALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,$ TAU( I ), A( I+1, I ), LDA, WORK )END IFCALL DSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA )END IFA( I, I ) = ONE - TAU( I )** Set A(i,1:i-1) to zero*DO 30 L = 1, I - 1A( I, L ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORGL2*ENDSUBROUTINE DORGLQ( M, N, K, 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, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORGLQ generates an M-by-N real matrix Q with orthonormal rows,* which is defined as the first M rows of a product of K elementary* reflectors of order N** Q = H(k) . . . H(2) H(1)** as returned by DGELQF.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix Q. M >= 0.** N (input) INTEGER* The number of columns of the matrix Q. N >= M.** K (input) INTEGER* The number of elementary reflectors whose product defines the* matrix Q. M >= K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the i-th row must contain the vector which defines* the elementary reflector H(i), for i = 1,2,...,k, as returned* by DGELQF in the first k rows of its array argument A.* On exit, the M-by-N matrix Q.** LDA (input) INTEGER* The first dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGELQF.** 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 has an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,$ LWKOPT, NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORGL2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 )LWKOPT = MAX( 1, M )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGLQ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.LE.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, 'DORGLQ', ' ', M, N, K, -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, 'DORGLQ', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the last block.* The first kk rows are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )** Set A(kk+1:m,1:kk) to zero.*DO 20 J = 1, KKDO 10 I = KK + 1, MA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the last or only block.*IF( KK.LT.M )$ CALL DORGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,$ TAU( KK+1 ), WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = KI + 1, 1, -NBIB = MIN( NB, K-I+1 )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', '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 IF** Apply H' to columns i:n of current block*CALL DORGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )** Set columns 1:i-1 of current block to zero*DO 40 J = 1, I - 1DO 30 L = I, I + IB - 1A( L, J ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGLQ*ENDSUBROUTINE DORGQL( M, N, K, 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, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORGQL generates an M-by-N real matrix Q with orthonormal columns,* which is defined as the last N columns of a product of K elementary* reflectors of order M** Q = H(k) . . . H(2) H(1)** as returned by DGEQLF.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix Q. M >= 0.** N (input) INTEGER* The number of columns of the matrix Q. M >= N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines the* matrix Q. N >= K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the (n-k+i)-th column must contain the vector which* defines the elementary reflector H(i), for i = 1,2,...,k, as* returned by DGEQLF in the last k columns of its array* argument A.* On exit, the M-by-N matrix Q.** LDA (input) INTEGER* The first dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEQLF.** 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 has an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT,$ NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORG2L, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DORGQL', ' ', M, N, K, -1 )LWKOPT = MAX( 1, N )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGQL', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.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, 'DORGQL', ' ', M, N, K, -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, 'DORGQL', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the first block.* The last kk columns are handled by the block method.*KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )** Set A(m-kk+1:m,1:n-kk) to zero.*DO 20 J = 1, N - KKDO 10 I = M - KK + 1, MA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the first or only block.*CALL DORG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = K - KK + 1, K, NBIB = MIN( NB, K-I+1 )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', 'No 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 IF** Apply H to rows 1:m-k+i+ib-1 of current block*CALL DORG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA,$ TAU( I ), WORK, IINFO )** Set rows m-k+i+ib:m of current block to zero*DO 40 J = N - K + I, N - K + I + IB - 1DO 30 L = M - K + I + IB, MA( L, J ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGQL*ENDSUBROUTINE DORGQR( M, N, K, 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, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORGQR generates an M-by-N real matrix Q with orthonormal columns,* which is defined as the first N columns of a product of K elementary* reflectors of order M** Q = H(1) H(2) . . . H(k)** as returned by DGEQRF.** Arguments* =========** M (input) INTEGER* The number of rows of the matrix Q. M >= 0.** N (input) INTEGER* The number of columns of the matrix Q. M >= N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines the* matrix Q. N >= K >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the i-th column must contain the vector which* defines the elementary reflector H(i), for i = 1,2,...,k, as* returned by DGEQRF in the first k columns of its array* argument A.* On exit, the M-by-N matrix Q.** LDA (input) INTEGER* The first dimension of the array A. LDA >= max(1,M).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEQRF.** 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 has an illegal value** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,$ LWKOPT, NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORG2R, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 )LWKOPT = MAX( 1, N )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGQR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.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, 'DORGQR', ' ', M, N, K, -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, 'DORGQR', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the last block.* The first kk columns are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )** Set A(1:kk,kk+1:n) to zero.*DO 20 J = KK + 1, NDO 10 I = 1, KKA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the last or only block.*IF( KK.LT.N )$ CALL DORG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,$ TAU( KK+1 ), WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = KI + 1, 1, -NBIB = MIN( NB, K-I+1 )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', 'No 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 IF** Apply H to rows i:m of current block*CALL DORG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )** Set rows 1:i-1 of current block to zero*DO 40 J = I, I + IB - 1DO 30 L = 1, I - 1A( L, J ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGQR*ENDSUBROUTINE DORGTR( UPLO, 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 ..CHARACTER UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORGTR generates a real orthogonal matrix Q which is defined as the* product of n-1 elementary reflectors of order N, as returned by* DSYTRD:** if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),** if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).** Arguments* =========** UPLO (input) CHARACTER*1* = 'U': Upper triangle of A contains elementary reflectors* from DSYTRD;* = 'L': Lower triangle of A contains elementary reflectors* from DSYTRD.** N (input) INTEGER* The order of the matrix Q. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the vectors which define the elementary reflectors,* as returned by DSYTRD.* On exit, the N-by-N orthogonal matrix Q.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** TAU (input) DOUBLE PRECISION array, dimension (N-1)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DSYTRD.** 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-1).* For optimum performance LWORK >= (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** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPERINTEGER I, IINFO, J, LWKOPT, NB* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORGQL, DORGQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THENINFO = -7END IF*IF( INFO.EQ.0 ) THENIF( UPPER ) THENNB = ILAENV( 1, 'DORGQL', ' ', N-1, N-1, N-1, -1 )ELSENB = ILAENV( 1, 'DORGQR', ' ', N-1, N-1, N-1, -1 )END IFLWKOPT = MAX( 1, N-1 )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGTR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( UPPER ) THEN** Q was determined by a call to DSYTRD with UPLO = 'U'** Shift the vectors which define the elementary reflectors one* column to the left, and set the last row and column of Q to* those of the unit matrix*DO 20 J = 1, N - 1DO 10 I = 1, J - 1A( I, J ) = A( I, J+1 )10 CONTINUEA( N, J ) = ZERO20 CONTINUEDO 30 I = 1, N - 1A( I, N ) = ZERO30 CONTINUEA( N, N ) = ONE** Generate Q(1:n-1,1:n-1)*CALL DORGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, IINFO )*ELSE** Q was determined by a call to DSYTRD with UPLO = 'L'.** Shift the vectors which define the elementary reflectors one* column to the right, and set the first row and column of Q to* those of the unit matrix*DO 50 J = N, 2, -1A( 1, J ) = ZERODO 40 I = J + 1, NA( I, J ) = A( I, J-1 )40 CONTINUE50 CONTINUEA( 1, 1 ) = ONEDO 60 I = 2, NA( I, 1 ) = ZERO60 CONTINUEIF( N.GT.1 ) THEN** Generate Q(2:n,2:n)*CALL DORGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,$ LWORK, IINFO )END IFEND IFWORK( 1 ) = LWKOPTRETURN** End of DORGTR*ENDSUBROUTINE DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, 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* February 29, 1992** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORM2R overwrites the general real m by n matrix C with** Q * C if SIDE = 'L' and TRANS = 'N', or** Q'* C if SIDE = 'L' and TRANS = 'T', or** C * Q if SIDE = 'R' and TRANS = 'N', or** C * Q' if SIDE = 'R' and TRANS = 'T',** where Q is a real orthogonal matrix defined as the product of k* elementary reflectors** Q = H(1) H(2) . . . H(k)** as returned by DGEQRF. Q is of order m if SIDE = 'L' and of order n* if SIDE = 'R'.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': apply Q or Q' from the Left* = 'R': apply Q or Q' from the Right** TRANS (input) CHARACTER*1* = 'N': apply Q (No transpose)* = 'T': apply Q' (Transpose)** M (input) INTEGER* The number of rows of the matrix C. M >= 0.** N (input) INTEGER* The number of columns of the matrix C. N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines* the matrix Q.* If SIDE = 'L', M >= K >= 0;* if SIDE = 'R', N >= K >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,K)* The i-th column must contain the vector which defines the* elementary reflector H(i), for i = 1,2,...,k, as returned by* DGEQRF in the first k columns of its array argument A.* A is modified by the routine but restored on exit.** LDA (input) INTEGER* The leading dimension of the array A.* If SIDE = 'L', LDA >= max(1,M);* if SIDE = 'R', LDA >= max(1,N).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEQRF.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the m by n matrix C.* On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** WORK (workspace) DOUBLE PRECISION array, dimension* (N) if SIDE = 'L',* (M) if SIDE = 'R'** 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 LEFT, NOTRANINTEGER I, I1, I2, I3, IC, JC, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORM2R', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. ( .NOT.LEFT .AND. NOTRAN ) )$ THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H(i) is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H(i)*AII = A( I, I )A( I, I ) = ONECALL DLARF( SIDE, MI, NI, A( I, I ), 1, TAU( I ), C( IC, JC ),$ LDC, WORK )A( I, I ) = AII10 CONTINUERETURN** End of DORM2R*ENDSUBROUTINE DORMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,$ LDC, 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 SIDE, TRANS, VECTINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** Purpose* =======** If VECT = 'Q', DORMBR overwrites the general real M-by-N matrix C* with* SIDE = 'L' SIDE = 'R'* TRANS = 'N': Q * C C * Q* TRANS = 'T': Q**T * C C * Q**T** If VECT = 'P', DORMBR overwrites the general real M-by-N matrix C* with* SIDE = 'L' SIDE = 'R'* TRANS = 'N': P * C C * P* TRANS = 'T': P**T * C C * P**T** Here Q and P**T are the orthogonal matrices determined by DGEBRD when* reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and* P**T are defined as products of elementary reflectors H(i) and G(i)* respectively.** Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the* order of the orthogonal matrix Q or P**T that is applied.** If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:* if nq >= k, Q = H(1) H(2) . . . H(k);* if nq < k, Q = H(1) H(2) . . . H(nq-1).** If VECT = 'P', A is assumed to have been a K-by-NQ matrix:* if k < nq, P = G(1) G(2) . . . G(k);* if k >= nq, P = G(1) G(2) . . . G(nq-1).** Arguments* =========** VECT (input) CHARACTER*1* = 'Q': apply Q or Q**T;* = 'P': apply P or P**T.** SIDE (input) CHARACTER*1* = 'L': apply Q, Q**T, P or P**T from the Left;* = 'R': apply Q, Q**T, P or P**T from the Right.** TRANS (input) CHARACTER*1* = 'N': No transpose, apply Q or P;* = 'T': Transpose, apply Q**T or P**T.** M (input) INTEGER* The number of rows of the matrix C. M >= 0.** N (input) INTEGER* The number of columns of the matrix C. N >= 0.** K (input) INTEGER* If VECT = 'Q', the number of columns in the original* matrix reduced by DGEBRD.* If VECT = 'P', the number of rows in the original* matrix reduced by DGEBRD.* K >= 0.** A (input) DOUBLE PRECISION array, dimension* (LDA,min(nq,K)) if VECT = 'Q'* (LDA,nq) if VECT = 'P'* The vectors which define the elementary reflectors H(i) and* G(i), whose products determine the matrices Q and P, as* returned by DGEBRD.** LDA (input) INTEGER* The leading dimension of the array A.* If VECT = 'Q', LDA >= max(1,nq);* if VECT = 'P', LDA >= max(1,min(nq,K)).** TAU (input) DOUBLE PRECISION array, dimension (min(nq,K))* TAU(i) must contain the scalar factor of the elementary* reflector H(i) or G(i) which determines Q or P, as returned* by DGEBRD in the array argument TAUQ or TAUP.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the M-by-N matrix C.* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q* or P*C or P**T*C or C*P or C*P**T.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** 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.* If SIDE = 'L', LWORK >= max(1,N);* if SIDE = 'R', LWORK >= max(1,M).* For optimum performance LWORK >= N*NB if SIDE = 'L', and* LWORK >= M*NB if SIDE = 'R', 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** =====================================================================** .. Local Scalars ..LOGICAL APPLYQ, LEFT, LQUERY, NOTRANCHARACTER TRANSTINTEGER I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORMLQ, DORMQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0APPLYQ = LSAME( VECT, 'Q' )LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q or P and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THENINFO = -1ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -2ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( K.LT.0 ) THENINFO = -6ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR.$ ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) )$ THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -13END IF*IF( INFO.EQ.0 ) THENIF( APPLYQ ) THENIF( LEFT ) THENNB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M-1, N, M-1,$ -1 )ELSENB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N-1, N-1,$ -1 )END IFELSEIF( LEFT ) THENNB = ILAENV( 1, 'DORMLQ', SIDE // TRANS, M-1, N, M-1,$ -1 )ELSENB = ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N-1, N-1,$ -1 )END IFEND IFLWKOPT = MAX( 1, NW )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMBR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*WORK( 1 ) = 1IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN*IF( APPLYQ ) THEN** Apply Q*IF( NQ.GE.K ) THEN** Q was determined by a call to DGEBRD with nq >= k*CALL DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, IINFO )ELSE IF( NQ.GT.1 ) THEN** Q was determined by a call to DGEBRD with nq < k*IF( LEFT ) THENMI = M - 1NI = NI1 = 2I2 = 1ELSEMI = MNI = N - 1I1 = 1I2 = 2END IFCALL DORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,$ C( I1, I2 ), LDC, WORK, LWORK, IINFO )END IFELSE** Apply P*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IFIF( NQ.GT.K ) THEN** P was determined by a call to DGEBRD with nq > k*CALL DORMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, IINFO )ELSE IF( NQ.GT.1 ) THEN** P was determined by a call to DGEBRD with nq <= k*IF( LEFT ) THENMI = M - 1NI = NI1 = 2I2 = 1ELSEMI = MNI = N - 1I1 = 1I2 = 2END IFCALL DORMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA,$ TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO )END IFEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMBR*ENDSUBROUTINE DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, 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* February 29, 1992** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORML2 overwrites the general real m by n matrix C with** Q * C if SIDE = 'L' and TRANS = 'N', or** Q'* C if SIDE = 'L' and TRANS = 'T', or** C * Q if SIDE = 'R' and TRANS = 'N', or** C * Q' if SIDE = 'R' and TRANS = 'T',** where Q is a real orthogonal matrix defined as the product of k* elementary reflectors** Q = H(k) . . . H(2) H(1)** as returned by DGELQF. Q is of order m if SIDE = 'L' and of order n* if SIDE = 'R'.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': apply Q or Q' from the Left* = 'R': apply Q or Q' from the Right** TRANS (input) CHARACTER*1* = 'N': apply Q (No transpose)* = 'T': apply Q' (Transpose)** M (input) INTEGER* The number of rows of the matrix C. M >= 0.** N (input) INTEGER* The number of columns of the matrix C. N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines* the matrix Q.* If SIDE = 'L', M >= K >= 0;* if SIDE = 'R', N >= K >= 0.** A (input) DOUBLE PRECISION array, dimension* (LDA,M) if SIDE = 'L',* (LDA,N) if SIDE = 'R'* The i-th row must contain the vector which defines the* elementary reflector H(i), for i = 1,2,...,k, as returned by* DGELQF in the first k rows of its array argument A.* A is modified by the routine but restored on exit.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,K).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGELQF.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the m by n matrix C.* On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** WORK (workspace) DOUBLE PRECISION array, dimension* (N) if SIDE = 'L',* (M) if SIDE = 'R'** 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 LEFT, NOTRANINTEGER I, I1, I2, I3, IC, JC, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORML2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) )$ THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H(i) is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H(i)*AII = A( I, I )A( I, I ) = ONECALL DLARF( SIDE, MI, NI, A( I, I ), LDA, TAU( I ),$ C( IC, JC ), LDC, WORK )A( I, I ) = AII10 CONTINUERETURN** End of DORML2*ENDSUBROUTINE DORMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ 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 SIDE, TRANSINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORMLQ overwrites the general real M-by-N matrix C with** SIDE = 'L' SIDE = 'R'* TRANS = 'N': Q * C C * Q* TRANS = 'T': Q**T * C C * Q**T** where Q is a real orthogonal matrix defined as the product of k* elementary reflectors** Q = H(k) . . . H(2) H(1)** as returned by DGELQF. Q is of order M if SIDE = 'L' and of order N* if SIDE = 'R'.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': apply Q or Q**T from the Left;* = 'R': apply Q or Q**T from the Right.** TRANS (input) CHARACTER*1* = 'N': No transpose, apply Q;* = 'T': Transpose, apply Q**T.** M (input) INTEGER* The number of rows of the matrix C. M >= 0.** N (input) INTEGER* The number of columns of the matrix C. N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines* the matrix Q.* If SIDE = 'L', M >= K >= 0;* if SIDE = 'R', N >= K >= 0.** A (input) DOUBLE PRECISION array, dimension* (LDA,M) if SIDE = 'L',* (LDA,N) if SIDE = 'R'* The i-th row must contain the vector which defines the* elementary reflector H(i), for i = 1,2,...,k, as returned by* DGELQF in the first k rows of its array argument A.* A is modified by the routine but restored on exit.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,K).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGELQF.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the M-by-N matrix C.* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** 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.* If SIDE = 'L', LWORK >= max(1,N);* if SIDE = 'R', LWORK >= max(1,M).* For optimum performance LWORK >= N*NB if SIDE = 'L', and* LWORK >= M*NB if SIDE = 'R', 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** =====================================================================** .. Parameters ..INTEGER NBMAX, LDTPARAMETER ( NBMAX = 64, LDT = NBMAX+1 )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANCHARACTER TRANSTINTEGER I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,$ LWKOPT, MI, NB, NBMIN, NI, NQ, NW* ..* .. Local Arrays ..DOUBLE PRECISION T( LDT, NBMAX )* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORML2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THEN** Determine the block size. NB may be at most NBMAX, where NBMAX* is used to define the local array T.*NB = MIN( NBMAX, ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N, K,$ -1 ) )LWKOPT = MAX( 1, NW )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMLQ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIWS = NW*NBIF( LWORK.LT.IWS ) THENNB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMLQ', SIDE // TRANS, M, N, K,$ -1 ) )END IFELSEIWS = NWEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,$ IINFO )ELSE** Use blocked code*IF( ( LEFT .AND. NOTRAN ) .OR.$ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),$ LDA, TAU( I ), T, LDT )IF( LEFT ) THEN** H or H' is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H or H' is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H or H'*CALL DLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,$ A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK,$ LDWORK )10 CONTINUEEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMLQ*ENDSUBROUTINE DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ 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 SIDE, TRANSINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** Purpose* =======** DORMQR overwrites the general real M-by-N matrix C with** SIDE = 'L' SIDE = 'R'* TRANS = 'N': Q * C C * Q* TRANS = 'T': Q**T * C C * Q**T** where Q is a real orthogonal matrix defined as the product of k* elementary reflectors** Q = H(1) H(2) . . . H(k)** as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N* if SIDE = 'R'.** Arguments* =========** SIDE (input) CHARACTER*1* = 'L': apply Q or Q**T from the Left;* = 'R': apply Q or Q**T from the Right.** TRANS (input) CHARACTER*1* = 'N': No transpose, apply Q;* = 'T': Transpose, apply Q**T.** M (input) INTEGER* The number of rows of the matrix C. M >= 0.** N (input) INTEGER* The number of columns of the matrix C. N >= 0.** K (input) INTEGER* The number of elementary reflectors whose product defines* the matrix Q.* If SIDE = 'L', M >= K >= 0;* if SIDE = 'R', N >= K >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,K)* The i-th column must contain the vector which defines the* elementary reflector H(i), for i = 1,2,...,k, as returned by* DGEQRF in the first k columns of its array argument A.* A is modified by the routine but restored on exit.** LDA (input) INTEGER* The leading dimension of the array A.* If SIDE = 'L', LDA >= max(1,M);* if SIDE = 'R', LDA >= max(1,N).** TAU (input) DOUBLE PRECISION array, dimension (K)* TAU(i) must contain the scalar factor of the elementary* reflector H(i), as returned by DGEQRF.** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the M-by-N matrix C.* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M).** 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.* If SIDE = 'L', LWORK >= max(1,N);* if SIDE = 'R', LWORK >= max(1,M).* For optimum performance LWORK >= N*NB if SIDE = 'L', and* LWORK >= M*NB if SIDE = 'R', 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** =====================================================================** .. Parameters ..INTEGER NBMAX, LDTPARAMETER ( NBMAX = 64, LDT = NBMAX+1 )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANINTEGER I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK,$ LWKOPT, MI, NB, NBMIN, NI, NQ, NW* ..* .. Local Arrays ..DOUBLE PRECISION T( LDT, NBMAX )* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORM2R, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THEN** Determine the block size. NB may be at most NBMAX, where NBMAX* is used to define the local array T.*NB = MIN( NBMAX, ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N, K,$ -1 ) )LWKOPT = MAX( 1, NW )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMQR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIWS = NW*NBIF( LWORK.LT.IWS ) THENNB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMQR', SIDE // TRANS, M, N, K,$ -1 ) )END IFELSEIWS = NWEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,$ IINFO )ELSE** Use blocked code*IF( ( LEFT .AND. .NOT.NOTRAN ) .OR.$ ( .NOT.LEFT .AND. NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ),$ LDA, TAU( I ), T, LDT )IF( LEFT ) THEN** H or H' is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H or H' is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H or H'*CALL DLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI,$ IB, A( I, I ), LDA, T, LDT, C( IC, JC ), LDC,$ WORK, LDWORK )10 CONTINUEEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMQR*ENDSUBROUTINE DRSCL( N, SA, SX, INCX )** -- LAPACK auxiliary 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 INCX, NDOUBLE PRECISION SA* ..* .. Array Arguments ..DOUBLE PRECISION SX( * )* ..** Purpose* =======** DRSCL multiplies an n-element real vector x by the real scalar 1/a.* This is done without overflow or underflow as long as* the final result x/a does not overflow or underflow.** Arguments* =========** N (input) INTEGER* The number of components of the vector x.** SA (input) DOUBLE PRECISION* The scalar a which is used to divide each component of x.* SA must be >= 0, or the subroutine will divide by zero.** SX (input/output) DOUBLE PRECISION array, dimension* (1+(N-1)*abs(INCX))* The n-element vector x.** INCX (input) INTEGER* The increment between successive values of the vector SX.* > 0: SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i), 1< i<= n** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL DONEDOUBLE PRECISION BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DSCAL* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 )$ RETURN** Get machine parameters*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Initialize the denominator to SA and the numerator to 1.*CDEN = SACNUM = ONE*10 CONTINUECDEN1 = CDEN*SMLNUMCNUM1 = CNUM / BIGNUMIF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN** Pre-multiply X by SMLNUM if CDEN is large compared to CNUM.*MUL = SMLNUMDONE = .FALSE.CDEN = CDEN1ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN** Pre-multiply X by BIGNUM if CDEN is small compared to CNUM.*MUL = BIGNUMDONE = .FALSE.CNUM = CNUM1ELSE** Multiply X by CNUM / CDEN and return.*MUL = CNUM / CDENDONE = .TRUE.END IF** Scale the vector X by MUL*CALL DSCAL( N, MUL, SX, INCX )*IF( .NOT.DONE )$ GO TO 10*RETURN** End of DRSCL*ENDSUBROUTINE DSTEQR( COMPZ, N, D, E, Z, LDZ, 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 COMPZINTEGER INFO, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..** Purpose* =======** DSTEQR computes all eigenvalues and, optionally, eigenvectors of a* symmetric tridiagonal matrix using the implicit QL or QR method.* The eigenvectors of a full or band symmetric matrix can also be found* if DSYTRD or DSPTRD or DSBTRD has been used to reduce this matrix to* tridiagonal form.** Arguments* =========** COMPZ (input) CHARACTER*1* = 'N': Compute eigenvalues only.* = 'V': Compute eigenvalues and eigenvectors of the original* symmetric matrix. On entry, Z must contain the* orthogonal matrix used to reduce the original matrix* to tridiagonal form.* = 'I': Compute eigenvalues and eigenvectors of the* tridiagonal matrix. Z is initialized to the identity* matrix.** N (input) INTEGER* The order of the matrix. N >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the diagonal elements of the tridiagonal matrix.* On exit, if INFO = 0, the eigenvalues in ascending order.** E (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, the (n-1) subdiagonal elements of the tridiagonal* matrix.* On exit, E has been destroyed.** Z (input/output) DOUBLE PRECISION array, dimension (LDZ, N)* On entry, if COMPZ = 'V', then Z contains the orthogonal* matrix used in the reduction to tridiagonal form.* On exit, if INFO = 0, then if COMPZ = 'V', Z contains the* orthonormal eigenvectors of the original symmetric matrix,* and if COMPZ = 'I', Z contains the orthonormal eigenvectors* of the symmetric tridiagonal matrix.* If COMPZ = 'N', then Z is not referenced.** LDZ (input) INTEGER* The leading dimension of the array Z. LDZ >= 1, and if* eigenvectors are desired, then LDZ >= max(1,N).** WORK (workspace) DOUBLE PRECISION array, dimension (max(1,2*N-2))* If COMPZ = 'N', then WORK is not referenced.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: the algorithm has failed to find all the eigenvalues in* a total of 30*N iterations; if INFO = i, then i* elements of E have not converged to zero; on exit, D* and E contain the elements of a symmetric tridiagonal* matrix which is orthogonally similar to the original* matrix.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, THREEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0 )INTEGER MAXITPARAMETER ( MAXIT = 30 )* ..* .. Local Scalars ..INTEGER I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,$ LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,$ NM1, NMAXITDOUBLE PRECISION ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,$ S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANST, DLAPY2EXTERNAL LSAME, DLAMCH, DLANST, DLAPY2* ..* .. External Subroutines ..EXTERNAL DLAE2, DLAEV2, DLARTG, DLASCL, DLASET, DLASR,$ DLASRT, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( LSAME( COMPZ, 'N' ) ) THENICOMPZ = 0ELSE IF( LSAME( COMPZ, 'V' ) ) THENICOMPZ = 1ELSE IF( LSAME( COMPZ, 'I' ) ) THENICOMPZ = 2ELSEICOMPZ = -1END IFIF( ICOMPZ.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,$ N ) ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEQR', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ICOMPZ.EQ.2 )$ Z( 1, 1 ) = ONERETURNEND IF** Determine the unit roundoff and over/underflow thresholds.*EPS = DLAMCH( 'E' )EPS2 = EPS**2SAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINSSFMAX = SQRT( SAFMAX ) / THREESSFMIN = SQRT( SAFMIN ) / EPS2** Compute the eigenvalues and eigenvectors of the tridiagonal* matrix.*IF( ICOMPZ.EQ.2 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )*NMAXIT = N*MAXITJTOT = 0** Determine where the matrix splits and choose QL or QR iteration* for each block, according to whether top or bottom diagonal* element is smaller.*L1 = 1NM1 = N - 1*10 CONTINUEIF( L1.GT.N )$ GO TO 160IF( L1.GT.1 )$ E( L1-1 ) = ZEROIF( L1.LE.NM1 ) THENDO 20 M = L1, NM1TST = ABS( E( M ) )IF( TST.EQ.ZERO )$ GO TO 30IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+$ 1 ) ) ) )*EPS ) THENE( M ) = ZEROGO TO 30END IF20 CONTINUEEND IFM = N*30 CONTINUEL = L1LSV = LLEND = MLENDSV = LENDL1 = M + 1IF( LEND.EQ.L )$ GO TO 10** Scale submatrix in rows and columns L to LEND*ANORM = DLANST( 'I', LEND-L+1, D( L ), E( L ) )ISCALE = 0IF( ANORM.EQ.ZERO )$ GO TO 10IF( ANORM.GT.SSFMAX ) THENISCALE = 1CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,$ INFO )ELSE IF( ANORM.LT.SSFMIN ) THENISCALE = 2CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,$ INFO )END IF** Choose between QL and QR iteration*IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THENLEND = LSVL = LENDSVEND IF*IF( LEND.GT.L ) THEN** QL Iteration** Look for small subdiagonal element.*40 CONTINUEIF( L.NE.LEND ) THENLENDM1 = LEND - 1DO 50 M = L, LENDM1TST = ABS( E( M ) )**2IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+$ SAFMIN )GO TO 6050 CONTINUEEND IF*M = LEND*60 CONTINUEIF( M.LT.LEND )$ E( M ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 80** If remaining matrix is 2-by-2, use DLAE2 or SLAEV2* to compute its eigensystem.*IF( M.EQ.L+1 ) THENIF( ICOMPZ.GT.0 ) THENCALL DLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )WORK( L ) = CWORK( N-1+L ) = SCALL DLASR( 'R', 'V', 'B', N, 2, WORK( L ),$ WORK( N-1+L ), Z( 1, L ), LDZ )ELSECALL DLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )END IFD( L ) = RT1D( L+1 ) = RT2E( L ) = ZEROL = L + 2IF( L.LE.LEND )$ GO TO 40GO TO 140END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 140JTOT = JTOT + 1** Form shift.*G = ( D( L+1 )-P ) / ( TWO*E( L ) )R = DLAPY2( G, ONE )G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )*S = ONEC = ONEP = ZERO** Inner loop*MM1 = M - 1DO 70 I = MM1, L, -1F = S*E( I )B = C*E( I )CALL DLARTG( G, F, C, S, R )IF( I.NE.M-1 )$ E( I+1 ) = RG = D( I+1 ) - PR = ( D( I )-G )*S + TWO*C*BP = S*RD( I+1 ) = G + PG = C*R - B** If eigenvectors are desired, then save rotations.*IF( ICOMPZ.GT.0 ) THENWORK( I ) = CWORK( N-1+I ) = -SEND IF*70 CONTINUE** If eigenvectors are desired, then apply saved rotations.*IF( ICOMPZ.GT.0 ) THENMM = M - L + 1CALL DLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),$ Z( 1, L ), LDZ )END IF*D( L ) = D( L ) - PE( L ) = GGO TO 40** Eigenvalue found.*80 CONTINUED( L ) = P*L = L + 1IF( L.LE.LEND )$ GO TO 40GO TO 140*ELSE** QR Iteration** Look for small superdiagonal element.*90 CONTINUEIF( L.NE.LEND ) THENLENDP1 = LEND + 1DO 100 M = L, LENDP1, -1TST = ABS( E( M-1 ) )**2IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+$ SAFMIN )GO TO 110100 CONTINUEEND IF*M = LEND*110 CONTINUEIF( M.GT.LEND )$ E( M-1 ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 130** If remaining matrix is 2-by-2, use DLAE2 or SLAEV2* to compute its eigensystem.*IF( M.EQ.L-1 ) THENIF( ICOMPZ.GT.0 ) THENCALL DLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )WORK( M ) = CWORK( N-1+M ) = SCALL DLASR( 'R', 'V', 'F', N, 2, WORK( M ),$ WORK( N-1+M ), Z( 1, L-1 ), LDZ )ELSECALL DLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )END IFD( L-1 ) = RT1D( L ) = RT2E( L-1 ) = ZEROL = L - 2IF( L.GE.LEND )$ GO TO 90GO TO 140END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 140JTOT = JTOT + 1** Form shift.*G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )R = DLAPY2( G, ONE )G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )*S = ONEC = ONEP = ZERO** Inner loop*LM1 = L - 1DO 120 I = M, LM1F = S*E( I )B = C*E( I )CALL DLARTG( G, F, C, S, R )IF( I.NE.M )$ E( I-1 ) = RG = D( I ) - PR = ( D( I+1 )-G )*S + TWO*C*BP = S*RD( I ) = G + PG = C*R - B** If eigenvectors are desired, then save rotations.*IF( ICOMPZ.GT.0 ) THENWORK( I ) = CWORK( N-1+I ) = SEND IF*120 CONTINUE** If eigenvectors are desired, then apply saved rotations.*IF( ICOMPZ.GT.0 ) THENMM = L - M + 1CALL DLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),$ Z( 1, M ), LDZ )END IF*D( L ) = D( L ) - PE( LM1 ) = GGO TO 90** Eigenvalue found.*130 CONTINUED( L ) = P*L = L - 1IF( L.GE.LEND )$ GO TO 90GO TO 140*END IF** Undo scaling if necessary*140 CONTINUEIF( ISCALE.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),$ N, INFO )ELSE IF( ISCALE.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),$ N, INFO )END IF** Check for no convergence to an eigenvalue after a total* of N*MAXIT iterations.*IF( JTOT.LT.NMAXIT )$ GO TO 10DO 150 I = 1, N - 1IF( E( I ).NE.ZERO )$ INFO = INFO + 1150 CONTINUEGO TO 190** Order eigenvalues and eigenvectors.*160 CONTINUEIF( ICOMPZ.EQ.0 ) THEN** Use Quick Sort*CALL DLASRT( 'I', N, D, INFO )*ELSE** Use Selection Sort to minimize swaps of eigenvectors*DO 180 II = 2, NI = II - 1K = IP = D( I )DO 170 J = II, NIF( D( J ).LT.P ) THENK = JP = D( J )END IF170 CONTINUEIF( K.NE.I ) THEND( K ) = D( I )D( I ) = PCALL DSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )END IF180 CONTINUEEND IF*190 CONTINUERETURN** End of DSTEQR*ENDSUBROUTINE DSTERF( N, D, E, 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 ..DOUBLE PRECISION D( * ), E( * )* ..** Purpose* =======** DSTERF computes all eigenvalues of a symmetric tridiagonal matrix* using the Pal-Walker-Kahan variant of the QL or QR algorithm.** Arguments* =========** N (input) INTEGER* The order of the matrix. N >= 0.** D (input/output) DOUBLE PRECISION array, dimension (N)* On entry, the n diagonal elements of the tridiagonal matrix.* On exit, if INFO = 0, the eigenvalues in ascending order.** E (input/output) DOUBLE PRECISION array, dimension (N-1)* On entry, the (n-1) subdiagonal elements of the tridiagonal* matrix.* On exit, E has been destroyed.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: the algorithm failed to find all of the eigenvalues in* a total of 30*N iterations; if INFO = i, then i* elements of E have not converged to zero.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, THREEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0 )INTEGER MAXITPARAMETER ( MAXIT = 30 )* ..* .. Local Scalars ..INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,$ NMAXITDOUBLE PRECISION ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,$ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,$ SIGMA, SSFMAX, SSFMIN* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLANST, DLAPY2EXTERNAL DLAMCH, DLANST, DLAPY2* ..* .. External Subroutines ..EXTERNAL DLAE2, DLASCL, DLASRT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0** Quick return if possible*IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DSTERF', -INFO )RETURNEND IFIF( N.LE.1 )$ RETURN** Determine the unit roundoff for this environment.*EPS = DLAMCH( 'E' )EPS2 = EPS**2SAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINSSFMAX = SQRT( SAFMAX ) / THREESSFMIN = SQRT( SAFMIN ) / EPS2** Compute the eigenvalues of the tridiagonal matrix.*NMAXIT = N*MAXITSIGMA = ZEROJTOT = 0** Determine where the matrix splits and choose QL or QR iteration* for each block, according to whether top or bottom diagonal* element is smaller.*L1 = 1*10 CONTINUEIF( L1.GT.N )$ GO TO 170IF( L1.GT.1 )$ E( L1-1 ) = ZERODO 20 M = L1, N - 1IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+$ 1 ) ) ) )*EPS ) THENE( M ) = ZEROGO TO 30END IF20 CONTINUEM = N*30 CONTINUEL = L1LSV = LLEND = MLENDSV = LENDL1 = M + 1IF( LEND.EQ.L )$ GO TO 10** Scale submatrix in rows and columns L to LEND*ANORM = DLANST( 'I', LEND-L+1, D( L ), E( L ) )ISCALE = 0IF( ANORM.GT.SSFMAX ) THENISCALE = 1CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,$ INFO )ELSE IF( ANORM.LT.SSFMIN ) THENISCALE = 2CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,$ INFO )END IF*DO 40 I = L, LEND - 1E( I ) = E( I )**240 CONTINUE** Choose between QL and QR iteration*IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THENLEND = LSVL = LENDSVEND IF*IF( LEND.GE.L ) THEN** QL Iteration** Look for small subdiagonal element.*50 CONTINUEIF( L.NE.LEND ) THENDO 60 M = L, LEND - 1IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) )$ GO TO 7060 CONTINUEEND IFM = LEND*70 CONTINUEIF( M.LT.LEND )$ E( M ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 90** If remaining matrix is 2 by 2, use DLAE2 to compute its* eigenvalues.*IF( M.EQ.L+1 ) THENRTE = SQRT( E( L ) )CALL DLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )D( L ) = RT1D( L+1 ) = RT2E( L ) = ZEROL = L + 2IF( L.LE.LEND )$ GO TO 50GO TO 150END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 150JTOT = JTOT + 1** Form shift.*RTE = SQRT( E( L ) )SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )R = DLAPY2( SIGMA, ONE )SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )*C = ONES = ZEROGAMMA = D( M ) - SIGMAP = GAMMA*GAMMA** Inner loop*DO 80 I = M - 1, L, -1BB = E( I )R = P + BBIF( I.NE.M-1 )$ E( I+1 ) = S*ROLDC = CC = P / RS = BB / ROLDGAM = GAMMAALPHA = D( I )GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAMD( I+1 ) = OLDGAM + ( ALPHA-GAMMA )IF( C.NE.ZERO ) THENP = ( GAMMA*GAMMA ) / CELSEP = OLDC*BBEND IF80 CONTINUE*E( L ) = S*PD( L ) = SIGMA + GAMMAGO TO 50** Eigenvalue found.*90 CONTINUED( L ) = P*L = L + 1IF( L.LE.LEND )$ GO TO 50GO TO 150*ELSE** QR Iteration** Look for small superdiagonal element.*100 CONTINUEDO 110 M = L, LEND + 1, -1IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) )$ GO TO 120110 CONTINUEM = LEND*120 CONTINUEIF( M.GT.LEND )$ E( M-1 ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 140** If remaining matrix is 2 by 2, use DLAE2 to compute its* eigenvalues.*IF( M.EQ.L-1 ) THENRTE = SQRT( E( L-1 ) )CALL DLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )D( L ) = RT1D( L-1 ) = RT2E( L-1 ) = ZEROL = L - 2IF( L.GE.LEND )$ GO TO 100GO TO 150END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 150JTOT = JTOT + 1** Form shift.*RTE = SQRT( E( L-1 ) )SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )R = DLAPY2( SIGMA, ONE )SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )*C = ONES = ZEROGAMMA = D( M ) - SIGMAP = GAMMA*GAMMA** Inner loop*DO 130 I = M, L - 1BB = E( I )R = P + BBIF( I.NE.M )$ E( I-1 ) = S*ROLDC = CC = P / RS = BB / ROLDGAM = GAMMAALPHA = D( I+1 )GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAMD( I ) = OLDGAM + ( ALPHA-GAMMA )IF( C.NE.ZERO ) THENP = ( GAMMA*GAMMA ) / CELSEP = OLDC*BBEND IF130 CONTINUE*E( L-1 ) = S*PD( L ) = SIGMA + GAMMAGO TO 100** Eigenvalue found.*140 CONTINUED( L ) = P*L = L - 1IF( L.GE.LEND )$ GO TO 100GO TO 150*END IF** Undo scaling if necessary*150 CONTINUEIF( ISCALE.EQ.1 )$ CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )IF( ISCALE.EQ.2 )$ CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )** Check for no convergence to an eigenvalue after a total* of N*MAXIT iterations.*IF( JTOT.LT.NMAXIT )$ GO TO 10DO 160 I = 1, N - 1IF( E( I ).NE.ZERO )$ INFO = INFO + 1160 CONTINUEGO TO 180** Sort eigenvalues in increasing order.*170 CONTINUECALL DLASRT( 'I', N, D, INFO )*180 CONTINUERETURN** End of DSTERF*ENDSUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )** -- LAPACK driver 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 JOBZ, UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )* ..** Purpose* =======** DSYEV computes all eigenvalues and, optionally, eigenvectors of a* real symmetric matrix A.** Arguments* =========** JOBZ (input) CHARACTER*1* = 'N': Compute eigenvalues only;* = 'V': Compute eigenvalues and eigenvectors.** UPLO (input) CHARACTER*1* = 'U': Upper triangle of A is stored;* = 'L': Lower triangle of A is stored.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA, N)* On entry, the symmetric matrix A. If UPLO = 'U', the* leading N-by-N upper triangular part of A contains the* upper triangular part of the matrix A. If UPLO = 'L',* the leading N-by-N lower triangular part of A contains* the lower triangular part of the matrix A.* On exit, if JOBZ = 'V', then if INFO = 0, A contains the* orthonormal eigenvectors of the matrix A.* If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')* or the upper triangle (if UPLO='U') of A, including the* diagonal, is destroyed.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,N).** W (output) DOUBLE PRECISION array, dimension (N)* If INFO = 0, the eigenvalues in ascending order.** 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,3*N-1).* For optimal efficiency, LWORK >= (NB+2)*N,* where NB is the blocksize for DSYTRD 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, the algorithm failed to converge; i* off-diagonal elements of an intermediate tridiagonal* form did not converge to zero.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LOWER, LQUERY, WANTZINTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,$ LLWORK, LOPT, LWKOPT, NBDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, ILAENV, DLAMCH, DLANSY* ..* .. External Subroutines ..EXTERNAL DLASCL, DORGTR, DSCAL, DSTEQR, DSTERF, DSYTRD,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LOWER = LSAME( UPLO, 'L' )LQUERY = ( LWORK.EQ.-1 )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY ) THENINFO = -8END IF*IF( INFO.EQ.0 ) THENNB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )LWKOPT = MAX( 1, ( NB+2 )*N )WORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYEV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( N.EQ.1 ) THENW( 1 ) = A( 1, 1 )WORK( 1 ) = 3IF( WANTZ )$ A( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 )$ CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )** Call DSYTRD to reduce symmetric matrix to tridiagonal form.*INDE = 1INDTAU = INDE + NINDWRK = INDTAU + NLLWORK = LWORK - INDWRK + 1CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),$ WORK( INDWRK ), LLWORK, IINFO )LOPT = 2*N + WORK( INDWRK )** For eigenvalues only, call DSTERF. For eigenvectors, first call* DORGTR to generate the orthogonal matrix, then call DSTEQR.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),$ LLWORK, IINFO )CALL DSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = NELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** Set WORK(1) to optimal workspace size.*WORK( 1 ) = LWKOPT*RETURN** End of DSYEV*ENDSUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, 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 ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * )* ..** Purpose* =======** DSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal* form T by an orthogonal similarity transformation: Q' * A * Q = T.** Arguments* =========** UPLO (input) CHARACTER*1* Specifies whether the upper or lower triangular part of the* symmetric matrix A is stored:* = 'U': Upper triangular* = 'L': Lower triangular** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the symmetric matrix A. If UPLO = 'U', the leading* n-by-n upper triangular part of A contains the upper* triangular part of the matrix A, and the strictly lower* triangular part of A is not referenced. If UPLO = 'L', the* leading n-by-n lower triangular part of A contains the lower* triangular part of the matrix A, and the strictly upper* triangular part of A is not referenced.* On exit, if UPLO = 'U', the diagonal and first superdiagonal* of A are overwritten by the corresponding elements of the* tridiagonal matrix T, and the elements above the first* superdiagonal, with the array TAU, represent the orthogonal* matrix Q as a product of elementary reflectors; if UPLO* = 'L', the diagonal and first subdiagonal of A are over-* written by the corresponding elements of the tridiagonal* matrix T, 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).** D (output) DOUBLE PRECISION array, dimension (N)* The diagonal elements of the tridiagonal matrix T:* D(i) = A(i,i).** E (output) DOUBLE PRECISION array, dimension (N-1)* The off-diagonal elements of the tridiagonal matrix T:* E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.** TAU (output) DOUBLE PRECISION array, dimension (N-1)* The scalar factors of the elementary reflectors (see Further* Details).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.** Further Details* ===============** If UPLO = 'U', the matrix Q is represented as a product of elementary* reflectors** Q = H(n-1) . . . H(2) H(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(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in* A(1:i-1,i+1), and tau in TAU(i).** If UPLO = 'L', the matrix Q is represented as a product of elementary* reflectors** Q = H(1) H(2) . . . H(n-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 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),* and tau in TAU(i).** The contents of A on exit are illustrated by the following examples* with n = 5:** if UPLO = 'U': if UPLO = 'L':** ( d e v2 v3 v4 ) ( d )* ( d e v3 v4 ) ( e d )* ( d e v4 ) ( v1 e d )* ( d e ) ( v1 v2 e d )* ( d ) ( v1 v2 v3 e d )** where d and e denote diagonal and off-diagonal elements of T, and vi* denotes an element of the vector defining H(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZERO, HALFPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0,$ HALF = 1.0D0 / 2.0D0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER IDOUBLE PRECISION ALPHA, TAUI* ..* .. External Subroutines ..EXTERNAL DAXPY, DLARFG, DSYMV, DSYR2, XERBLA* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTD2', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN*IF( UPPER ) THEN** Reduce the upper triangle of A*DO 10 I = N - 1, 1, -1** Generate elementary reflector H(i) = I - tau * v * v'* to annihilate A(1:i-1,i+1)*CALL DLARFG( I, A( I, I+1 ), A( 1, I+1 ), 1, TAUI )E( I ) = A( I, I+1 )*IF( TAUI.NE.ZERO ) THEN** Apply H(i) from both sides to A(1:i,1:i)*A( I, I+1 ) = ONE** Compute x := tau * A * v storing x in TAU(1:i)*CALL DSYMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO,$ TAU, 1 )** Compute w := x - 1/2 * tau * (x'*v) * v*ALPHA = -HALF*TAUI*DDOT( I, TAU, 1, A( 1, I+1 ), 1 )CALL DAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )** Apply the transformation as a rank-2 update:* A := A - v * w' - w * v'*CALL DSYR2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A,$ LDA )*A( I, I+1 ) = E( I )END IFD( I+1 ) = A( I+1, I+1 )TAU( I ) = TAUI10 CONTINUED( 1 ) = A( 1, 1 )ELSE** Reduce the lower triangle of A*DO 20 I = 1, N - 1** Generate elementary reflector H(i) = I - tau * v * v'* to annihilate A(i+2:n,i)*CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,$ TAUI )E( I ) = A( I+1, I )*IF( TAUI.NE.ZERO ) THEN** Apply H(i) from both sides to A(i+1:n,i+1:n)*A( I+1, I ) = ONE** Compute x := tau * A * v storing y in TAU(i:n-1)*CALL DSYMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA,$ A( I+1, I ), 1, ZERO, TAU( I ), 1 )** Compute w := x - 1/2 * tau * (x'*v) * v*ALPHA = -HALF*TAUI*DDOT( N-I, TAU( I ), 1, A( I+1, I ),$ 1 )CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )** Apply the transformation as a rank-2 update:* A := A - v * w' - w * v'*CALL DSYR2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1,$ A( I+1, I+1 ), LDA )*A( I+1, I ) = E( I )END IFD( I ) = A( I, I )TAU( I ) = TAUI20 CONTINUED( N ) = A( N, N )END IF*RETURN** End of DSYTD2*ENDSUBROUTINE DSYTRD( UPLO, N, A, LDA, D, E, 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 ..CHARACTER UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ),$ WORK( * )* ..** Purpose* =======** DSYTRD reduces a real symmetric matrix A to real symmetric* tridiagonal form T by an orthogonal similarity transformation:* Q**T * A * Q = T.** Arguments* =========** UPLO (input) CHARACTER*1* = 'U': Upper triangle of A is stored;* = 'L': Lower triangle of A is stored.** N (input) INTEGER* The order of the matrix A. N >= 0.** A (input/output) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the symmetric matrix A. If UPLO = 'U', the leading* N-by-N upper triangular part of A contains the upper* triangular part of the matrix A, and the strictly lower* triangular part of A is not referenced. If UPLO = 'L', the* leading N-by-N lower triangular part of A contains the lower* triangular part of the matrix A, and the strictly upper* triangular part of A is not referenced.* On exit, if UPLO = 'U', the diagonal and first superdiagonal* of A are overwritten by the corresponding elements of the* tridiagonal matrix T, and the elements above the first* superdiagonal, with the array TAU, represent the orthogonal* matrix Q as a product of elementary reflectors; if UPLO* = 'L', the diagonal and first subdiagonal of A are over-* written by the corresponding elements of the tridiagonal* matrix T, 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).** D (output) DOUBLE PRECISION array, dimension (N)* The diagonal elements of the tridiagonal matrix T:* D(i) = A(i,i).** E (output) DOUBLE PRECISION array, dimension (N-1)* The off-diagonal elements of the tridiagonal matrix T:* E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.** TAU (output) DOUBLE PRECISION array, dimension (N-1)* 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 >= 1.* 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* ===============** If UPLO = 'U', the matrix Q is represented as a product of elementary* reflectors** Q = H(n-1) . . . H(2) H(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(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in* A(1:i-1,i+1), and tau in TAU(i).** If UPLO = 'L', the matrix Q is represented as a product of elementary* reflectors** Q = H(1) H(2) . . . H(n-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 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),* and tau in TAU(i).** The contents of A on exit are illustrated by the following examples* with n = 5:** if UPLO = 'U': if UPLO = 'L':** ( d e v2 v3 v4 ) ( d )* ( d e v3 v4 ) ( e d )* ( d e v4 ) ( v1 e d )* ( d e ) ( v1 v2 e d )* ( d ) ( v1 v2 v3 e d )** where d and e denote diagonal and off-diagonal elements of T, and vi* denotes an element of the vector defining H(i).** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPERINTEGER I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLATRD, DSYR2K, DSYTD2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THENINFO = -9END IF*IF( INFO.EQ.0 ) THEN** Determine the block size.*NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NX = NIWS = 1IF( NB.GT.1 .AND. NB.LT.N ) THEN** Determine when to cross over from blocked to unblocked code* (last block is always handled by unblocked code).*NX = MAX( NB, ILAENV( 3, 'DSYTRD', UPLO, N, -1, -1, -1 ) )IF( NX.LT.N ) 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: determine the* minimum value of NB, and reduce NB or force use of* unblocked code by setting NX = N.*NB = MAX( LWORK / LDWORK, 1 )NBMIN = ILAENV( 2, 'DSYTRD', UPLO, N, -1, -1, -1 )IF( NB.LT.NBMIN )$ NX = NEND IFELSENX = NEND IFELSENB = 1END IF*IF( UPPER ) THEN** Reduce the upper triangle of A.* Columns 1:kk are handled by the unblocked method.*KK = N - ( ( N-NX+NB-1 ) / NB )*NBDO 20 I = N - NB + 1, KK + 1, -NB** Reduce columns i:i+nb-1 to tridiagonal form and form the* matrix W which is needed to update the unreduced part of* the matrix*CALL DLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK,$ LDWORK )** Update the unreduced submatrix A(1:i-1,1:i-1), using an* update of the form: A := A - V*W' - W*V'*CALL DSYR2K( UPLO, 'No transpose', I-1, NB, -ONE, A( 1, I ),$ LDA, WORK, LDWORK, ONE, A, LDA )** Copy superdiagonal elements back into A, and diagonal* elements into D*DO 10 J = I, I + NB - 1A( J-1, J ) = E( J-1 )D( J ) = A( J, J )10 CONTINUE20 CONTINUE** Use unblocked code to reduce the last or only block*CALL DSYTD2( UPLO, KK, A, LDA, D, E, TAU, IINFO )ELSE** Reduce the lower triangle of A*DO 40 I = 1, N - NX, NB** Reduce columns i:i+nb-1 to tridiagonal form and form the* matrix W which is needed to update the unreduced part of* the matrix*CALL DLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ),$ TAU( I ), WORK, LDWORK )** Update the unreduced submatrix A(i+ib:n,i+ib:n), using* an update of the form: A := A - V*W' - W*V'*CALL DSYR2K( UPLO, 'No transpose', N-I-NB+1, NB, -ONE,$ A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE,$ A( I+NB, I+NB ), LDA )** Copy subdiagonal elements back into A, and diagonal* elements into D*DO 30 J = I, I + NB - 1A( J+1, J ) = E( J )D( J ) = A( J, J )30 CONTINUE40 CONTINUE** Use unblocked code to reduce the last or only block*CALL DSYTD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ),$ TAU( I ), IINFO )END IF*WORK( 1 ) = LWKOPTRETURN** End of DSYTRD*ENDSUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,$ LDVR, MM, M, WORK, 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 HOWMNY, SIDEINTEGER INFO, LDT, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),$ WORK( * )* ..** Purpose* =======** DTREVC computes some or all of the right and/or left eigenvectors of* a real upper quasi-triangular matrix T.** The right eigenvector x and the left eigenvector y of T corresponding* to an eigenvalue w are defined by:** T*x = w*x, y'*T = w*y'** where y' denotes the conjugate transpose of the vector y.** If all eigenvectors are requested, the routine may either return the* matrices X and/or Y of right or left eigenvectors of T, or the* products Q*X and/or Q*Y, where Q is an input orthogonal* matrix. If T was obtained from the real-Schur factorization of an* original matrix A = Q*T*Q', then Q*X and Q*Y are the matrices of* right or left eigenvectors of A.** T must be in Schur canonical form (as returned by DHSEQR), that is,* block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each* 2-by-2 diagonal block has its diagonal elements equal and its* off-diagonal elements of opposite sign. Corresponding to each 2-by-2* diagonal block is a complex conjugate pair of eigenvalues and* eigenvectors; only one eigenvector of the pair is computed, namely* the one corresponding to the eigenvalue with positive imaginary part.** Arguments* =========** SIDE (input) CHARACTER*1* = 'R': compute right eigenvectors only;* = 'L': compute left eigenvectors only;* = 'B': compute both right and left eigenvectors.** HOWMNY (input) CHARACTER*1* = 'A': compute all right and/or left eigenvectors;* = 'B': compute all right and/or left eigenvectors,* and backtransform them using the input matrices* supplied in VR and/or VL;* = 'S': compute selected right and/or left eigenvectors,* specified by the logical array SELECT.** SELECT (input/output) LOGICAL array, dimension (N)* If HOWMNY = 'S', SELECT specifies the eigenvectors to be* computed.* If HOWMNY = 'A' or 'B', SELECT is not referenced.* To select the real eigenvector corresponding to a real* eigenvalue w(j), SELECT(j) must be set to .TRUE.. To select* the complex eigenvector corresponding to a complex conjugate* pair w(j) and w(j+1), either SELECT(j) or SELECT(j+1) 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 T. N >= 0.** T (input) DOUBLE PRECISION array, dimension (LDT,N)* The upper quasi-triangular matrix T in Schur canonical form.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= max(1,N).** VL (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)* On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must* contain an N-by-N matrix Q (usually the orthogonal matrix Q* of Schur vectors returned by DHSEQR).* On exit, if SIDE = 'L' or 'B', VL contains:* if HOWMNY = 'A', the matrix Y of left eigenvectors of T;* VL has the same quasi-lower triangular form* as T'. If T(i,i) is a real eigenvalue, then* the i-th column VL(i) of VL is its* corresponding eigenvector. If T(i:i+1,i:i+1)* is a 2-by-2 block whose eigenvalues are* complex-conjugate eigenvalues of T, then* VL(i)+sqrt(-1)*VL(i+1) is the complex* eigenvector corresponding to the eigenvalue* with positive real part.* if HOWMNY = 'B', the matrix Q*Y;* if HOWMNY = 'S', the left eigenvectors of T specified by* SELECT, 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 SIDE = 'R' or 'B' and HOWMNY = 'B', VR must* contain an N-by-N matrix Q (usually the orthogonal matrix Q* of Schur vectors returned by DHSEQR).* On exit, if SIDE = 'R' or 'B', VR contains:* if HOWMNY = 'A', the matrix X of right eigenvectors of T;* VR has the same quasi-upper triangular form* as T. If T(i,i) is a real eigenvalue, then* the i-th column VR(i) of VR is its* corresponding eigenvector. If T(i:i+1,i:i+1)* is a 2-by-2 block whose eigenvalues are* complex-conjugate eigenvalues of T, then* VR(i)+sqrt(-1)*VR(i+1) is the complex* eigenvector corresponding to the eigenvalue* with positive real part.* if HOWMNY = 'B', the matrix Q*X;* if HOWMNY = 'S', the right eigenvectors of T specified by* SELECT, 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 actually* used to store the eigenvectors.* If HOWMNY = 'A' or 'B', M is set to N.* Each selected real eigenvector occupies one column and each* selected complex eigenvector occupies two columns.** 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 algorithm used in this program is basically backward (forward)* substitution, with scaling to make the the code robust against* possible overflow.** 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 ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEVINTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,$ SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,$ XNORM* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DLALN2, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Local Arrays ..DOUBLE PRECISION X( 2, 2 )* ..* .. Executable Statements ..** Decode and test the input parameters*BOTHV = LSAME( SIDE, 'B' )RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHVLEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV*ALLV = LSAME( HOWMNY, 'A' )OVER = LSAME( HOWMNY, 'B' )SOMEV = LSAME( HOWMNY, 'S' )*INFO = 0IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -1ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THENINFO = -8ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THENINFO = -10ELSE** Set M to the number of columns required to store the selected* eigenvectors, standardize the array SELECT if necessary, and* test MM.*IF( SOMEV ) THENM = 0PAIR = .FALSE.DO 10 J = 1, NIF( PAIR ) THENPAIR = .FALSE.SELECT( J ) = .FALSE.ELSEIF( J.LT.N ) THENIF( T( J+1, J ).EQ.ZERO ) THENIF( SELECT( J ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( J ) .OR. SELECT( J+1 ) ) THENSELECT( J ) = .TRUE.M = M + 2END IFEND IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEELSEM = NEND IF*IF( MM.LT.M ) THENINFO = -11END IFEND IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTREVC', -INFO )RETURNEND IF** Quick return if possible.*IF( N.EQ.0 )$ RETURN** Set the constants to control overflow.*UNFL = DLAMCH( 'Safe minimum' )OVFL = ONE / UNFLCALL DLABAD( UNFL, OVFL )ULP = DLAMCH( 'Precision' )SMLNUM = UNFL*( N / ULP )BIGNUM = ( ONE-ULP ) / SMLNUM** Compute 1-norm of each column of strictly upper triangular* part of T to control overflow in triangular solver.*WORK( 1 ) = ZERODO 30 J = 2, NWORK( J ) = ZERODO 20 I = 1, J - 1WORK( J ) = WORK( J ) + ABS( T( I, J ) )20 CONTINUE30 CONTINUE** Index IP is used to specify the real or complex eigenvalue:* IP = 0, real eigenvalue,* 1, first of conjugate complex pair: (wr,wi)* -1, second of conjugate complex pair: (wr,wi)*N2 = 2*N*IF( RIGHTV ) THEN** Compute right eigenvectors.*IP = 0IS = MDO 140 KI = N, 1, -1*IF( IP.EQ.1 )$ GO TO 130IF( KI.EQ.1 )$ GO TO 40IF( T( KI, KI-1 ).EQ.ZERO )$ GO TO 40IP = -1*40 CONTINUEIF( SOMEV ) THENIF( IP.EQ.0 ) THENIF( .NOT.SELECT( KI ) )$ GO TO 130ELSEIF( .NOT.SELECT( KI-1 ) )$ GO TO 130END IFEND IF** Compute the KI-th eigenvalue (WR,WI).*WR = T( KI, KI )WI = ZEROIF( IP.NE.0 )$ WI = SQRT( ABS( T( KI, KI-1 ) ) )*$ SQRT( ABS( T( KI-1, KI ) ) )SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )*IF( IP.EQ.0 ) THEN** Real right eigenvector*WORK( KI+N ) = ONE** Form right-hand side*DO 50 K = 1, KI - 1WORK( K+N ) = -T( K, KI )50 CONTINUE** Solve the upper quasi-triangular system:* (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.*JNXT = KI - 1DO 60 J = KI - 1, 1, -1IF( J.GT.JNXT )$ GO TO 60J1 = JJ2 = JJNXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block*CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale X(1,1) to avoid overflow when updating* the right-hand side.*IF( XNORM.GT.ONE ) THENIF( WORK( J ).GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )WORK( J+N ) = X( 1, 1 )** Update right-hand side*CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )*ELSE** 2-by-2 diagonal block*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE,$ T( J-1, J-1 ), LDT, ONE, ONE,$ WORK( J-1+N ), N, WR, ZERO, X, 2,$ SCALE, XNORM, IERR )** Scale X(1,1) and X(2,1) to avoid overflow when* updating the right-hand side.*IF( XNORM.GT.ONE ) THENBETA = MAX( WORK( J-1 ), WORK( J ) )IF( BETA.GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMX( 2, 1 ) = X( 2, 1 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )WORK( J-1+N ) = X( 1, 1 )WORK( J+N ) = X( 2, 1 )** Update right-hand side*CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )END IF60 CONTINUE** Copy the vector x or Q*x to VR and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS ), 1 )*II = IDAMAX( KI, VR( 1, IS ), 1 )REMAX = ONE / ABS( VR( II, IS ) )CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )*DO 70 K = KI + 1, NVR( K, IS ) = ZERO70 CONTINUEELSEIF( KI.GT.1 )$ CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,$ WORK( 1+N ), 1, WORK( KI+N ),$ VR( 1, KI ), 1 )*II = IDAMAX( N, VR( 1, KI ), 1 )REMAX = ONE / ABS( VR( II, KI ) )CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )END IF*ELSE** Complex right eigenvector.** Initial solve* [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.* [ (T(KI,KI-1) T(KI,KI) ) ]*IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THENWORK( KI-1+N ) = ONEWORK( KI+N2 ) = WI / T( KI-1, KI )ELSEWORK( KI-1+N ) = -WI / T( KI, KI-1 )WORK( KI+N2 ) = ONEEND IFWORK( KI+N ) = ZEROWORK( KI-1+N2 ) = ZERO** Form right-hand side*DO 80 K = 1, KI - 2WORK( K+N ) = -WORK( KI-1+N )*T( K, KI-1 )WORK( K+N2 ) = -WORK( KI+N2 )*T( K, KI )80 CONTINUE** Solve upper quasi-triangular system:* (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)*JNXT = KI - 2DO 90 J = KI - 2, 1, -1IF( J.GT.JNXT )$ GO TO 90J1 = JJ2 = JJNXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block*CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR, WI,$ X, 2, SCALE, XNORM, IERR )** Scale X(1,1) and X(1,2) to avoid overflow when* updating the right-hand side.*IF( XNORM.GT.ONE ) THENIF( WORK( J ).GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMX( 1, 2 ) = X( 1, 2 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )END IFWORK( J+N ) = X( 1, 1 )WORK( J+N2 ) = X( 1, 2 )** Update the right-hand side*CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,$ WORK( 1+N2 ), 1 )*ELSE** 2-by-2 diagonal block*CALL DLALN2( .FALSE., 2, 2, SMIN, ONE,$ T( J-1, J-1 ), LDT, ONE, ONE,$ WORK( J-1+N ), N, WR, WI, X, 2, SCALE,$ XNORM, IERR )** Scale X to avoid overflow when updating* the right-hand side.*IF( XNORM.GT.ONE ) THENBETA = MAX( WORK( J-1 ), WORK( J ) )IF( BETA.GT.BIGNUM / XNORM ) THENREC = ONE / XNORMX( 1, 1 ) = X( 1, 1 )*RECX( 1, 2 ) = X( 1, 2 )*RECX( 2, 1 ) = X( 2, 1 )*RECX( 2, 2 ) = X( 2, 2 )*RECSCALE = SCALE*RECEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )END IFWORK( J-1+N ) = X( 1, 1 )WORK( J+N ) = X( 2, 1 )WORK( J-1+N2 ) = X( 1, 2 )WORK( J+N2 ) = X( 2, 2 )** Update the right-hand side*CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,$ WORK( 1+N2 ), 1 )CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,$ WORK( 1+N2 ), 1 )END IF90 CONTINUE** Copy the vector x or Q*x to VR and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS-1 ), 1 )CALL DCOPY( KI, WORK( 1+N2 ), 1, VR( 1, IS ), 1 )*EMAX = ZERODO 100 K = 1, KIEMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+$ ABS( VR( K, IS ) ) )100 CONTINUE*REMAX = ONE / EMAXCALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )*DO 110 K = KI + 1, NVR( K, IS-1 ) = ZEROVR( K, IS ) = ZERO110 CONTINUE*ELSE*IF( KI.GT.2 ) THENCALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,$ WORK( 1+N ), 1, WORK( KI-1+N ),$ VR( 1, KI-1 ), 1 )CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,$ WORK( 1+N2 ), 1, WORK( KI+N2 ),$ VR( 1, KI ), 1 )ELSECALL DSCAL( N, WORK( KI-1+N ), VR( 1, KI-1 ), 1 )CALL DSCAL( N, WORK( KI+N2 ), VR( 1, KI ), 1 )END IF*EMAX = ZERODO 120 K = 1, NEMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+$ ABS( VR( K, KI ) ) )120 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )END IFEND IF*IS = IS - 1IF( IP.NE.0 )$ IS = IS - 1130 CONTINUEIF( IP.EQ.1 )$ IP = 0IF( IP.EQ.-1 )$ IP = 1140 CONTINUEEND IF*IF( LEFTV ) THEN** Compute left eigenvectors.*IP = 0IS = 1DO 260 KI = 1, N*IF( IP.EQ.-1 )$ GO TO 250IF( KI.EQ.N )$ GO TO 150IF( T( KI+1, KI ).EQ.ZERO )$ GO TO 150IP = 1*150 CONTINUEIF( SOMEV ) THENIF( .NOT.SELECT( KI ) )$ GO TO 250END IF** Compute the KI-th eigenvalue (WR,WI).*WR = T( KI, KI )WI = ZEROIF( IP.NE.0 )$ WI = SQRT( ABS( T( KI, KI+1 ) ) )*$ SQRT( ABS( T( KI+1, KI ) ) )SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )*IF( IP.EQ.0 ) THEN** Real left eigenvector.*WORK( KI+N ) = ONE** Form right-hand side*DO 160 K = KI + 1, NWORK( K+N ) = -T( KI, K )160 CONTINUE** Solve the quasi-triangular system:* (T(KI+1:N,KI+1:N) - WR)'*X = SCALE*WORK*VMAX = ONEVCRIT = BIGNUM*JNXT = KI + 1DO 170 J = KI + 1, NIF( J.LT.JNXT )$ GO TO 170J1 = JJ2 = JJNXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side.*IF( WORK( J ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-1, T( KI+1, J ), 1,$ WORK( KI+1+N ), 1 )** Solve (T(J,J)-WR)'*X = WORK*CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )WORK( J+N ) = X( 1, 1 )VMAX = MAX( ABS( WORK( J+N ) ), VMAX )VCRIT = BIGNUM / VMAX*ELSE** 2-by-2 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side.*BETA = MAX( WORK( J ), WORK( J+1 ) )IF( BETA.GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-1, T( KI+1, J ), 1,$ WORK( KI+1+N ), 1 )*WORK( J+1+N ) = WORK( J+1+N ) -$ DDOT( J-KI-1, T( KI+1, J+1 ), 1,$ WORK( KI+1+N ), 1 )** Solve* [T(J,J)-WR T(J,J+1) ]'* X = SCALE*( WORK1 )* [T(J+1,J) T(J+1,J+1)-WR] ( WORK2 )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )WORK( J+N ) = X( 1, 1 )WORK( J+1+N ) = X( 2, 1 )*VMAX = MAX( ABS( WORK( J+N ) ),$ ABS( WORK( J+1+N ) ), VMAX )VCRIT = BIGNUM / VMAX*END IF170 CONTINUE** Copy the vector x or Q*x to VL and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )*II = IDAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1REMAX = ONE / ABS( VL( II, IS ) )CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )*DO 180 K = 1, KI - 1VL( K, IS ) = ZERO180 CONTINUE*ELSE*IF( KI.LT.N )$ CALL DGEMV( 'N', N, N-KI, ONE, VL( 1, KI+1 ), LDVL,$ WORK( KI+1+N ), 1, WORK( KI+N ),$ VL( 1, KI ), 1 )*II = IDAMAX( N, VL( 1, KI ), 1 )REMAX = ONE / ABS( VL( II, KI ) )CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )*END IF*ELSE** Complex left eigenvector.** Initial solve:* ((T(KI,KI) T(KI,KI+1) )' - (WR - I* WI))*X = 0.* ((T(KI+1,KI) T(KI+1,KI+1)) )*IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THENWORK( KI+N ) = WI / T( KI, KI+1 )WORK( KI+1+N2 ) = ONEELSEWORK( KI+N ) = ONEWORK( KI+1+N2 ) = -WI / T( KI+1, KI )END IFWORK( KI+1+N ) = ZEROWORK( KI+N2 ) = ZERO** Form right-hand side*DO 190 K = KI + 2, NWORK( K+N ) = -WORK( KI+N )*T( KI, K )WORK( K+N2 ) = -WORK( KI+1+N2 )*T( KI+1, K )190 CONTINUE** Solve complex quasi-triangular system:* ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2*VMAX = ONEVCRIT = BIGNUM*JNXT = KI + 2DO 200 J = KI + 2, NIF( J.LT.JNXT )$ GO TO 200J1 = JJ2 = JJNXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block** Scale if necessary to avoid overflow when* forming the right-hand side elements.*IF( WORK( J ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N ), 1 )WORK( J+N2 ) = WORK( J+N2 ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N2 ), 1 )** Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2*CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ -WI, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )END IFWORK( J+N ) = X( 1, 1 )WORK( J+N2 ) = X( 1, 2 )VMAX = MAX( ABS( WORK( J+N ) ),$ ABS( WORK( J+N2 ) ), VMAX )VCRIT = BIGNUM / VMAX*ELSE** 2-by-2 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side elements.*BETA = MAX( WORK( J ), WORK( J+1 ) )IF( BETA.GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N ), 1 )*WORK( J+N2 ) = WORK( J+N2 ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N2 ), 1 )*WORK( J+1+N ) = WORK( J+1+N ) -$ DDOT( J-KI-2, T( KI+2, J+1 ), 1,$ WORK( KI+2+N ), 1 )*WORK( J+1+N2 ) = WORK( J+1+N2 ) -$ DDOT( J-KI-2, T( KI+2, J+1 ), 1,$ WORK( KI+2+N2 ), 1 )** Solve 2-by-2 complex linear equation* ([T(j,j) T(j,j+1) ]'-(wr-i*wi)*I)*X = SCALE*B* ([T(j+1,j) T(j+1,j+1)] )*CALL DLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ -WI, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )END IFWORK( J+N ) = X( 1, 1 )WORK( J+N2 ) = X( 1, 2 )WORK( J+1+N ) = X( 2, 1 )WORK( J+1+N2 ) = X( 2, 2 )VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),$ ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ), VMAX )VCRIT = BIGNUM / VMAX*END IF200 CONTINUE** Copy the vector x or Q*x to VL and normalize.*210 CONTINUEIF( .NOT.OVER ) THENCALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )CALL DCOPY( N-KI+1, WORK( KI+N2 ), 1, VL( KI, IS+1 ),$ 1 )*EMAX = ZERODO 220 K = KI, NEMAX = MAX( EMAX, ABS( VL( K, IS ) )+$ ABS( VL( K, IS+1 ) ) )220 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )*DO 230 K = 1, KI - 1VL( K, IS ) = ZEROVL( K, IS+1 ) = ZERO230 CONTINUEELSEIF( KI.LT.N-1 ) THENCALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),$ LDVL, WORK( KI+2+N ), 1, WORK( KI+N ),$ VL( 1, KI ), 1 )CALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),$ LDVL, WORK( KI+2+N2 ), 1,$ WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )ELSECALL DSCAL( N, WORK( KI+N ), VL( 1, KI ), 1 )CALL DSCAL( N, WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )END IF*EMAX = ZERODO 240 K = 1, NEMAX = MAX( EMAX, ABS( VL( K, KI ) )+$ ABS( VL( K, KI+1 ) ) )240 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N, REMAX, VL( 1, KI ), 1 )CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )*END IF*END IF*IS = IS + 1IF( IP.NE.0 )$ IS = IS + 1250 CONTINUEIF( IP.EQ.-1 )$ IP = 0IF( IP.EQ.1 )$ IP = -1*260 CONTINUE*END IF*RETURN** End of DTREVC*ENDSUBROUTINE DTREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, WORK,$ 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 COMPQINTEGER IFST, ILST, INFO, LDQ, LDT, N* ..* .. Array Arguments ..DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )* ..** Purpose* =======** DTREXC reorders the real Schur factorization of a real matrix* A = Q*T*Q**T, so that the diagonal block of T with row index IFST is* moved to row ILST.** The real Schur form T is reordered by an orthogonal similarity* transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors* is updated by postmultiplying it with Z.** T must be in Schur canonical form (as returned by DHSEQR), that is,* block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each* 2-by-2 diagonal block has its diagonal elements equal and its* off-diagonal elements of opposite sign.** Arguments* =========** COMPQ (input) CHARACTER*1* = 'V': update the matrix Q of Schur vectors;* = 'N': do not update Q.** N (input) INTEGER* The order of the matrix T. N >= 0.** T (input/output) DOUBLE PRECISION array, dimension (LDT,N)* On entry, the upper quasi-triangular matrix T, in Schur* Schur canonical form.* On exit, the reordered upper quasi-triangular matrix, again* in Schur canonical form.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= max(1,N).** Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N)* On entry, if COMPQ = 'V', the matrix Q of Schur vectors.* On exit, if COMPQ = 'V', Q has been postmultiplied by the* orthogonal transformation matrix Z which reorders T.* If COMPQ = 'N', Q is not referenced.** LDQ (input) INTEGER* The leading dimension of the array Q. LDQ >= max(1,N).** IFST (input/output) INTEGER* ILST (input/output) INTEGER* Specify the reordering of the diagonal blocks of T.* The block with row index IFST is moved to row ILST, by a* sequence of transpositions between adjacent blocks.* On exit, if IFST pointed on entry to the second row of a* 2-by-2 block, it is changed to point to the first row; ILST* always points to the first row of the block in its final* position (which may differ from its input value by +1 or -1).* 1 <= IFST <= N; 1 <= ILST <= N.** 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* = 1: two adjacent blocks were too close to swap (the problem* is very ill-conditioned); T may have been partially* reordered, and ILST points to the first row of the* current position of the block being moved.** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL WANTQINTEGER HERE, NBF, NBL, NBNEXT* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLAEXC, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Decode and test the input arguments.*INFO = 0WANTQ = LSAME( COMPQ, 'V' )IF( .NOT.WANTQ .AND. .NOT.LSAME( COMPQ, 'N' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) ) THENINFO = -6ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THENINFO = -7ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTREXC', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.1 )$ RETURN** Determine the first row of specified block* and find out it is 1 by 1 or 2 by 2.*IF( IFST.GT.1 ) THENIF( T( IFST, IFST-1 ).NE.ZERO )$ IFST = IFST - 1END IFNBF = 1IF( IFST.LT.N ) THENIF( T( IFST+1, IFST ).NE.ZERO )$ NBF = 2END IF** Determine the first row of the final block* and find out it is 1 by 1 or 2 by 2.*IF( ILST.GT.1 ) THENIF( T( ILST, ILST-1 ).NE.ZERO )$ ILST = ILST - 1END IFNBL = 1IF( ILST.LT.N ) THENIF( T( ILST+1, ILST ).NE.ZERO )$ NBL = 2END IF*IF( IFST.EQ.ILST )$ RETURN*IF( IFST.LT.ILST ) THEN** Update ILST*IF( NBF.EQ.2 .AND. NBL.EQ.1 )$ ILST = ILST - 1IF( NBF.EQ.1 .AND. NBL.EQ.2 )$ ILST = ILST + 1*HERE = IFST*10 CONTINUE** Swap block with next one below*IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN** Current block either 1 by 1 or 2 by 2*NBNEXT = 1IF( HERE+NBF+1.LE.N ) THENIF( T( HERE+NBF+1, HERE+NBF ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBF, NBNEXT,$ WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + NBNEXT** Test if 2 by 2 block breaks into two 1 by 1 blocks*IF( NBF.EQ.2 ) THENIF( T( HERE+1, HERE ).EQ.ZERO )$ NBF = 3END IF*ELSE** Current block consists of two 1 by 1 blocks each of which* must be swapped individually*NBNEXT = 1IF( HERE+3.LE.N ) THENIF( T( HERE+3, HERE+2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, NBNEXT,$ WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFIF( NBNEXT.EQ.1 ) THEN** Swap two 1 by 1 blocks, no problems possible*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, NBNEXT,$ WORK, INFO )HERE = HERE + 1ELSE** Recompute NBNEXT in case 2 by 2 split*IF( T( HERE+2, HERE+1 ).EQ.ZERO )$ NBNEXT = 1IF( NBNEXT.EQ.2 ) THEN** 2 by 2 Block did not split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1,$ NBNEXT, WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + 2ELSE** 2 by 2 Block did split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,$ WORK, INFO )CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, 1,$ WORK, INFO )HERE = HERE + 2END IFEND IFEND IFIF( HERE.LT.ILST )$ GO TO 10*ELSE*HERE = IFST20 CONTINUE** Swap block with next one above*IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN** Current block either 1 by 1 or 2 by 2*NBNEXT = 1IF( HERE.GE.3 ) THENIF( T( HERE-1, HERE-2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,$ NBF, WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - NBNEXT** Test if 2 by 2 block breaks into two 1 by 1 blocks*IF( NBF.EQ.2 ) THENIF( T( HERE+1, HERE ).EQ.ZERO )$ NBF = 3END IF*ELSE** Current block consists of two 1 by 1 blocks each of which* must be swapped individually*NBNEXT = 1IF( HERE.GE.3 ) THENIF( T( HERE-1, HERE-2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,$ 1, WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFIF( NBNEXT.EQ.1 ) THEN** Swap two 1 by 1 blocks, no problems possible*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBNEXT, 1,$ WORK, INFO )HERE = HERE - 1ELSE** Recompute NBNEXT in case 2 by 2 split*IF( T( HERE, HERE-1 ).EQ.ZERO )$ NBNEXT = 1IF( NBNEXT.EQ.2 ) THEN** 2 by 2 Block did not split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 2, 1,$ WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - 2ELSE** 2 by 2 Block did split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,$ WORK, INFO )CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 1, 1,$ WORK, INFO )HERE = HERE - 2END IFEND IFEND IFIF( HERE.GT.ILST )$ GO TO 20END IFILST = HERE*RETURN** End of DTREXC*ENDSUBROUTINE DTRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI,$ M, S, SEP, WORK, LWORK, IWORK, LIWORK, 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, JOBINTEGER INFO, LDQ, LDT, LIWORK, LWORK, M, NDOUBLE PRECISION S, SEP* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IWORK( * )DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WI( * ), WORK( * ),$ WR( * )* ..** Purpose* =======** DTRSEN reorders the real Schur factorization of a real matrix* A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in* the leading diagonal blocks of the upper quasi-triangular matrix T,* and the leading columns of Q form an orthonormal basis of the* corresponding right invariant subspace.** Optionally the routine computes the reciprocal condition numbers of* the cluster of eigenvalues and/or the invariant subspace.** T must be in Schur canonical form (as returned by DHSEQR), that is,* block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each* 2-by-2 diagonal block has its diagonal elemnts equal and its* off-diagonal elements of opposite sign.** Arguments* =========** JOB (input) CHARACTER*1* Specifies whether condition numbers are required for the* cluster of eigenvalues (S) or the invariant subspace (SEP):* = 'N': none;* = 'E': for eigenvalues only (S);* = 'V': for invariant subspace only (SEP);* = 'B': for both eigenvalues and invariant subspace (S and* SEP).** COMPQ (input) CHARACTER*1* = 'V': update the matrix Q of Schur vectors;* = 'N': do not update Q.** SELECT (input) LOGICAL array, dimension (N)* SELECT specifies the eigenvalues in the selected cluster. To* select a real eigenvalue w(j), SELECT(j) must be set to* .TRUE.. To select a complex conjugate pair of eigenvalues* w(j) and w(j+1), corresponding to a 2-by-2 diagonal block,* either SELECT(j) or SELECT(j+1) or both must be set to* .TRUE.; a complex conjugate pair of eigenvalues must be* either both included in the cluster or both excluded.** N (input) INTEGER* The order of the matrix T. N >= 0.** T (input/output) DOUBLE PRECISION array, dimension (LDT,N)* On entry, the upper quasi-triangular matrix T, in Schur* canonical form.* On exit, T is overwritten by the reordered matrix T, again in* Schur canonical form, with the selected eigenvalues in the* leading diagonal blocks.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= max(1,N).** Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N)* On entry, if COMPQ = 'V', the matrix Q of Schur vectors.* On exit, if COMPQ = 'V', Q has been postmultiplied by the* orthogonal transformation matrix which reorders T; the* leading M columns of Q form an orthonormal basis for the* specified invariant subspace.* If COMPQ = 'N', Q is not referenced.** LDQ (input) INTEGER* The leading dimension of the array Q.* LDQ >= 1; and if COMPQ = 'V', LDQ >= N.** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* The real and imaginary parts, respectively, of the reordered* eigenvalues of T. The eigenvalues are stored in the same* order as on the diagonal of T, with WR(i) = T(i,i) and, if* T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0 and* WI(i+1) = -WI(i). Note that if a complex eigenvalue is* sufficiently ill-conditioned, then its value may differ* significantly from its value before reordering.** M (output) INTEGER* The dimension of the specified invariant subspace.* 0 < = M <= N.** S (output) DOUBLE PRECISION* If JOB = 'E' or 'B', S is a lower bound on the reciprocal* condition number for the selected cluster of eigenvalues.* S cannot underestimate the true reciprocal condition number* by more than a factor of sqrt(N). If M = 0 or N, S = 1.* If JOB = 'N' or 'V', S is not referenced.** SEP (output) DOUBLE PRECISION* If JOB = 'V' or 'B', SEP is the estimated reciprocal* condition number of the specified invariant subspace. If* M = 0 or N, SEP = norm(T).* If JOB = 'N' or 'E', SEP is not referenced.** 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.* If JOB = 'N', LWORK >= max(1,N);* if JOB = 'E', LWORK >= M*(N-M);* if JOB = 'V' or 'B', LWORK >= 2*M*(N-M).** 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.** IWORK (workspace) INTEGER array, dimension (LIWORK)* IF JOB = 'N' or 'E', IWORK is not referenced.** LIWORK (input) INTEGER* The dimension of the array IWORK.* If JOB = 'N' or 'E', LIWORK >= 1;* if JOB = 'V' or 'B', LIWORK >= M*(N-M).** If LIWORK = -1, then a workspace query is assumed; the* routine only calculates the optimal size of the IWORK array,* returns this value as the first entry of the IWORK array, and* no error message related to LIWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* = 1: reordering of T failed because some eigenvalues are too* close to separate (the problem is very ill-conditioned);* T may have been partially reordered, and WR and WI* contain the eigenvalues in the same order as in T; S and* SEP (if requested) are set to zero.** Further Details* ===============** DTRSEN first collects the selected eigenvalues by computing an* orthogonal transformation Z to move them to the top left corner of T.* In other words, the selected eigenvalues are the eigenvalues of T11* in:** Z'*T*Z = ( T11 T12 ) n1* ( 0 T22 ) n2* n1 n2** where N = n1+n2 and Z' means the transpose of Z. The first n1 columns* of Z span the specified invariant subspace of T.** If T has been obtained from the real Schur factorization of a matrix* A = Q*T*Q', then the reordered real Schur factorization of A is given* by A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span* the corresponding invariant subspace of A.** The reciprocal condition number of the average of the eigenvalues of* T11 may be returned in S. S lies between 0 (very badly conditioned)* and 1 (very well conditioned). It is computed as follows. First we* compute R so that** P = ( I R ) n1* ( 0 0 ) n2* n1 n2** is the projector on the invariant subspace associated with T11.* R is the solution of the Sylvester equation:** T11*R - R*T22 = T12.** Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote* the two-norm of M. Then S is computed as the lower bound** (1 + F-norm(R)**2)**(-1/2)** on the reciprocal of 2-norm(P), the true reciprocal condition number.* S cannot underestimate 1 / 2-norm(P) by more than a factor of* sqrt(N).** An approximate error bound for the computed average of the* eigenvalues of T11 is** EPS * norm(T) / S** where EPS is the machine precision.** The reciprocal condition number of the right invariant subspace* spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP.* SEP is defined as the separation of T11 and T22:** sep( T11, T22 ) = sigma-min( C )** where sigma-min(C) is the smallest singular value of the* n1*n2-by-n1*n2 matrix** C = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )** I(m) is an m by m identity matrix, and kprod denotes the Kronecker* product. We estimate sigma-min(C) by the reciprocal of an estimate of* the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C)* cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2).** When SEP is small, small changes in T can cause large changes in* the invariant subspace. An approximate bound on the maximum angular* error in the computed right invariant subspace is** EPS * norm(T) / SEP** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, PAIR, SWAP, WANTBH, WANTQ, WANTS,$ WANTSPINTEGER IERR, K, KASE, KK, KS, LIWMIN, LWMIN, N1, N2,$ NNDOUBLE PRECISION EST, RNORM, SCALE* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLANGEEXTERNAL LSAME, DLANGE* ..* .. External Subroutines ..EXTERNAL DLACON, DLACPY, DTREXC, DTRSYL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode and test the input parameters*WANTBH = LSAME( JOB, 'B' )WANTS = LSAME( JOB, 'E' ) .OR. WANTBHWANTSP = LSAME( JOB, 'V' ) .OR. WANTBHWANTQ = LSAME( COMPQ, 'V' )*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.WANTS .AND. .NOT.WANTSP )$ THENINFO = -1ELSE IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -8ELSE** Set M to the dimension of the specified invariant subspace,* and test LWORK and LIWORK.*M = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSEIF( K.LT.N ) THENIF( T( K+1, K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) )$ M = M + 2END IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUE*N1 = MN2 = N - MNN = N1*N2*IF( WANTSP ) THENLWMIN = MAX( 1, 2*NN )LIWMIN = MAX( 1, NN )ELSE IF( LSAME( JOB, 'N' ) ) THENLWMIN = MAX( 1, N )LIWMIN = 1ELSE IF( LSAME( JOB, 'E' ) ) THENLWMIN = MAX( 1, NN )LIWMIN = 1END IF*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -15ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -17END IFEND IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMINEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTRSEN', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible.*IF( M.EQ.N .OR. M.EQ.0 ) THENIF( WANTS )$ S = ONEIF( WANTSP )$ SEP = DLANGE( '1', N, N, T, LDT, WORK )GO TO 40END IF** Collect the selected blocks at the top-left corner of T.*KS = 0PAIR = .FALSE.DO 20 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSESWAP = SELECT( K )IF( K.LT.N ) THENIF( T( K+1, K ).NE.ZERO ) THENPAIR = .TRUE.SWAP = SWAP .OR. SELECT( K+1 )END IFEND IFIF( SWAP ) THENKS = KS + 1** Swap the K-th block to position KS.*IERR = 0KK = KIF( K.NE.KS )$ CALL DTREXC( COMPQ, N, T, LDT, Q, LDQ, KK, KS, WORK,$ IERR )IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN** Blocks too close to swap: exit.*INFO = 1IF( WANTS )$ S = ZEROIF( WANTSP )$ SEP = ZEROGO TO 40END IFIF( PAIR )$ KS = KS + 1END IFEND IF20 CONTINUE*IF( WANTS ) THEN** Solve Sylvester equation for R:** T11*R - R*T22 = scale*T12*CALL DLACPY( 'F', N1, N2, T( 1, N1+1 ), LDT, WORK, N1 )CALL DTRSYL( 'N', 'N', -1, N1, N2, T, LDT, T( N1+1, N1+1 ),$ LDT, WORK, N1, SCALE, IERR )** Estimate the reciprocal of the condition number of the cluster* of eigenvalues.*RNORM = DLANGE( 'F', N1, N2, WORK, N1, WORK )IF( RNORM.EQ.ZERO ) THENS = ONEELSES = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*$ SQRT( RNORM ) )END IFEND IF*IF( WANTSP ) THEN** Estimate sep(T11,T22).*EST = ZEROKASE = 030 CONTINUECALL DLACON( NN, WORK( NN+1 ), WORK, IWORK, EST, KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Solve T11*R - R*T22 = scale*X.*CALL DTRSYL( 'N', 'N', -1, N1, N2, T, LDT,$ T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,$ IERR )ELSE** Solve T11'*R - R*T22' = scale*X.*CALL DTRSYL( 'T', 'T', -1, N1, N2, T, LDT,$ T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,$ IERR )END IFGO TO 30END IF*SEP = SCALE / ESTEND IF*40 CONTINUE** Store the output eigenvalues in WR and WI.*DO 50 K = 1, NWR( K ) = T( K, K )WI( K ) = ZERO50 CONTINUEDO 60 K = 1, N - 1IF( T( K+1, K ).NE.ZERO ) THENWI( K ) = SQRT( ABS( T( K, K+1 ) ) )*$ SQRT( ABS( T( K+1, K ) ) )WI( K+1 ) = -WI( K )END IF60 CONTINUE*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DTRSEN*ENDSUBROUTINE DTRSNA( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,$ LDVR, S, SEP, MM, M, WORK, LDWORK, 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 HOWMNY, JOBINTEGER INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IWORK( * )DOUBLE PRECISION S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),$ VR( LDVR, * ), WORK( LDWORK, * )* ..** Purpose* =======** DTRSNA estimates reciprocal condition numbers for specified* eigenvalues and/or right eigenvectors of a real upper* quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q* orthogonal).** T must be in Schur canonical form (as returned by DHSEQR), that is,* block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each* 2-by-2 diagonal block has its diagonal elements equal and its* off-diagonal elements of opposite sign.** Arguments* =========** JOB (input) CHARACTER*1* Specifies whether condition numbers are required for* eigenvalues (S) or eigenvectors (SEP):* = 'E': for eigenvalues only (S);* = 'V': for eigenvectors only (SEP);* = 'B': for both eigenvalues and eigenvectors (S and SEP).** HOWMNY (input) CHARACTER*1* = 'A': compute condition numbers for all eigenpairs;* = 'S': compute condition numbers for selected eigenpairs* specified by the array SELECT.** SELECT (input) LOGICAL array, dimension (N)* If HOWMNY = 'S', SELECT specifies the eigenpairs for which* condition numbers are required. To select condition numbers* for the eigenpair corresponding to a real eigenvalue w(j),* SELECT(j) must be set to .TRUE.. To select condition numbers* corresponding to a complex conjugate pair of eigenvalues w(j)* and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be* set to .TRUE..* If HOWMNY = 'A', SELECT is not referenced.** N (input) INTEGER* The order of the matrix T. N >= 0.** T (input) DOUBLE PRECISION array, dimension (LDT,N)* The upper quasi-triangular matrix T, in Schur canonical form.** LDT (input) INTEGER* The leading dimension of the array T. LDT >= max(1,N).** VL (input) DOUBLE PRECISION array, dimension (LDVL,M)* If JOB = 'E' or 'B', VL must contain left eigenvectors of T* (or of any Q*T*Q**T with Q orthogonal), corresponding to the* eigenpairs specified by HOWMNY and SELECT. The eigenvectors* must be stored in consecutive columns of VL, as returned by* DHSEIN or DTREVC.* If JOB = 'V', VL is not referenced.** LDVL (input) INTEGER* The leading dimension of the array VL.* LDVL >= 1; and if JOB = 'E' or 'B', LDVL >= N.** VR (input) DOUBLE PRECISION array, dimension (LDVR,M)* If JOB = 'E' or 'B', VR must contain right eigenvectors of T* (or of any Q*T*Q**T with Q orthogonal), corresponding to the* eigenpairs specified by HOWMNY and SELECT. The eigenvectors* must be stored in consecutive columns of VR, as returned by* DHSEIN or DTREVC.* If JOB = 'V', VR is not referenced.** LDVR (input) INTEGER* The leading dimension of the array VR.* LDVR >= 1; and if JOB = 'E' or 'B', LDVR >= N.** S (output) DOUBLE PRECISION array, dimension (MM)* If JOB = 'E' or 'B', the reciprocal condition numbers of the* selected eigenvalues, stored in consecutive elements of the* array. For a complex conjugate pair of eigenvalues two* consecutive elements of S are set to the same value. Thus* S(j), SEP(j), and the j-th columns of VL and VR all* correspond to the same eigenpair (but not in general the* j-th eigenpair, unless all eigenpairs are selected).* If JOB = 'V', S is not referenced.** SEP (output) DOUBLE PRECISION array, dimension (MM)* If JOB = 'V' or 'B', the estimated reciprocal condition* numbers of the selected eigenvectors, stored in consecutive* elements of the array. For a complex eigenvector two* consecutive elements of SEP are set to the same value. If* the eigenvalues cannot be reordered to compute SEP(j), SEP(j)* is set to 0; this can only occur when the true value would be* very small anyway.* If JOB = 'E', SEP is not referenced.** MM (input) INTEGER* The number of elements in the arrays S (if JOB = 'E' or 'B')* and/or SEP (if JOB = 'V' or 'B'). MM >= M.** M (output) INTEGER* The number of elements of the arrays S and/or SEP actually* used to store the estimated condition numbers.* If HOWMNY = 'A', M is set to N.** WORK (workspace) DOUBLE PRECISION array, dimension (LDWORK,N+1)* If JOB = 'E', WORK is not referenced.** LDWORK (input) INTEGER* The leading dimension of the array WORK.* LDWORK >= 1; and if JOB = 'V' or 'B', LDWORK >= N.** IWORK (workspace) INTEGER array, dimension (N)* If JOB = 'E', IWORK is not referenced.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value** Further Details* ===============** The reciprocal of the condition number of an eigenvalue lambda is* defined as** S(lambda) = |v'*u| / (norm(u)*norm(v))** where u and v are the right and left eigenvectors of T corresponding* to lambda; v' denotes the conjugate-transpose of v, and norm(u)* denotes the Euclidean norm. These reciprocal condition numbers always* lie between zero (very badly conditioned) and one (very well* conditioned). If n = 1, S(lambda) is defined to be 1.** An approximate error bound for a computed eigenvalue W(i) is given by** EPS * norm(T) / S(i)** where EPS is the machine precision.** The reciprocal of the condition number of the right eigenvector u* corresponding to lambda is defined as follows. Suppose** T = ( lambda c )* ( 0 T22 )** Then the reciprocal condition number is** SEP( lambda, T22 ) = sigma-min( T22 - lambda*I )** where sigma-min denotes the smallest singular value. We approximate* the smallest singular value by the reciprocal of an estimate of the* one-norm of the inverse of T22 - lambda*I. If n = 1, SEP(1) is* defined to be abs(T(1,1)).** An approximate error bound for a computed right eigenvector VR(i)* is given by** EPS * norm(T) / SEP(i)** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..LOGICAL PAIR, SOMCON, WANTBH, WANTS, WANTSPINTEGER I, IERR, IFST, ILST, J, K, KASE, KS, N2, NNDOUBLE PRECISION BIGNUM, COND, CS, DELTA, DUMM, EPS, EST, LNRM,$ MU, PROD, PROD1, PROD2, RNRM, SCALE, SMLNUM, SN* ..* .. Local Arrays ..DOUBLE PRECISION DUMMY( 1 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOT, DLAMCH, DLAPY2, DNRM2EXTERNAL LSAME, DDOT, DLAMCH, DLAPY2, DNRM2* ..* .. External Subroutines ..EXTERNAL DLACON, DLACPY, DLAQTR, DTREXC, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode and test the input parameters*WANTBH = LSAME( JOB, 'B' )WANTS = LSAME( JOB, 'E' ) .OR. WANTBHWANTSP = LSAME( JOB, 'V' ) .OR. WANTBH*SOMCON = LSAME( HOWMNY, 'S' )*INFO = 0IF( .NOT.WANTS .AND. .NOT.WANTSP ) THENINFO = -1ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVL.LT.1 .OR. ( WANTS .AND. LDVL.LT.N ) ) THENINFO = -8ELSE IF( LDVR.LT.1 .OR. ( WANTS .AND. LDVR.LT.N ) ) THENINFO = -10ELSE** Set M to the number of eigenpairs for which condition numbers* are required, and test MM.*IF( SOMCON ) THENM = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSEIF( K.LT.N ) THENIF( T( K+1, K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) )$ M = M + 2END IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEELSEM = NEND IF*IF( MM.LT.M ) THENINFO = -13ELSE IF( LDWORK.LT.1 .OR. ( WANTSP .AND. LDWORK.LT.N ) ) THENINFO = -16END IFEND IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRSNA', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( SOMCON ) THENIF( .NOT.SELECT( 1 ) )$ RETURNEND IFIF( WANTS )$ S( 1 ) = ONEIF( WANTSP )$ SEP( 1 ) = ABS( T( 1, 1 ) )RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )*KS = 0PAIR = .FALSE.DO 60 K = 1, N** Determine whether T(k,k) begins a 1-by-1 or 2-by-2 block.*IF( PAIR ) THENPAIR = .FALSE.GO TO 60ELSEIF( K.LT.N )$ PAIR = T( K+1, K ).NE.ZEROEND IF** Determine whether condition numbers are required for the k-th* eigenpair.*IF( SOMCON ) THENIF( PAIR ) THENIF( .NOT.SELECT( K ) .AND. .NOT.SELECT( K+1 ) )$ GO TO 60ELSEIF( .NOT.SELECT( K ) )$ GO TO 60END IFEND IF*KS = KS + 1*IF( WANTS ) THEN** Compute the reciprocal condition number of the k-th* eigenvalue.*IF( .NOT.PAIR ) THEN** Real eigenvalue.*PROD = DDOT( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )RNRM = DNRM2( N, VR( 1, KS ), 1 )LNRM = DNRM2( N, VL( 1, KS ), 1 )S( KS ) = ABS( PROD ) / ( RNRM*LNRM )ELSE** Complex eigenvalue.*PROD1 = DDOT( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )PROD1 = PROD1 + DDOT( N, VR( 1, KS+1 ), 1, VL( 1, KS+1 ),$ 1 )PROD2 = DDOT( N, VL( 1, KS ), 1, VR( 1, KS+1 ), 1 )PROD2 = PROD2 - DDOT( N, VL( 1, KS+1 ), 1, VR( 1, KS ),$ 1 )RNRM = DLAPY2( DNRM2( N, VR( 1, KS ), 1 ),$ DNRM2( N, VR( 1, KS+1 ), 1 ) )LNRM = DLAPY2( DNRM2( N, VL( 1, KS ), 1 ),$ DNRM2( N, VL( 1, KS+1 ), 1 ) )COND = DLAPY2( PROD1, PROD2 ) / ( RNRM*LNRM )S( KS ) = CONDS( KS+1 ) = CONDEND IFEND IF*IF( WANTSP ) THEN** Estimate the reciprocal condition number of the k-th* eigenvector.** Copy the matrix T to the array WORK and swap the diagonal* block beginning at T(k,k) to the (1,1) position.*CALL DLACPY( 'Full', N, N, T, LDT, WORK, LDWORK )IFST = KILST = 1CALL DTREXC( 'No Q', N, WORK, LDWORK, DUMMY, 1, IFST, ILST,$ WORK( 1, N+1 ), IERR )*IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN** Could not swap because blocks not well separated*SCALE = ONEEST = BIGNUMELSE** Reordering successful*IF( WORK( 2, 1 ).EQ.ZERO ) THEN** Form C = T22 - lambda*I in WORK(2:N,2:N).*DO 20 I = 2, NWORK( I, I ) = WORK( I, I ) - WORK( 1, 1 )20 CONTINUEN2 = 1NN = N - 1ELSE** Triangularize the 2 by 2 block by unitary* transformation U = [ cs i*ss ]* [ i*ss cs ].* such that the (1,1) position of WORK is complex* eigenvalue lambda with positive imaginary part. (2,2)* position of WORK is the complex eigenvalue lambda* with negative imaginary part.*MU = SQRT( ABS( WORK( 1, 2 ) ) )*$ SQRT( ABS( WORK( 2, 1 ) ) )DELTA = DLAPY2( MU, WORK( 2, 1 ) )CS = MU / DELTASN = -WORK( 2, 1 ) / DELTA** Form** C' = WORK(2:N,2:N) + i*[rwork(1) ..... rwork(n-1) ]* [ mu ]* [ .. ]* [ .. ]* [ mu ]* where C' is conjugate transpose of complex matrix C,* and RWORK is stored starting in the N+1-st column of* WORK.*DO 30 J = 3, NWORK( 2, J ) = CS*WORK( 2, J )WORK( J, J ) = WORK( J, J ) - WORK( 1, 1 )30 CONTINUEWORK( 2, 2 ) = ZERO*WORK( 1, N+1 ) = TWO*MUDO 40 I = 2, N - 1WORK( I, N+1 ) = SN*WORK( 1, I+1 )40 CONTINUEN2 = 2NN = 2*( N-1 )END IF** Estimate norm(inv(C'))*EST = ZEROKASE = 050 CONTINUECALL DLACON( NN, WORK( 1, N+2 ), WORK( 1, N+4 ), IWORK,$ EST, KASE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THENIF( N2.EQ.1 ) THEN** Real eigenvalue: solve C'*x = scale*c.*CALL DLAQTR( .TRUE., .TRUE., N-1, WORK( 2, 2 ),$ LDWORK, DUMMY, DUMM, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )ELSE** Complex eigenvalue: solve* C'*(p+iq) = scale*(c+id) in real arithmetic.*CALL DLAQTR( .TRUE., .FALSE., N-1, WORK( 2, 2 ),$ LDWORK, WORK( 1, N+1 ), MU, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )END IFELSEIF( N2.EQ.1 ) THEN** Real eigenvalue: solve C*x = scale*c.*CALL DLAQTR( .FALSE., .TRUE., N-1, WORK( 2, 2 ),$ LDWORK, DUMMY, DUMM, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )ELSE** Complex eigenvalue: solve* C*(p+iq) = scale*(c+id) in real arithmetic.*CALL DLAQTR( .FALSE., .FALSE., N-1,$ WORK( 2, 2 ), LDWORK,$ WORK( 1, N+1 ), MU, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )*END IFEND IF*GO TO 50END IFEND IF*SEP( KS ) = SCALE / MAX( EST, SMLNUM )IF( PAIR )$ SEP( KS+1 ) = SEP( KS )END IF*IF( PAIR )$ KS = KS + 1*60 CONTINUERETURN** End of DTRSNA*ENDSUBROUTINE DTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,$ LDC, SCALE, 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 TRANA, TRANBINTEGER INFO, ISGN, LDA, LDB, LDC, M, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * )* ..** Purpose* =======** DTRSYL solves the real Sylvester matrix equation:** op(A)*X + X*op(B) = scale*C or* op(A)*X - X*op(B) = scale*C,** where op(A) = A or A**T, and A and B are both upper quasi-* triangular. A is M-by-M and B is N-by-N; the right hand side C and* the solution X are M-by-N; and scale is an output scale factor, set* <= 1 to avoid overflow in X.** A and B must be in Schur canonical form (as returned by DHSEQR), that* is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;* each 2-by-2 diagonal block has its diagonal elements equal and its* off-diagonal elements of opposite sign.** Arguments* =========** TRANA (input) CHARACTER*1* Specifies the option op(A):* = 'N': op(A) = A (No transpose)* = 'T': op(A) = A**T (Transpose)* = 'C': op(A) = A**H (Conjugate transpose = Transpose)** TRANB (input) CHARACTER*1* Specifies the option op(B):* = 'N': op(B) = B (No transpose)* = 'T': op(B) = B**T (Transpose)* = 'C': op(B) = B**H (Conjugate transpose = Transpose)** ISGN (input) INTEGER* Specifies the sign in the equation:* = +1: solve op(A)*X + X*op(B) = scale*C* = -1: solve op(A)*X - X*op(B) = scale*C** M (input) INTEGER* The order of the matrix A, and the number of rows in the* matrices X and C. M >= 0.** N (input) INTEGER* The order of the matrix B, and the number of columns in the* matrices X and C. N >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,M)* The upper quasi-triangular matrix A, in Schur canonical form.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** B (input) DOUBLE PRECISION array, dimension (LDB,N)* The upper quasi-triangular matrix B, in Schur canonical form.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,N).** C (input/output) DOUBLE PRECISION array, dimension (LDC,N)* On entry, the M-by-N right hand side matrix C.* On exit, C is overwritten by the solution matrix X.** LDC (input) INTEGER* The leading dimension of the array C. LDC >= max(1,M)** SCALE (output) DOUBLE PRECISION* The scale factor, scale, set <= 1 to avoid overflow in X.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* = 1: A and B have common or very close eigenvalues; perturbed* values were used to solve the equation (but the matrices* A and B are unchanged).** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRNA, NOTRNBINTEGER IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXTDOUBLE PRECISION A11, BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,$ SMLNUM, SUML, SUMR, XNORM* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 ), VEC( 2, 2 ), X( 2, 2 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOT, DLAMCH, DLANGEEXTERNAL LSAME, DDOT, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DLALN2, DLASY2, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN* ..* .. Executable Statements ..** Decode and Test input parameters*NOTRNA = LSAME( TRANA, 'N' )NOTRNB = LSAME( TRANB, 'N' )*INFO = 0IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND. .NOT.$ LSAME( TRANA, 'C' ) ) THENINFO = -1ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'T' ) .AND. .NOT.$ LSAME( TRANB, 'C' ) ) THENINFO = -2ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRSYL', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SMLNUM*DBLE( M*N ) / EPSBIGNUM = ONE / SMLNUM*SMIN = MAX( SMLNUM, EPS*DLANGE( 'M', M, M, A, LDA, DUM ),$ EPS*DLANGE( 'M', N, N, B, LDB, DUM ) )*SCALE = ONESGN = ISGN*IF( NOTRNA .AND. NOTRNB ) THEN** Solve A*X + ISGN*X*B = scale*C.** The (K,L)th block of X is determined starting from* bottom-left corner column by column by** A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)** Where* M L-1* R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)].* I=K+1 J=1** Start column loop (index = L)* L1 (L2) : column index of the first (first) row of X(K,L).*LNEXT = 1DO 60 L = 1, NIF( L.LT.LNEXT )$ GO TO 60IF( L.EQ.N ) THENL1 = LL2 = LELSEIF( B( L+1, L ).NE.ZERO ) THENL1 = LL2 = L + 1LNEXT = L + 2ELSEL1 = LL2 = LLNEXT = L + 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L).*KNEXT = MDO 50 K = M, 1, -1IF( K.GT.KNEXT )$ GO TO 50IF( K.EQ.1 ) THENK1 = KK2 = KELSEIF( A( K, K-1 ).NE.ZERO ) THENK1 = K - 1K2 = KKNEXT = K - 2ELSEK1 = KK2 = KKNEXT = K - 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 10 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )10 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 20 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )20 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 30 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )30 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .FALSE., .FALSE., ISGN, 2, 2,$ A( K1, K1 ), LDA, B( L1, L1 ), LDB, VEC,$ 2, SCALOC, X, 2, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 40 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )40 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 1, 2 )C( K2, L1 ) = X( 2, 1 )C( K2, L2 ) = X( 2, 2 )END IF*50 CONTINUE*60 CONTINUE*ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN** Solve A' *X + ISGN*X*B = scale*C.** The (K,L)th block of X is determined starting from* upper-left corner column by column by** A(K,K)'*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)** Where* K-1 L-1* R(K,L) = SUM [A(I,K)'*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)]* I=1 J=1** Start column loop (index = L)* L1 (L2): column index of the first (last) row of X(K,L)*LNEXT = 1DO 120 L = 1, NIF( L.LT.LNEXT )$ GO TO 120IF( L.EQ.N ) THENL1 = LL2 = LELSEIF( B( L+1, L ).NE.ZERO ) THENL1 = LL2 = L + 1LNEXT = L + 2ELSEL1 = LL2 = LLNEXT = L + 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L)*KNEXT = 1DO 110 K = 1, MIF( K.LT.KNEXT )$ GO TO 110IF( K.EQ.M ) THENK1 = KK2 = KELSEIF( A( K+1, K ).NE.ZERO ) THENK1 = KK2 = K + 1KNEXT = K + 2ELSEK1 = KK2 = KKNEXT = K + 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 70 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )70 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 80 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )80 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 90 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )90 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .TRUE., .FALSE., ISGN, 2, 2, A( K1, K1 ),$ LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,$ 2, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 100 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )100 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 1, 2 )C( K2, L1 ) = X( 2, 1 )C( K2, L2 ) = X( 2, 2 )END IF*110 CONTINUE120 CONTINUE*ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN** Solve A'*X + ISGN*X*B' = scale*C.** The (K,L)th block of X is determined starting from* top-right corner column by column by** A(K,K)'*X(K,L) + ISGN*X(K,L)*B(L,L)' = C(K,L) - R(K,L)** Where* K-1 N* R(K,L) = SUM [A(I,K)'*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)'].* I=1 J=L+1** Start column loop (index = L)* L1 (L2): column index of the first (last) row of X(K,L)*LNEXT = NDO 180 L = N, 1, -1IF( L.GT.LNEXT )$ GO TO 180IF( L.EQ.1 ) THENL1 = LL2 = LELSEIF( B( L, L-1 ).NE.ZERO ) THENL1 = L - 1L2 = LLNEXT = L - 2ELSEL1 = LL2 = LLNEXT = L - 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L)*KNEXT = 1DO 170 K = 1, MIF( K.LT.KNEXT )$ GO TO 170IF( K.EQ.M ) THENK1 = KK2 = KELSEIF( A( K+1, K ).NE.ZERO ) THENK1 = KK2 = K + 1KNEXT = K + 2ELSEK1 = KK2 = KKNEXT = K + 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,$ B( L1, MIN( L1+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 130 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )130 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 140 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )140 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 150 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )150 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .TRUE., .TRUE., ISGN, 2, 2, A( K1, K1 ),$ LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,$ 2, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 160 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )160 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 1, 2 )C( K2, L1 ) = X( 2, 1 )C( K2, L2 ) = X( 2, 2 )END IF*170 CONTINUE180 CONTINUE*ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN** Solve A*X + ISGN*X*B' = scale*C.** The (K,L)th block of X is determined starting from* bottom-right corner column by column by** A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L)' = C(K,L) - R(K,L)** Where* M N* R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)'].* I=K+1 J=L+1** Start column loop (index = L)* L1 (L2): column index of the first (last) row of X(K,L)*LNEXT = NDO 240 L = N, 1, -1IF( L.GT.LNEXT )$ GO TO 240IF( L.EQ.1 ) THENL1 = LL2 = LELSEIF( B( L, L-1 ).NE.ZERO ) THENL1 = L - 1L2 = LLNEXT = L - 2ELSEL1 = LL2 = LLNEXT = L - 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L)*KNEXT = MDO 230 K = M, 1, -1IF( K.GT.KNEXT )$ GO TO 230IF( K.EQ.1 ) THENK1 = KK2 = KELSEIF( A( K, K-1 ).NE.ZERO ) THENK1 = K - 1K2 = KKNEXT = K - 2ELSEK1 = KK2 = KKNEXT = K - 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,$ B( L1, MIN( L1+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 190 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )190 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 200 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )200 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 210 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )210 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .FALSE., .TRUE., ISGN, 2, 2, A( K1, K1 ),$ LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,$ 2, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 220 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )220 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 1, 2 )C( K2, L1 ) = X( 2, 1 )C( K2, L2 ) = X( 2, 2 )END IF*230 CONTINUE240 CONTINUE*END IF*RETURN** End of DTRSYL*ENDINTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE )** -- LAPACK auxiliary routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1998** .. Scalar Arguments ..INTEGER ISPECREAL ONE, ZERO* ..** Purpose* =======** IEEECK is called from the ILAENV to verify that Infinity and* possibly NaN arithmetic is safe (i.e. will not trap).** Arguments* =========** ISPEC (input) INTEGER* Specifies whether to test just for inifinity arithmetic* or whether to test for infinity and NaN arithmetic.* = 0: Verify infinity arithmetic only.* = 1: Verify infinity and NaN arithmetic.** ZERO (input) REAL* Must contain the value 0.0* This is passed to prevent the compiler from optimizing* away this code.** ONE (input) REAL* Must contain the value 1.0* This is passed to prevent the compiler from optimizing* away this code.** RETURN VALUE: INTEGER* = 0: Arithmetic failed to produce the correct answers* = 1: Arithmetic produced the correct answers** .. Local Scalars ..REAL NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF,$ NEGZRO, NEWZRO, POSINF* ..* .. Executable Statements ..IEEECK = 1*POSINF = ONE / ZEROIF( POSINF.LE.ONE ) THENIEEECK = 0RETURNEND IF*NEGINF = -ONE / ZEROIF( NEGINF.GE.ZERO ) THENIEEECK = 0RETURNEND IF*NEGZRO = ONE / ( NEGINF+ONE )IF( NEGZRO.NE.ZERO ) THENIEEECK = 0RETURNEND IF*NEGINF = ONE / NEGZROIF( NEGINF.GE.ZERO ) THENIEEECK = 0RETURNEND IF*NEWZRO = NEGZRO + ZEROIF( NEWZRO.NE.ZERO ) THENIEEECK = 0RETURNEND IF*POSINF = ONE / NEWZROIF( POSINF.LE.ONE ) THENIEEECK = 0RETURNEND IF*NEGINF = NEGINF*POSINFIF( NEGINF.GE.ZERO ) THENIEEECK = 0RETURNEND IF*POSINF = POSINF*POSINFIF( POSINF.LE.ONE ) THENIEEECK = 0RETURNEND IF***** Return if we were only asked to check infinity arithmetic*IF( ISPEC.EQ.0 )$ RETURN*NAN1 = POSINF + NEGINF*NAN2 = POSINF / NEGINF*NAN3 = POSINF / POSINF*NAN4 = POSINF*ZERO*NAN5 = NEGINF*NEGZRO*NAN6 = NAN5*0.0*IF( NAN1.EQ.NAN1 ) THENIEEECK = 0RETURNEND IF*IF( NAN2.EQ.NAN2 ) THENIEEECK = 0RETURNEND IF*IF( NAN3.EQ.NAN3 ) THENIEEECK = 0RETURNEND IF*IF( NAN4.EQ.NAN4 ) THENIEEECK = 0RETURNEND IF*IF( NAN5.EQ.NAN5 ) THENIEEECK = 0RETURNEND IF*IF( NAN6.EQ.NAN6 ) THENIEEECK = 0RETURNEND IF*RETURNENDINTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3,$ N4 )** -- LAPACK auxiliary 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*( * ) NAME, OPTSINTEGER ISPEC, N1, N2, N3, N4* ..** Purpose* =======** ILAENV is called from the LAPACK routines to choose problem-dependent* parameters for the local environment. See ISPEC for a description of* the parameters.** This version provides a set of parameters which should give good,* but not optimal, performance on many of the currently available* computers. Users are encouraged to modify this subroutine to set* the tuning parameters for their particular machine using the option* and problem size information in the arguments.** This routine will not function correctly if it is converted to all* lower case. Converting it to all upper case is allowed.** Arguments* =========** ISPEC (input) INTEGER* Specifies the parameter to be returned as the value of* ILAENV.* = 1: the optimal blocksize; if this value is 1, an unblocked* algorithm will give the best performance.* = 2: the minimum block size for which the block routine* should be used; if the usable block size is less than* this value, an unblocked routine should be used.* = 3: the crossover point (in a block routine, for N less* than this value, an unblocked routine should be used)* = 4: the number of shifts, used in the nonsymmetric* eigenvalue routines* = 5: the minimum column dimension for blocking to be used;* rectangular blocks must have dimension at least k by m,* where k is given by ILAENV(2,...) and m by ILAENV(5,...)* = 6: the crossover point for the SVD (when reducing an m by n* matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds* this value, a QR factorization is used first to reduce* the matrix to a triangular form.)* = 7: the number of processors* = 8: the crossover point for the multishift QR and QZ methods* for nonsymmetric eigenvalue problems.* = 9: maximum size of the subproblems at the bottom of the* computation tree in the divide-and-conquer algorithm* (used by xGELSD and xGESDD)* =10: ieee NaN arithmetic can be trusted not to trap* =11: infinity arithmetic can be trusted not to trap** NAME (input) CHARACTER*(*)* The name of the calling subroutine, in either upper case or* lower case.** OPTS (input) CHARACTER*(*)* The character options to the subroutine NAME, concatenated* into a single character string. For example, UPLO = 'U',* TRANS = 'T', and DIAG = 'N' for a triangular routine would* be specified as OPTS = 'UTN'.** N1 (input) INTEGER* N2 (input) INTEGER* N3 (input) INTEGER* N4 (input) INTEGER* Problem dimensions for the subroutine NAME; these may not all* be required.** (ILAENV) (output) INTEGER* >= 0: the value of the parameter specified by ISPEC* < 0: if ILAENV = -k, the k-th argument had an illegal value.** Further Details* ===============** The following conventions have been used when calling ILAENV from the* LAPACK routines:* 1) OPTS is a concatenation of all of the character options to* subroutine NAME, in the same order that they appear in the* argument list for NAME, even if they are not used in determining* the value of the parameter specified by ISPEC.* 2) The problem dimensions N1, N2, N3, N4 are specified in the order* that they appear in the argument list for NAME. N1 is used* first, N2 second, and so on, and unused problem dimensions are* passed a value of -1.* 3) The parameter value returned by ILAENV is checked for validity in* the calling subroutine. For example, ILAENV is used to retrieve* the optimal blocksize for STRTRI as follows:** NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )* IF( NB.LE.1 ) NB = MAX( 1, N )** =====================================================================** .. Local Scalars ..LOGICAL CNAME, SNAMECHARACTER*1 C1CHARACTER*2 C2, C4CHARACTER*3 C3CHARACTER*6 SUBNAMINTEGER I, IC, IZ, NB, NBMIN, NX* ..* .. Intrinsic Functions ..INTRINSIC CHAR, ICHAR, INT, MIN, REAL* ..* .. External Functions ..INTEGER IEEECKEXTERNAL IEEECK* ..* .. Executable Statements ..*GO TO ( 100, 100, 100, 400, 500, 600, 700, 800, 900, 1000,$ 1100 ) ISPEC** Invalid value for ISPEC*ILAENV = -1RETURN*100 CONTINUE** Convert NAME to upper case if the first character is lower case.*ILAENV = 1SUBNAM = NAMEIC = ICHAR( SUBNAM( 1:1 ) )IZ = ICHAR( 'Z' )IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN** ASCII character set*IF( IC.GE.97 .AND. IC.LE.122 ) THENSUBNAM( 1:1 ) = CHAR( IC-32 )DO 10 I = 2, 6IC = ICHAR( SUBNAM( I:I ) )IF( IC.GE.97 .AND. IC.LE.122 )$ SUBNAM( I:I ) = CHAR( IC-32 )10 CONTINUEEND IF*ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN** EBCDIC character set*IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) ) THENSUBNAM( 1:1 ) = CHAR( IC+64 )DO 20 I = 2, 6IC = ICHAR( SUBNAM( I:I ) )IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) )$ SUBNAM( I:I ) = CHAR( IC+64 )20 CONTINUEEND IF*ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN** Prime machines: ASCII+128*IF( IC.GE.225 .AND. IC.LE.250 ) THENSUBNAM( 1:1 ) = CHAR( IC-32 )DO 30 I = 2, 6IC = ICHAR( SUBNAM( I:I ) )IF( IC.GE.225 .AND. IC.LE.250 )$ SUBNAM( I:I ) = CHAR( IC-32 )30 CONTINUEEND IFEND IF*C1 = SUBNAM( 1:1 )SNAME = C1.EQ.'S' .OR. C1.EQ.'D'CNAME = C1.EQ.'C' .OR. C1.EQ.'Z'IF( .NOT.( CNAME .OR. SNAME ) )$ RETURNC2 = SUBNAM( 2:3 )C3 = SUBNAM( 4:6 )C4 = C3( 2:3 )*GO TO ( 110, 200, 300 ) ISPEC*110 CONTINUE** ISPEC = 1: block size** In these examples, separate code is provided for setting NB for* real and complex. We assume that NB will take the same value in* single or double precision.*NB = 1*IF( C2.EQ.'GE' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.$ C3.EQ.'QLF' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFELSE IF( C3.EQ.'HRD' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFELSE IF( C3.EQ.'BRD' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFELSE IF( C3.EQ.'TRI' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( C2.EQ.'PO' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( C2.EQ.'SY' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFELSE IF( SNAME .AND. C3.EQ.'TRD' ) THENNB = 32ELSE IF( SNAME .AND. C3.EQ.'GST' ) THENNB = 64END IFELSE IF( CNAME .AND. C2.EQ.'HE' ) THENIF( C3.EQ.'TRF' ) THENNB = 64ELSE IF( C3.EQ.'TRD' ) THENNB = 32ELSE IF( C3.EQ.'GST' ) THENNB = 64END IFELSE IF( SNAME .AND. C2.EQ.'OR' ) THENIF( C3( 1:1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNB = 32END IFELSE IF( C3( 1:1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNB = 32END IFEND IFELSE IF( CNAME .AND. C2.EQ.'UN' ) THENIF( C3( 1:1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNB = 32END IFELSE IF( C3( 1:1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNB = 32END IFEND IFELSE IF( C2.EQ.'GB' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENIF( N4.LE.64 ) THENNB = 1ELSENB = 32END IFELSEIF( N4.LE.64 ) THENNB = 1ELSENB = 32END IFEND IFEND IFELSE IF( C2.EQ.'PB' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENIF( N2.LE.64 ) THENNB = 1ELSENB = 32END IFELSEIF( N2.LE.64 ) THENNB = 1ELSENB = 32END IFEND IFEND IFELSE IF( C2.EQ.'TR' ) THENIF( C3.EQ.'TRI' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( C2.EQ.'LA' ) THENIF( C3.EQ.'UUM' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( SNAME .AND. C2.EQ.'ST' ) THENIF( C3.EQ.'EBZ' ) THENNB = 1END IFEND IFILAENV = NBRETURN*200 CONTINUE** ISPEC = 2: minimum block size*NBMIN = 2IF( C2.EQ.'GE' ) THENIF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.$ C3.EQ.'QLF' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFELSE IF( C3.EQ.'HRD' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFELSE IF( C3.EQ.'BRD' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFELSE IF( C3.EQ.'TRI' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFEND IFELSE IF( C2.EQ.'SY' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNBMIN = 8ELSENBMIN = 8END IFELSE IF( SNAME .AND. C3.EQ.'TRD' ) THENNBMIN = 2END IFELSE IF( CNAME .AND. C2.EQ.'HE' ) THENIF( C3.EQ.'TRD' ) THENNBMIN = 2END IFELSE IF( SNAME .AND. C2.EQ.'OR' ) THENIF( C3( 1:1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNBMIN = 2END IFELSE IF( C3( 1:1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNBMIN = 2END IFEND IFELSE IF( CNAME .AND. C2.EQ.'UN' ) THENIF( C3( 1:1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNBMIN = 2END IFELSE IF( C3( 1:1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNBMIN = 2END IFEND IFEND IFILAENV = NBMINRETURN*300 CONTINUE** ISPEC = 3: crossover point*NX = 0IF( C2.EQ.'GE' ) THENIF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.$ C3.EQ.'QLF' ) THENIF( SNAME ) THENNX = 128ELSENX = 128END IFELSE IF( C3.EQ.'HRD' ) THENIF( SNAME ) THENNX = 128ELSENX = 128END IFELSE IF( C3.EQ.'BRD' ) THENIF( SNAME ) THENNX = 128ELSENX = 128END IFEND IFELSE IF( C2.EQ.'SY' ) THENIF( SNAME .AND. C3.EQ.'TRD' ) THENNX = 32END IFELSE IF( CNAME .AND. C2.EQ.'HE' ) THENIF( C3.EQ.'TRD' ) THENNX = 32END IFELSE IF( SNAME .AND. C2.EQ.'OR' ) THENIF( C3( 1:1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNX = 128END IFEND IFELSE IF( CNAME .AND. C2.EQ.'UN' ) THENIF( C3( 1:1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR.$ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR.$ C4.EQ.'BR' ) THENNX = 128END IFEND IFEND IFILAENV = NXRETURN*400 CONTINUE** ISPEC = 4: number of shifts (used by xHSEQR)*ILAENV = 6RETURN*500 CONTINUE** ISPEC = 5: minimum column dimension (not used)*ILAENV = 2RETURN*600 CONTINUE** ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD)*ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 )RETURN*700 CONTINUE** ISPEC = 7: number of processors (not used)*ILAENV = 1RETURN*800 CONTINUE** ISPEC = 8: crossover point for multishift (used by xHSEQR)*ILAENV = 50RETURN*900 CONTINUE** ISPEC = 9: maximum size of the subproblems at the bottom of the* computation tree in the divide-and-conquer algorithm* (used by xGELSD and xGESDD)*ILAENV = 25RETURN*1000 CONTINUE** ISPEC = 10: ieee NaN arithmetic can be trusted not to trap*C ILAENV = 0ILAENV = 1IF( ILAENV.EQ.1 ) THENILAENV = IEEECK( 0, 0.0, 1.0 )END IFRETURN*1100 CONTINUE** ISPEC = 11: infinity arithmetic can be trusted not to trap*C ILAENV = 0ILAENV = 1IF( ILAENV.EQ.1 ) THENILAENV = IEEECK( 1, 0.0, 1.0 )END IFRETURN** End of ILAENV*END