132
133
134
135
136
137 IMPLICIT NONE
138
139
140 CHARACTER UPLO
141 INTEGER N, LDA, LWORK, INFO
142
143
144 INTEGER IPIV( * )
145 COMPLEX A( LDA, * ), WORK( * )
146
147
148
149
150 COMPLEX ZERO, ONE
151 parameter( zero = (0.0e+0, 0.0e+0), one = (1.0e+0, 0.0e+0) )
152
153
154 LOGICAL LQUERY, UPPER
155 INTEGER J, LWKOPT
156 INTEGER NB, MJ, NJ, K1, K2, J1, J2, J3, JB
157 COMPLEX ALPHA
158
159
160 LOGICAL LSAME
161 INTEGER ILAENV
162 REAL SROUNDUP_LWORK
164
165
167
168
169 INTRINSIC real, conjg, max
170
171
172
173
174
175 nb =
ilaenv( 1,
'CHETRF_AA', uplo, n, -1, -1, -1 )
176
177
178
179 info = 0
180 upper =
lsame( uplo,
'U' )
181 lquery = ( lwork.EQ.-1 )
182 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
183 info = -1
184 ELSE IF( n.LT.0 ) THEN
185 info = -2
186 ELSE IF( lda.LT.max( 1, n ) ) THEN
187 info = -4
188 ELSE IF( lwork.LT.( 2*n ) .AND. .NOT.lquery ) THEN
189 info = -7
190 END IF
191
192 IF( info.EQ.0 ) THEN
193 lwkopt = (nb+1)*n
195 END IF
196
197 IF( info.NE.0 ) THEN
198 CALL xerbla(
'CHETRF_AA', -info )
199 RETURN
200 ELSE IF( lquery ) THEN
201 RETURN
202 END IF
203
204
205
206 IF ( n.EQ.0 ) THEN
207 RETURN
208 ENDIF
209 ipiv( 1 ) = 1
210 IF ( n.EQ.1 ) THEN
211 a( 1, 1 ) = real( a( 1, 1 ) )
212 RETURN
213 END IF
214
215
216
217 IF( lwork.LT.((1+nb)*n) ) THEN
218 nb = ( lwork-n ) / n
219 END IF
220
221 IF( upper ) THEN
222
223
224
225
226
227
228
229 CALL ccopy( n, a( 1, 1 ), lda, work( 1 ), 1 )
230
231
232
233
234
235 j = 0
236 10 CONTINUE
237 IF( j.GE.n )
238 $ GO TO 20
239
240
241
242
243
244
245
246
247 j1 = j + 1
248 jb = min( n-j1+1, nb )
249 k1 = max(1, j)-j
250
251
252
254 $ a( max(1, j), j+1 ), lda,
255 $ ipiv( j+1 ), work, n, work( n*nb+1 ) )
256
257
258
259 DO j2 = j+2, min(n, j+jb+1)
260 ipiv( j2 ) = ipiv( j2 ) + j
261 IF( (j2.NE.ipiv(j2)) .AND. ((j1-k1).GT.2) ) THEN
262 CALL cswap( j1-k1-2, a( 1, j2 ), 1,
263 $ a( 1, ipiv(j2) ), 1 )
264 END IF
265 END DO
266 j = j + jb
267
268
269
270
271
272 IF( j.LT.n ) THEN
273
274
275
276 IF( j1.GT.1 .OR. jb.GT.1 ) THEN
277
278
279
280 alpha = conjg( a( j, j+1 ) )
281 a( j, j+1 ) = one
282 CALL ccopy( n-j, a( j-1, j+1 ), lda,
283 $ work( (j+1-j1+1)+jb*n ), 1 )
284 CALL cscal( n-j, alpha, work( (j+1-j1+1)+jb*n ), 1 )
285
286
287
288
289
290 IF( j1.GT.1 ) THEN
291
292
293
294 k2 = 1
295 ELSE
296
297
298
299 k2 = 0
300
301
302
303 jb = jb - 1
304 END IF
305
306 DO j2 = j+1, n, nb
307 nj = min( nb, n-j2+1 )
308
309
310
311 j3 = j2
312 DO mj = nj-1, 1, -1
313 CALL cgemm(
'Conjugate transpose',
'Transpose',
314 $ 1, mj, jb+1,
315 $ -one, a( j1-k2, j3 ), lda,
316 $ work( (j3-j1+1)+k1*n ), n,
317 $ one, a( j3, j3 ), lda )
318 j3 = j3 + 1
319 END DO
320
321
322
323 CALL cgemm(
'Conjugate transpose',
'Transpose',
324 $ nj, n-j3+1, jb+1,
325 $ -one, a( j1-k2, j2 ), lda,
326 $ work( (j3-j1+1)+k1*n ), n,
327 $ one, a( j2, j3 ), lda )
328 END DO
329
330
331
332 a( j, j+1 ) = conjg( alpha )
333 END IF
334
335
336
337 CALL ccopy( n-j, a( j+1, j+1 ), lda, work( 1 ), 1 )
338 END IF
339 GO TO 10
340 ELSE
341
342
343
344
345
346
347
348
349 CALL ccopy( n, a( 1, 1 ), 1, work( 1 ), 1 )
350
351
352
353
354
355 j = 0
356 11 CONTINUE
357 IF( j.GE.n )
358 $ GO TO 20
359
360
361
362
363
364
365
366
367 j1 = j+1
368 jb = min( n-j1+1, nb )
369 k1 = max(1, j)-j
370
371
372
374 $ a( j+1, max(1, j) ), lda,
375 $ ipiv( j+1 ), work, n, work( n*nb+1 ) )
376
377
378
379 DO j2 = j+2, min(n, j+jb+1)
380 ipiv( j2 ) = ipiv( j2 ) + j
381 IF( (j2.NE.ipiv(j2)) .AND. ((j1-k1).GT.2) ) THEN
382 CALL cswap( j1-k1-2, a( j2, 1 ), lda,
383 $ a( ipiv(j2), 1 ), lda )
384 END IF
385 END DO
386 j = j + jb
387
388
389
390
391
392 IF( j.LT.n ) THEN
393
394
395
396 IF( j1.GT.1 .OR. jb.GT.1 ) THEN
397
398
399
400 alpha = conjg( a( j+1, j ) )
401 a( j+1, j ) = one
402 CALL ccopy( n-j, a( j+1, j-1 ), 1,
403 $ work( (j+1-j1+1)+jb*n ), 1 )
404 CALL cscal( n-j, alpha, work( (j+1-j1+1)+jb*n ), 1 )
405
406
407
408
409
410 IF( j1.GT.1 ) THEN
411
412
413
414 k2 = 1
415 ELSE
416
417
418
419 k2 = 0
420
421
422
423 jb = jb - 1
424 END IF
425
426 DO j2 = j+1, n, nb
427 nj = min( nb, n-j2+1 )
428
429
430
431 j3 = j2
432 DO mj = nj-1, 1, -1
433 CALL cgemm(
'No transpose',
'Conjugate transpose',
434 $ mj, 1, jb+1,
435 $ -one, work( (j3-j1+1)+k1*n ), n,
436 $ a( j3, j1-k2 ), lda,
437 $ one, a( j3, j3 ), lda )
438 j3 = j3 + 1
439 END DO
440
441
442
443 CALL cgemm(
'No transpose',
'Conjugate transpose',
444 $ n-j3+1, nj, jb+1,
445 $ -one, work( (j3-j1+1)+k1*n ), n,
446 $ a( j2, j1-k2 ), lda,
447 $ one, a( j3, j2 ), lda )
448 END DO
449
450
451
452 a( j+1, j ) = conjg( alpha )
453 END IF
454
455
456
457 CALL ccopy( n-j, a( j+1, j+1 ), 1, work( 1 ), 1 )
458 END IF
459 GO TO 11
460 END IF
461
462 20 CONTINUE
464 RETURN
465
466
467
subroutine xerbla(srname, info)
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine clahef_aa(uplo, j1, m, nb, a, lda, ipiv, h, ldh, work)
CLAHEF_AA
logical function lsame(ca, cb)
LSAME
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine cscal(n, ca, cx, incx)
CSCAL
subroutine cswap(n, cx, incx, cy, incy)
CSWAP