114
115
116
117
118
119
120 CHARACTER UPLO
121 INTEGER INFO, LDA, N
122
123
124 INTEGER IPIV( * )
125 COMPLEX A( LDA, * ), WORK( * )
126
127
128
129
130
131 REAL ONE
132 COMPLEX CONE, ZERO
133 parameter( one = 1.0e+0, cone = ( 1.0e+0, 0.0e+0 ),
134 $ zero = ( 0.0e+0, 0.0e+0 ) )
135
136
137 LOGICAL UPPER
138 INTEGER J, K, KP, KSTEP
139 REAL AK, AKP1, D, T
140 COMPLEX AKKP1, TEMP
141
142
143 LOGICAL LSAME
144 COMPLEX CDOTC
146
147
149
150
151 INTRINSIC abs, conjg, max, real
152
153
154
155
156
157 info = 0
158 upper =
lsame( uplo,
'U' )
159 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
160 info = -1
161 ELSE IF( n.LT.0 ) THEN
162 info = -2
163 ELSE IF( lda.LT.max( 1, n ) ) THEN
164 info = -4
165 END IF
166 IF( info.NE.0 ) THEN
167 CALL xerbla(
'CHETRI', -info )
168 RETURN
169 END IF
170
171
172
173 IF( n.EQ.0 )
174 $ RETURN
175
176
177
178 IF( upper ) THEN
179
180
181
182 DO 10 info = n, 1, -1
183 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
184 $ RETURN
185 10 CONTINUE
186 ELSE
187
188
189
190 DO 20 info = 1, n
191 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
192 $ RETURN
193 20 CONTINUE
194 END IF
195 info = 0
196
197 IF( upper ) THEN
198
199
200
201
202
203
204 k = 1
205 30 CONTINUE
206
207
208
209 IF( k.GT.n )
210 $ GO TO 50
211
212 IF( ipiv( k ).GT.0 ) THEN
213
214
215
216
217
218 a( k, k ) = one / real( a( k, k ) )
219
220
221
222 IF( k.GT.1 ) THEN
223 CALL ccopy( k-1, a( 1, k ), 1, work, 1 )
224 CALL chemv( uplo, k-1, -cone, a, lda, work, 1, zero,
225 $ a( 1, k ), 1 )
226 a( k, k ) = a( k, k ) - real(
cdotc( k-1, work, 1, a( 1,
227 $ k ), 1 ) )
228 END IF
229 kstep = 1
230 ELSE
231
232
233
234
235
236 t = abs( a( k, k+1 ) )
237 ak = real( a( k, k ) ) / t
238 akp1 = real( a( k+1, k+1 ) ) / t
239 akkp1 = a( k, k+1 ) / t
240 d = t*( ak*akp1-one )
241 a( k, k ) = akp1 / d
242 a( k+1, k+1 ) = ak / d
243 a( k, k+1 ) = -akkp1 / d
244
245
246
247 IF( k.GT.1 ) THEN
248 CALL ccopy( k-1, a( 1, k ), 1, work, 1 )
249 CALL chemv( uplo, k-1, -cone, a, lda, work, 1, zero,
250 $ a( 1, k ), 1 )
251 a( k, k ) = a( k, k ) - real(
cdotc( k-1, work, 1, a( 1,
252 $ k ), 1 ) )
253 a( k, k+1 ) = a( k, k+1 ) -
254 $
cdotc( k-1, a( 1, k ), 1, a( 1, k+1 ), 1 )
255 CALL ccopy( k-1, a( 1, k+1 ), 1, work, 1 )
256 CALL chemv( uplo, k-1, -cone, a, lda, work, 1, zero,
257 $ a( 1, k+1 ), 1 )
258 a( k+1, k+1 ) = a( k+1, k+1 ) -
259 $ real(
cdotc( k-1, work, 1, a( 1, k+1 ),
260 $ 1 ) )
261 END IF
262 kstep = 2
263 END IF
264
265 kp = abs( ipiv( k ) )
266 IF( kp.NE.k ) THEN
267
268
269
270
271 CALL cswap( kp-1, a( 1, k ), 1, a( 1, kp ), 1 )
272 DO 40 j = kp + 1, k - 1
273 temp = conjg( a( j, k ) )
274 a( j, k ) = conjg( a( kp, j ) )
275 a( kp, j ) = temp
276 40 CONTINUE
277 a( kp, k ) = conjg( a( kp, k ) )
278 temp = a( k, k )
279 a( k, k ) = a( kp, kp )
280 a( kp, kp ) = temp
281 IF( kstep.EQ.2 ) THEN
282 temp = a( k, k+1 )
283 a( k, k+1 ) = a( kp, k+1 )
284 a( kp, k+1 ) = temp
285 END IF
286 END IF
287
288 k = k + kstep
289 GO TO 30
290 50 CONTINUE
291
292 ELSE
293
294
295
296
297
298
299 k = n
300 60 CONTINUE
301
302
303
304 IF( k.LT.1 )
305 $ GO TO 80
306
307 IF( ipiv( k ).GT.0 ) THEN
308
309
310
311
312
313 a( k, k ) = one / real( a( k, k ) )
314
315
316
317 IF( k.LT.n ) THEN
318 CALL ccopy( n-k, a( k+1, k ), 1, work, 1 )
319 CALL chemv( uplo, n-k, -cone, a( k+1, k+1 ), lda, work,
320 $ 1, zero, a( k+1, k ), 1 )
321 a( k, k ) = a( k, k ) - real(
cdotc( n-k, work, 1,
322 $ a( k+1, k ), 1 ) )
323 END IF
324 kstep = 1
325 ELSE
326
327
328
329
330
331 t = abs( a( k, k-1 ) )
332 ak = real( a( k-1, k-1 ) ) / t
333 akp1 = real( a( k, k ) ) / t
334 akkp1 = a( k, k-1 ) / t
335 d = t*( ak*akp1-one )
336 a( k-1, k-1 ) = akp1 / d
337 a( k, k ) = ak / d
338 a( k, k-1 ) = -akkp1 / d
339
340
341
342 IF( k.LT.n ) THEN
343 CALL ccopy( n-k, a( k+1, k ), 1, work, 1 )
344 CALL chemv( uplo, n-k, -cone, a( k+1, k+1 ), lda, work,
345 $ 1, zero, a( k+1, k ), 1 )
346 a( k, k ) = a( k, k ) - real(
cdotc( n-k, work, 1,
347 $ a( k+1, k ), 1 ) )
348 a( k, k-1 ) = a( k, k-1 ) -
349 $
cdotc( n-k, a( k+1, k ), 1, a( k+1, k-1 ),
350 $ 1 )
351 CALL ccopy( n-k, a( k+1, k-1 ), 1, work, 1 )
352 CALL chemv( uplo, n-k, -cone, a( k+1, k+1 ), lda, work,
353 $ 1, zero, a( k+1, k-1 ), 1 )
354 a( k-1, k-1 ) = a( k-1, k-1 ) -
355 $ real(
cdotc( n-k, work, 1, a( k+1, k-1 ),
356 $ 1 ) )
357 END IF
358 kstep = 2
359 END IF
360
361 kp = abs( ipiv( k ) )
362 IF( kp.NE.k ) THEN
363
364
365
366
367 IF( kp.LT.n )
368 $
CALL cswap( n-kp, a( kp+1, k ), 1, a( kp+1, kp ), 1 )
369 DO 70 j = k + 1, kp - 1
370 temp = conjg( a( j, k ) )
371 a( j, k ) = conjg( a( kp, j ) )
372 a( kp, j ) = temp
373 70 CONTINUE
374 a( kp, k ) = conjg( a( kp, k ) )
375 temp = a( k, k )
376 a( k, k ) = a( kp, kp )
377 a( kp, kp ) = temp
378 IF( kstep.EQ.2 ) THEN
379 temp = a( k, k-1 )
380 a( k, k-1 ) = a( kp, k-1 )
381 a( kp, k-1 ) = temp
382 END IF
383 END IF
384
385 k = k - kstep
386 GO TO 60
387 80 CONTINUE
388 END IF
389
390 RETURN
391
392
393
subroutine xerbla(srname, info)
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
complex function cdotc(n, cx, incx, cy, incy)
CDOTC
subroutine chemv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
CHEMV
logical function lsame(ca, cb)
LSAME
subroutine cswap(n, cx, incx, cy, incy)
CSWAP