1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
SUBROUTINE DLAQZH( ILQ, ILZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ,
$ Z, LDZ, WORK, INFO )
*
* -- LAPACK timing 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 ..
LOGICAL ILQ, ILZ
INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N
* ..
* .. Array Arguments ..
DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
$ WORK( N ), Z( LDZ, * )
* ..
*
* Purpose
* =======
*
* This calls the LAPACK routines to perform the function of
* QZHES. It is similar in function to DGGHRD, except that
* B is not assumed to be upper-triangular.
*
* It reduces a pair of matrices (A,B) to a Hessenberg-triangular
* pair (H,T). More specifically, it computes orthogonal matrices
* Q and Z, an (upper) Hessenberg matrix H, and an upper triangular
* matrix T such that:
*
* A = Q H Z' and B = Q T Z'
*
*
* Arguments
* =========
*
* ILQ (input) LOGICAL
* = .FALSE. do not compute Q.
* = .TRUE. compute Q.
*
* ILZ (input) LOGICAL
* = .FALSE. do not compute Z.
* = .TRUE. compute Z.
*
* N (input) INTEGER
* The number of rows and columns in the matrices A, B, Q, and
* Z. N must be at least 0.
*
* ILO (input) INTEGER
* Columns 1 through ILO-1 of A and B are assumed to be in
* upper triangular form already, and will not be modified.
* ILO must be at least 1.
*
* IHI (input) INTEGER
* Rows IHI+1 through N of A and B are assumed to be in upper
* triangular form already, and will not be touched. IHI may
* not be greater than N.
*
* A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
* On entry, the first of the pair of N x N general matrices to
* be reduced.
* On exit, the upper triangle and the first subdiagonal of A
* are overwritten with the Hessenberg matrix H, and the rest
* is set to zero.
*
* LDA (input) INTEGER
* The leading dimension of A as declared in the calling
* program. LDA must be at least max ( 1, N ) .
*
* B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
* On entry, the second of the pair of N x N general matrices to
* be reduced.
* On exit, the transformed matrix T = Q' B Z, which is upper
* triangular.
*
* LDB (input) INTEGER
* The leading dimension of B as declared in the calling
* program. LDB must be at least max ( 1, N ) .
*
* Q (output) DOUBLE PRECISION array, dimension (LDQ,N)
* If ILQ = .TRUE., Q will contain the orthogonal matrix Q.
* (See "Purpose", above.)
* Will not be referenced if ILQ = .FALSE.
*
* LDQ (input) INTEGER
* The leading dimension of the matrix Q. LDQ must be at
* least 1 and at least N.
*
* Z (output) DOUBLE PRECISION array, dimension (LDZ,N)
* If ILZ = .TRUE., Z will contain the orthogonal matrix Z.
* (See "Purpose", above.)
* May be referenced even if ILZ = .FALSE.
*
* LDZ (input) INTEGER
* The leading dimension of the matrix Z. LDZ must be at
* least 1 and at least N.
*
* WORK (workspace) DOUBLE PRECISION array, dimension (N)
* Workspace.
*
* INFO (output) INTEGER
* = 0: successful exit.
* < 0: if INFO = -i, the i-th argument had an illegal value.
* > 0: errors that usually indicate LAPACK problems:
* = 2: error return from DGEQRF;
* = 3: error return from DORMQR;
* = 4: error return from DORGQR;
* = 5: error return from DGGHRD.
*
* =====================================================================
*
* .. Parameters ..
DOUBLE PRECISION ZERO, ONE
PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
* ..
* .. Local Scalars ..
CHARACTER COMPQ, COMPZ
INTEGER ICOLS, IINFO, IROWS
* ..
* .. External Subroutines ..
EXTERNAL DGEQRF, DGGHRD, DLACPY, DLASET, DORGQR, DORMQR
* ..
* .. Executable Statements ..
*
* Quick return if possible
*
IF( N.EQ.0 )
$ RETURN
*
* Reduce B to triangular form, and initialize Q and/or Z
*
IROWS = IHI + 1 - ILO
ICOLS = N + 1 - ILO
CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK, Z, N*LDZ,
$ IINFO )
IF( IINFO.NE.0 ) THEN
INFO = 2
GO TO 10
END IF
*
CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
$ WORK, A( ILO, ILO ), LDA, Z, N*LDZ, IINFO )
IF( IINFO.NE.0 ) THEN
INFO = 3
GO TO 10
END IF
*
IF( ILQ ) THEN
CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )
CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
$ Q( ILO+1, ILO ), LDQ )
CALL DORGQR( IROWS, IROWS, IROWS, Q( ILO, ILO ), LDQ, WORK, Z,
$ N*LDZ, IINFO )
IF( IINFO.NE.0 ) THEN
INFO = 4
GO TO 10
END IF
END IF
*
* Reduce to generalized Hessenberg form
*
IF( ILQ ) THEN
COMPQ = 'V'
ELSE
COMPQ = 'N'
END IF
*
IF( ILZ ) THEN
COMPZ = 'I'
ELSE
COMPZ = 'N'
END IF
*
CALL DGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z,
$ LDZ, IINFO )
IF( IINFO.NE.0 ) THEN
INFO = 5
GO TO 10
END IF
*
* End
*
10 CONTINUE
*
RETURN
*
* End of DLAQZH
*
END
|