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