Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgehrd.f
5213 views
1
SUBROUTINE CGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )
2
*
3
* -- LAPACK routine (version 3.0) --
4
* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
5
* Courant Institute, Argonne National Lab, and Rice University
6
* June 30, 1999
7
*
8
* .. Scalar Arguments ..
9
INTEGER IHI, ILO, INFO, LDA, LWORK, N
10
* ..
11
* .. Array Arguments ..
12
COMPLEX A( LDA, * ), TAU( * ), WORK( * )
13
* ..
14
*
15
* Purpose
16
* =======
17
*
18
* CGEHRD reduces a complex general matrix A to upper Hessenberg form H
19
* by a unitary similarity transformation: Q' * A * Q = H .
20
*
21
* Arguments
22
* =========
23
*
24
* N (input) INTEGER
25
* The order of the matrix A. N >= 0.
26
*
27
* ILO (input) INTEGER
28
* IHI (input) INTEGER
29
* It is assumed that A is already upper triangular in rows
30
* and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
31
* set by a previous call to CGEBAL; otherwise they should be
32
* set to 1 and N respectively. See Further Details.
33
* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
34
*
35
* A (input/output) COMPLEX array, dimension (LDA,N)
36
* On entry, the N-by-N general matrix to be reduced.
37
* On exit, the upper triangle and the first subdiagonal of A
38
* are overwritten with the upper Hessenberg matrix H, and the
39
* elements below the first subdiagonal, with the array TAU,
40
* represent the unitary matrix Q as a product of elementary
41
* reflectors. See Further Details.
42
*
43
* LDA (input) INTEGER
44
* The leading dimension of the array A. LDA >= max(1,N).
45
*
46
* TAU (output) COMPLEX array, dimension (N-1)
47
* The scalar factors of the elementary reflectors (see Further
48
* Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to
49
* zero.
50
*
51
* WORK (workspace/output) COMPLEX array, dimension (LWORK)
52
* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
53
*
54
* LWORK (input) INTEGER
55
* The length of the array WORK. LWORK >= max(1,N).
56
* For optimum performance LWORK >= N*NB, where NB is the
57
* optimal blocksize.
58
*
59
* If LWORK = -1, then a workspace query is assumed; the routine
60
* only calculates the optimal size of the WORK array, returns
61
* this value as the first entry of the WORK array, and no error
62
* message related to LWORK is issued by XERBLA.
63
*
64
* INFO (output) INTEGER
65
* = 0: successful exit
66
* < 0: if INFO = -i, the i-th argument had an illegal value.
67
*
68
* Further Details
69
* ===============
70
*
71
* The matrix Q is represented as a product of (ihi-ilo) elementary
72
* reflectors
73
*
74
* Q = H(ilo) H(ilo+1) . . . H(ihi-1).
75
*
76
* Each H(i) has the form
77
*
78
* H(i) = I - tau * v * v'
79
*
80
* where tau is a complex scalar, and v is a complex vector with
81
* v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
82
* exit in A(i+2:ihi,i), and tau in TAU(i).
83
*
84
* The contents of A are illustrated by the following example, with
85
* n = 7, ilo = 2 and ihi = 6:
86
*
87
* on entry, on exit,
88
*
89
* ( a a a a a a a ) ( a a h h h h a )
90
* ( a a a a a a ) ( a h h h h a )
91
* ( a a a a a a ) ( h h h h h h )
92
* ( a a a a a a ) ( v2 h h h h h )
93
* ( a a a a a a ) ( v2 v3 h h h h )
94
* ( a a a a a a ) ( v2 v3 v4 h h h )
95
* ( a ) ( a )
96
*
97
* where a denotes an element of the original matrix A, h denotes a
98
* modified element of the upper Hessenberg matrix H, and vi denotes an
99
* element of the vector defining H(i).
100
*
101
* =====================================================================
102
*
103
* .. Parameters ..
104
INTEGER NBMAX, LDT
105
PARAMETER ( NBMAX = 64, LDT = NBMAX+1 )
106
COMPLEX ZERO, ONE
107
PARAMETER ( ZERO = ( 0.0E+0, 0.0E+0 ),
108
$ ONE = ( 1.0E+0, 0.0E+0 ) )
109
* ..
110
* .. Local Scalars ..
111
LOGICAL LQUERY
112
INTEGER I, IB, IINFO, IWS, LDWORK, LWKOPT, NB, NBMIN,
113
$ NH, NX
114
COMPLEX EI
115
* ..
116
* .. Local Arrays ..
117
COMPLEX T( LDT, NBMAX )
118
* ..
119
* .. External Subroutines ..
120
EXTERNAL CGEHD2, CGEMM, CLAHRD, CLARFB, XERBLA
121
* ..
122
* .. Intrinsic Functions ..
123
INTRINSIC MAX, MIN
124
* ..
125
* .. External Functions ..
126
INTEGER ILAENV
127
EXTERNAL ILAENV
128
* ..
129
* .. Executable Statements ..
130
*
131
* Test the input parameters
132
*
133
INFO = 0
134
NB = MIN( NBMAX, ILAENV( 1, 'CGEHRD', ' ', N, ILO, IHI, -1 ) )
135
LWKOPT = N*NB
136
WORK( 1 ) = LWKOPT
137
LQUERY = ( LWORK.EQ.-1 )
138
IF( N.LT.0 ) THEN
139
INFO = -1
140
ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN
141
INFO = -2
142
ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN
143
INFO = -3
144
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
145
INFO = -5
146
ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
147
INFO = -8
148
END IF
149
IF( INFO.NE.0 ) THEN
150
CALL XERBLA( 'CGEHRD', -INFO )
151
RETURN
152
ELSE IF( LQUERY ) THEN
153
RETURN
154
END IF
155
*
156
* Set elements 1:ILO-1 and IHI:N-1 of TAU to zero
157
*
158
DO 10 I = 1, ILO - 1
159
TAU( I ) = ZERO
160
10 CONTINUE
161
DO 20 I = MAX( 1, IHI ), N - 1
162
TAU( I ) = ZERO
163
20 CONTINUE
164
*
165
* Quick return if possible
166
*
167
NH = IHI - ILO + 1
168
IF( NH.LE.1 ) THEN
169
WORK( 1 ) = 1
170
RETURN
171
END IF
172
*
173
NBMIN = 2
174
IWS = 1
175
IF( NB.GT.1 .AND. NB.LT.NH ) THEN
176
*
177
* Determine when to cross over from blocked to unblocked code
178
* (last block is always handled by unblocked code).
179
*
180
NX = MAX( NB, ILAENV( 3, 'CGEHRD', ' ', N, ILO, IHI, -1 ) )
181
IF( NX.LT.NH ) THEN
182
*
183
* Determine if workspace is large enough for blocked code.
184
*
185
IWS = N*NB
186
IF( LWORK.LT.IWS ) THEN
187
*
188
* Not enough workspace to use optimal NB: determine the
189
* minimum value of NB, and reduce NB or force use of
190
* unblocked code.
191
*
192
NBMIN = MAX( 2, ILAENV( 2, 'CGEHRD', ' ', N, ILO, IHI,
193
$ -1 ) )
194
IF( LWORK.GE.N*NBMIN ) THEN
195
NB = LWORK / N
196
ELSE
197
NB = 1
198
END IF
199
END IF
200
END IF
201
END IF
202
LDWORK = N
203
*
204
IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN
205
*
206
* Use unblocked code below
207
*
208
I = ILO
209
*
210
ELSE
211
*
212
* Use blocked code
213
*
214
DO 30 I = ILO, IHI - 1 - NX, NB
215
IB = MIN( NB, IHI-I )
216
*
217
* Reduce columns i:i+ib-1 to Hessenberg form, returning the
218
* matrices V and T of the block reflector H = I - V*T*V'
219
* which performs the reduction, and also the matrix Y = A*V*T
220
*
221
CALL CLAHRD( IHI, I, IB, A( 1, I ), LDA, TAU( I ), T, LDT,
222
$ WORK, LDWORK )
223
*
224
* Apply the block reflector H to A(1:ihi,i+ib:ihi) from the
225
* right, computing A := A - Y * V'. V(i+ib,ib-1) must be set
226
* to 1.
227
*
228
EI = A( I+IB, I+IB-1 )
229
A( I+IB, I+IB-1 ) = ONE
230
CALL CGEMM( 'No transpose', 'Conjugate transpose', IHI,
231
$ IHI-I-IB+1, IB, -ONE, WORK, LDWORK,
232
$ A( I+IB, I ), LDA, ONE, A( 1, I+IB ), LDA )
233
A( I+IB, I+IB-1 ) = EI
234
*
235
* Apply the block reflector H to A(i+1:ihi,i+ib:n) from the
236
* left
237
*
238
CALL CLARFB( 'Left', 'Conjugate transpose', 'Forward',
239
$ 'Columnwise', IHI-I, N-I-IB+1, IB, A( I+1, I ),
240
$ LDA, T, LDT, A( I+1, I+IB ), LDA, WORK,
241
$ LDWORK )
242
30 CONTINUE
243
END IF
244
*
245
* Use unblocked code to reduce the rest of the matrix
246
*
247
CALL CGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )
248
WORK( 1 ) = IWS
249
*
250
RETURN
251
*
252
* End of CGEHRD
253
*
254
END
255
256