Annotation of rpl/lapack/lapack/dgghrd.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
! 2: $ LDQ, Z, LDZ, INFO )
! 3: *
! 4: * -- LAPACK routine (version 3.2) --
! 5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 7: * November 2006
! 8: *
! 9: * .. Scalar Arguments ..
! 10: CHARACTER COMPQ, COMPZ
! 11: INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
! 12: * ..
! 13: * .. Array Arguments ..
! 14: DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
! 15: $ Z( LDZ, * )
! 16: * ..
! 17: *
! 18: * Purpose
! 19: * =======
! 20: *
! 21: * DGGHRD reduces a pair of real matrices (A,B) to generalized upper
! 22: * Hessenberg form using orthogonal transformations, where A is a
! 23: * general matrix and B is upper triangular. The form of the
! 24: * generalized eigenvalue problem is
! 25: * A*x = lambda*B*x,
! 26: * and B is typically made upper triangular by computing its QR
! 27: * factorization and moving the orthogonal matrix Q to the left side
! 28: * of the equation.
! 29: *
! 30: * This subroutine simultaneously reduces A to a Hessenberg matrix H:
! 31: * Q**T*A*Z = H
! 32: * and transforms B to another upper triangular matrix T:
! 33: * Q**T*B*Z = T
! 34: * in order to reduce the problem to its standard form
! 35: * H*y = lambda*T*y
! 36: * where y = Z**T*x.
! 37: *
! 38: * The orthogonal matrices Q and Z are determined as products of Givens
! 39: * rotations. They may either be formed explicitly, or they may be
! 40: * postmultiplied into input matrices Q1 and Z1, so that
! 41: *
! 42: * Q1 * A * Z1**T = (Q1*Q) * H * (Z1*Z)**T
! 43: *
! 44: * Q1 * B * Z1**T = (Q1*Q) * T * (Z1*Z)**T
! 45: *
! 46: * If Q1 is the orthogonal matrix from the QR factorization of B in the
! 47: * original equation A*x = lambda*B*x, then DGGHRD reduces the original
! 48: * problem to generalized Hessenberg form.
! 49: *
! 50: * Arguments
! 51: * =========
! 52: *
! 53: * COMPQ (input) CHARACTER*1
! 54: * = 'N': do not compute Q;
! 55: * = 'I': Q is initialized to the unit matrix, and the
! 56: * orthogonal matrix Q is returned;
! 57: * = 'V': Q must contain an orthogonal matrix Q1 on entry,
! 58: * and the product Q1*Q is returned.
! 59: *
! 60: * COMPZ (input) CHARACTER*1
! 61: * = 'N': do not compute Z;
! 62: * = 'I': Z is initialized to the unit matrix, and the
! 63: * orthogonal matrix Z is returned;
! 64: * = 'V': Z must contain an orthogonal matrix Z1 on entry,
! 65: * and the product Z1*Z is returned.
! 66: *
! 67: * N (input) INTEGER
! 68: * The order of the matrices A and B. N >= 0.
! 69: *
! 70: * ILO (input) INTEGER
! 71: * IHI (input) INTEGER
! 72: * ILO and IHI mark the rows and columns of A which are to be
! 73: * reduced. It is assumed that A is already upper triangular
! 74: * in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are
! 75: * normally set by a previous call to SGGBAL; otherwise they
! 76: * should be set to 1 and N respectively.
! 77: * 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
! 78: *
! 79: * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
! 80: * On entry, the N-by-N general matrix to be reduced.
! 81: * On exit, the upper triangle and the first subdiagonal of A
! 82: * are overwritten with the upper Hessenberg matrix H, and the
! 83: * rest is set to zero.
! 84: *
! 85: * LDA (input) INTEGER
! 86: * The leading dimension of the array A. LDA >= max(1,N).
! 87: *
! 88: * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
! 89: * On entry, the N-by-N upper triangular matrix B.
! 90: * On exit, the upper triangular matrix T = Q**T B Z. The
! 91: * elements below the diagonal are set to zero.
! 92: *
! 93: * LDB (input) INTEGER
! 94: * The leading dimension of the array B. LDB >= max(1,N).
! 95: *
! 96: * Q (input/output) DOUBLE PRECISION array, dimension (LDQ, N)
! 97: * On entry, if COMPQ = 'V', the orthogonal matrix Q1,
! 98: * typically from the QR factorization of B.
! 99: * On exit, if COMPQ='I', the orthogonal matrix Q, and if
! 100: * COMPQ = 'V', the product Q1*Q.
! 101: * Not referenced if COMPQ='N'.
! 102: *
! 103: * LDQ (input) INTEGER
! 104: * The leading dimension of the array Q.
! 105: * LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
! 106: *
! 107: * Z (input/output) DOUBLE PRECISION array, dimension (LDZ, N)
! 108: * On entry, if COMPZ = 'V', the orthogonal matrix Z1.
! 109: * On exit, if COMPZ='I', the orthogonal matrix Z, and if
! 110: * COMPZ = 'V', the product Z1*Z.
! 111: * Not referenced if COMPZ='N'.
! 112: *
! 113: * LDZ (input) INTEGER
! 114: * The leading dimension of the array Z.
! 115: * LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
! 116: *
! 117: * INFO (output) INTEGER
! 118: * = 0: successful exit.
! 119: * < 0: if INFO = -i, the i-th argument had an illegal value.
! 120: *
! 121: * Further Details
! 122: * ===============
! 123: *
! 124: * This routine reduces A to Hessenberg and B to triangular form by
! 125: * an unblocked reduction, as described in _Matrix_Computations_,
! 126: * by Golub and Van Loan (Johns Hopkins Press.)
! 127: *
! 128: * =====================================================================
! 129: *
! 130: * .. Parameters ..
! 131: DOUBLE PRECISION ONE, ZERO
! 132: PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
! 133: * ..
! 134: * .. Local Scalars ..
! 135: LOGICAL ILQ, ILZ
! 136: INTEGER ICOMPQ, ICOMPZ, JCOL, JROW
! 137: DOUBLE PRECISION C, S, TEMP
! 138: * ..
! 139: * .. External Functions ..
! 140: LOGICAL LSAME
! 141: EXTERNAL LSAME
! 142: * ..
! 143: * .. External Subroutines ..
! 144: EXTERNAL DLARTG, DLASET, DROT, XERBLA
! 145: * ..
! 146: * .. Intrinsic Functions ..
! 147: INTRINSIC MAX
! 148: * ..
! 149: * .. Executable Statements ..
! 150: *
! 151: * Decode COMPQ
! 152: *
! 153: IF( LSAME( COMPQ, 'N' ) ) THEN
! 154: ILQ = .FALSE.
! 155: ICOMPQ = 1
! 156: ELSE IF( LSAME( COMPQ, 'V' ) ) THEN
! 157: ILQ = .TRUE.
! 158: ICOMPQ = 2
! 159: ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
! 160: ILQ = .TRUE.
! 161: ICOMPQ = 3
! 162: ELSE
! 163: ICOMPQ = 0
! 164: END IF
! 165: *
! 166: * Decode COMPZ
! 167: *
! 168: IF( LSAME( COMPZ, 'N' ) ) THEN
! 169: ILZ = .FALSE.
! 170: ICOMPZ = 1
! 171: ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
! 172: ILZ = .TRUE.
! 173: ICOMPZ = 2
! 174: ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
! 175: ILZ = .TRUE.
! 176: ICOMPZ = 3
! 177: ELSE
! 178: ICOMPZ = 0
! 179: END IF
! 180: *
! 181: * Test the input parameters.
! 182: *
! 183: INFO = 0
! 184: IF( ICOMPQ.LE.0 ) THEN
! 185: INFO = -1
! 186: ELSE IF( ICOMPZ.LE.0 ) THEN
! 187: INFO = -2
! 188: ELSE IF( N.LT.0 ) THEN
! 189: INFO = -3
! 190: ELSE IF( ILO.LT.1 ) THEN
! 191: INFO = -4
! 192: ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THEN
! 193: INFO = -5
! 194: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
! 195: INFO = -7
! 196: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
! 197: INFO = -9
! 198: ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THEN
! 199: INFO = -11
! 200: ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THEN
! 201: INFO = -13
! 202: END IF
! 203: IF( INFO.NE.0 ) THEN
! 204: CALL XERBLA( 'DGGHRD', -INFO )
! 205: RETURN
! 206: END IF
! 207: *
! 208: * Initialize Q and Z if desired.
! 209: *
! 210: IF( ICOMPQ.EQ.3 )
! 211: $ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )
! 212: IF( ICOMPZ.EQ.3 )
! 213: $ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
! 214: *
! 215: * Quick return if possible
! 216: *
! 217: IF( N.LE.1 )
! 218: $ RETURN
! 219: *
! 220: * Zero out lower triangle of B
! 221: *
! 222: DO 20 JCOL = 1, N - 1
! 223: DO 10 JROW = JCOL + 1, N
! 224: B( JROW, JCOL ) = ZERO
! 225: 10 CONTINUE
! 226: 20 CONTINUE
! 227: *
! 228: * Reduce A and B
! 229: *
! 230: DO 40 JCOL = ILO, IHI - 2
! 231: *
! 232: DO 30 JROW = IHI, JCOL + 2, -1
! 233: *
! 234: * Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)
! 235: *
! 236: TEMP = A( JROW-1, JCOL )
! 237: CALL DLARTG( TEMP, A( JROW, JCOL ), C, S,
! 238: $ A( JROW-1, JCOL ) )
! 239: A( JROW, JCOL ) = ZERO
! 240: CALL DROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,
! 241: $ A( JROW, JCOL+1 ), LDA, C, S )
! 242: CALL DROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,
! 243: $ B( JROW, JROW-1 ), LDB, C, S )
! 244: IF( ILQ )
! 245: $ CALL DROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C, S )
! 246: *
! 247: * Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)
! 248: *
! 249: TEMP = B( JROW, JROW )
! 250: CALL DLARTG( TEMP, B( JROW, JROW-1 ), C, S,
! 251: $ B( JROW, JROW ) )
! 252: B( JROW, JROW-1 ) = ZERO
! 253: CALL DROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )
! 254: CALL DROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,
! 255: $ S )
! 256: IF( ILZ )
! 257: $ CALL DROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )
! 258: 30 CONTINUE
! 259: 40 CONTINUE
! 260: *
! 261: RETURN
! 262: *
! 263: * End of DGGHRD
! 264: *
! 265: END
CVSweb interface <joel.bertrand@systella.fr>