00001 SUBROUTINE ZLAHEF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 CHARACTER UPLO
00010 INTEGER INFO, KB, LDA, LDW, N, NB
00011
00012
00013 INTEGER IPIV( * )
00014 COMPLEX*16 A( LDA, * ), W( LDW, * )
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 DOUBLE PRECISION ZERO, ONE
00100 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
00101 COMPLEX*16 CONE
00102 PARAMETER ( CONE = ( 1.0D+0, 0.0D+0 ) )
00103 DOUBLE PRECISION EIGHT, SEVTEN
00104 PARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 )
00105
00106
00107 INTEGER IMAX, J, JB, JJ, JMAX, JP, K, KK, KKW, KP,
00108 $ KSTEP, KW
00109 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, R1, ROWMAX, T
00110 COMPLEX*16 D11, D21, D22, Z
00111
00112
00113 LOGICAL LSAME
00114 INTEGER IZAMAX
00115 EXTERNAL LSAME, IZAMAX
00116
00117
00118 EXTERNAL ZCOPY, ZDSCAL, ZGEMM, ZGEMV, ZLACGV, ZSWAP
00119
00120
00121 INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, MIN, SQRT
00122
00123
00124 DOUBLE PRECISION CABS1
00125
00126
00127 CABS1( Z ) = ABS( DBLE( Z ) ) + ABS( DIMAG( Z ) )
00128
00129
00130
00131 INFO = 0
00132
00133
00134
00135 ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT
00136
00137 IF( LSAME( UPLO, 'U' ) ) THEN
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 K = N
00148 10 CONTINUE
00149 KW = NB + K - N
00150
00151
00152
00153 IF( ( K.LE.N-NB+1 .AND. NB.LT.N ) .OR. K.LT.1 )
00154 $ GO TO 30
00155
00156
00157
00158 CALL ZCOPY( K-1, A( 1, K ), 1, W( 1, KW ), 1 )
00159 W( K, KW ) = DBLE( A( K, K ) )
00160 IF( K.LT.N ) THEN
00161 CALL ZGEMV( 'No transpose', K, N-K, -CONE, A( 1, K+1 ), LDA,
00162 $ W( K, KW+1 ), LDW, CONE, W( 1, KW ), 1 )
00163 W( K, KW ) = DBLE( W( K, KW ) )
00164 END IF
00165
00166 KSTEP = 1
00167
00168
00169
00170
00171 ABSAKK = ABS( DBLE( W( K, KW ) ) )
00172
00173
00174
00175
00176 IF( K.GT.1 ) THEN
00177 IMAX = IZAMAX( K-1, W( 1, KW ), 1 )
00178 COLMAX = CABS1( W( IMAX, KW ) )
00179 ELSE
00180 COLMAX = ZERO
00181 END IF
00182
00183 IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
00184
00185
00186
00187 IF( INFO.EQ.0 )
00188 $ INFO = K
00189 KP = K
00190 A( K, K ) = DBLE( A( K, K ) )
00191 ELSE
00192 IF( ABSAKK.GE.ALPHA*COLMAX ) THEN
00193
00194
00195
00196 KP = K
00197 ELSE
00198
00199
00200
00201 CALL ZCOPY( IMAX-1, A( 1, IMAX ), 1, W( 1, KW-1 ), 1 )
00202 W( IMAX, KW-1 ) = DBLE( A( IMAX, IMAX ) )
00203 CALL ZCOPY( K-IMAX, A( IMAX, IMAX+1 ), LDA,
00204 $ W( IMAX+1, KW-1 ), 1 )
00205 CALL ZLACGV( K-IMAX, W( IMAX+1, KW-1 ), 1 )
00206 IF( K.LT.N ) THEN
00207 CALL ZGEMV( 'No transpose', K, N-K, -CONE,
00208 $ A( 1, K+1 ), LDA, W( IMAX, KW+1 ), LDW,
00209 $ CONE, W( 1, KW-1 ), 1 )
00210 W( IMAX, KW-1 ) = DBLE( W( IMAX, KW-1 ) )
00211 END IF
00212
00213
00214
00215
00216 JMAX = IMAX + IZAMAX( K-IMAX, W( IMAX+1, KW-1 ), 1 )
00217 ROWMAX = CABS1( W( JMAX, KW-1 ) )
00218 IF( IMAX.GT.1 ) THEN
00219 JMAX = IZAMAX( IMAX-1, W( 1, KW-1 ), 1 )
00220 ROWMAX = MAX( ROWMAX, CABS1( W( JMAX, KW-1 ) ) )
00221 END IF
00222
00223 IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN
00224
00225
00226
00227 KP = K
00228 ELSE IF( ABS( DBLE( W( IMAX, KW-1 ) ) ).GE.ALPHA*ROWMAX )
00229 $ THEN
00230
00231
00232
00233
00234 KP = IMAX
00235
00236
00237
00238 CALL ZCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 )
00239 ELSE
00240
00241
00242
00243
00244 KP = IMAX
00245 KSTEP = 2
00246 END IF
00247 END IF
00248
00249 KK = K - KSTEP + 1
00250 KKW = NB + KK - N
00251
00252
00253
00254 IF( KP.NE.KK ) THEN
00255
00256
00257
00258 A( KP, KP ) = DBLE( A( KK, KK ) )
00259 CALL ZCOPY( KK-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ),
00260 $ LDA )
00261 CALL ZLACGV( KK-1-KP, A( KP, KP+1 ), LDA )
00262 CALL ZCOPY( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 )
00263
00264
00265
00266 IF( KK.LT.N )
00267 $ CALL ZSWAP( N-KK, A( KK, KK+1 ), LDA, A( KP, KK+1 ),
00268 $ LDA )
00269 CALL ZSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ),
00270 $ LDW )
00271 END IF
00272
00273 IF( KSTEP.EQ.1 ) THEN
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 CALL ZCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 )
00284 R1 = ONE / DBLE( A( K, K ) )
00285 CALL ZDSCAL( K-1, R1, A( 1, K ), 1 )
00286
00287
00288
00289 CALL ZLACGV( K-1, W( 1, KW ), 1 )
00290 ELSE
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 IF( K.GT.2 ) THEN
00301
00302
00303
00304 D21 = W( K-1, KW )
00305 D11 = W( K, KW ) / DCONJG( D21 )
00306 D22 = W( K-1, KW-1 ) / D21
00307 T = ONE / ( DBLE( D11*D22 )-ONE )
00308 D21 = T / D21
00309 DO 20 J = 1, K - 2
00310 A( J, K-1 ) = D21*( D11*W( J, KW-1 )-W( J, KW ) )
00311 A( J, K ) = DCONJG( D21 )*
00312 $ ( D22*W( J, KW )-W( J, KW-1 ) )
00313 20 CONTINUE
00314 END IF
00315
00316
00317
00318 A( K-1, K-1 ) = W( K-1, KW-1 )
00319 A( K-1, K ) = W( K-1, KW )
00320 A( K, K ) = W( K, KW )
00321
00322
00323
00324 CALL ZLACGV( K-1, W( 1, KW ), 1 )
00325 CALL ZLACGV( K-2, W( 1, KW-1 ), 1 )
00326 END IF
00327 END IF
00328
00329
00330
00331 IF( KSTEP.EQ.1 ) THEN
00332 IPIV( K ) = KP
00333 ELSE
00334 IPIV( K ) = -KP
00335 IPIV( K-1 ) = -KP
00336 END IF
00337
00338
00339
00340 K = K - KSTEP
00341 GO TO 10
00342
00343 30 CONTINUE
00344
00345
00346
00347
00348
00349
00350
00351
00352 DO 50 J = ( ( K-1 ) / NB )*NB + 1, 1, -NB
00353 JB = MIN( NB, K-J+1 )
00354
00355
00356
00357 DO 40 JJ = J, J + JB - 1
00358 A( JJ, JJ ) = DBLE( A( JJ, JJ ) )
00359 CALL ZGEMV( 'No transpose', JJ-J+1, N-K, -CONE,
00360 $ A( J, K+1 ), LDA, W( JJ, KW+1 ), LDW, CONE,
00361 $ A( J, JJ ), 1 )
00362 A( JJ, JJ ) = DBLE( A( JJ, JJ ) )
00363 40 CONTINUE
00364
00365
00366
00367 CALL ZGEMM( 'No transpose', 'Transpose', J-1, JB, N-K,
00368 $ -CONE, A( 1, K+1 ), LDA, W( J, KW+1 ), LDW,
00369 $ CONE, A( 1, J ), LDA )
00370 50 CONTINUE
00371
00372
00373
00374
00375 J = K + 1
00376 60 CONTINUE
00377 JJ = J
00378 JP = IPIV( J )
00379 IF( JP.LT.0 ) THEN
00380 JP = -JP
00381 J = J + 1
00382 END IF
00383 J = J + 1
00384 IF( JP.NE.JJ .AND. J.LE.N )
00385 $ CALL ZSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA )
00386 IF( J.LE.N )
00387 $ GO TO 60
00388
00389
00390
00391 KB = N - K
00392
00393 ELSE
00394
00395
00396
00397
00398
00399
00400
00401 K = 1
00402 70 CONTINUE
00403
00404
00405
00406 IF( ( K.GE.NB .AND. NB.LT.N ) .OR. K.GT.N )
00407 $ GO TO 90
00408
00409
00410
00411 W( K, K ) = DBLE( A( K, K ) )
00412 IF( K.LT.N )
00413 $ CALL ZCOPY( N-K, A( K+1, K ), 1, W( K+1, K ), 1 )
00414 CALL ZGEMV( 'No transpose', N-K+1, K-1, -CONE, A( K, 1 ), LDA,
00415 $ W( K, 1 ), LDW, CONE, W( K, K ), 1 )
00416 W( K, K ) = DBLE( W( K, K ) )
00417
00418 KSTEP = 1
00419
00420
00421
00422
00423 ABSAKK = ABS( DBLE( W( K, K ) ) )
00424
00425
00426
00427
00428 IF( K.LT.N ) THEN
00429 IMAX = K + IZAMAX( N-K, W( K+1, K ), 1 )
00430 COLMAX = CABS1( W( IMAX, K ) )
00431 ELSE
00432 COLMAX = ZERO
00433 END IF
00434
00435 IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
00436
00437
00438
00439 IF( INFO.EQ.0 )
00440 $ INFO = K
00441 KP = K
00442 A( K, K ) = DBLE( A( K, K ) )
00443 ELSE
00444 IF( ABSAKK.GE.ALPHA*COLMAX ) THEN
00445
00446
00447
00448 KP = K
00449 ELSE
00450
00451
00452
00453 CALL ZCOPY( IMAX-K, A( IMAX, K ), LDA, W( K, K+1 ), 1 )
00454 CALL ZLACGV( IMAX-K, W( K, K+1 ), 1 )
00455 W( IMAX, K+1 ) = DBLE( A( IMAX, IMAX ) )
00456 IF( IMAX.LT.N )
00457 $ CALL ZCOPY( N-IMAX, A( IMAX+1, IMAX ), 1,
00458 $ W( IMAX+1, K+1 ), 1 )
00459 CALL ZGEMV( 'No transpose', N-K+1, K-1, -CONE, A( K, 1 ),
00460 $ LDA, W( IMAX, 1 ), LDW, CONE, W( K, K+1 ),
00461 $ 1 )
00462 W( IMAX, K+1 ) = DBLE( W( IMAX, K+1 ) )
00463
00464
00465
00466
00467 JMAX = K - 1 + IZAMAX( IMAX-K, W( K, K+1 ), 1 )
00468 ROWMAX = CABS1( W( JMAX, K+1 ) )
00469 IF( IMAX.LT.N ) THEN
00470 JMAX = IMAX + IZAMAX( N-IMAX, W( IMAX+1, K+1 ), 1 )
00471 ROWMAX = MAX( ROWMAX, CABS1( W( JMAX, K+1 ) ) )
00472 END IF
00473
00474 IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN
00475
00476
00477
00478 KP = K
00479 ELSE IF( ABS( DBLE( W( IMAX, K+1 ) ) ).GE.ALPHA*ROWMAX )
00480 $ THEN
00481
00482
00483
00484
00485 KP = IMAX
00486
00487
00488
00489 CALL ZCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 )
00490 ELSE
00491
00492
00493
00494
00495 KP = IMAX
00496 KSTEP = 2
00497 END IF
00498 END IF
00499
00500 KK = K + KSTEP - 1
00501
00502
00503
00504 IF( KP.NE.KK ) THEN
00505
00506
00507
00508 A( KP, KP ) = DBLE( A( KK, KK ) )
00509 CALL ZCOPY( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ),
00510 $ LDA )
00511 CALL ZLACGV( KP-KK-1, A( KP, KK+1 ), LDA )
00512 IF( KP.LT.N )
00513 $ CALL ZCOPY( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 )
00514
00515
00516
00517 CALL ZSWAP( KK-1, A( KK, 1 ), LDA, A( KP, 1 ), LDA )
00518 CALL ZSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW )
00519 END IF
00520
00521 IF( KSTEP.EQ.1 ) THEN
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 CALL ZCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 )
00532 IF( K.LT.N ) THEN
00533 R1 = ONE / DBLE( A( K, K ) )
00534 CALL ZDSCAL( N-K, R1, A( K+1, K ), 1 )
00535
00536
00537
00538 CALL ZLACGV( N-K, W( K+1, K ), 1 )
00539 END IF
00540 ELSE
00541
00542
00543
00544
00545
00546
00547
00548
00549 IF( K.LT.N-1 ) THEN
00550
00551
00552
00553 D21 = W( K+1, K )
00554 D11 = W( K+1, K+1 ) / D21
00555 D22 = W( K, K ) / DCONJG( D21 )
00556 T = ONE / ( DBLE( D11*D22 )-ONE )
00557 D21 = T / D21
00558 DO 80 J = K + 2, N
00559 A( J, K ) = DCONJG( D21 )*
00560 $ ( D11*W( J, K )-W( J, K+1 ) )
00561 A( J, K+1 ) = D21*( D22*W( J, K+1 )-W( J, K ) )
00562 80 CONTINUE
00563 END IF
00564
00565
00566
00567 A( K, K ) = W( K, K )
00568 A( K+1, K ) = W( K+1, K )
00569 A( K+1, K+1 ) = W( K+1, K+1 )
00570
00571
00572
00573 CALL ZLACGV( N-K, W( K+1, K ), 1 )
00574 CALL ZLACGV( N-K-1, W( K+2, K+1 ), 1 )
00575 END IF
00576 END IF
00577
00578
00579
00580 IF( KSTEP.EQ.1 ) THEN
00581 IPIV( K ) = KP
00582 ELSE
00583 IPIV( K ) = -KP
00584 IPIV( K+1 ) = -KP
00585 END IF
00586
00587
00588
00589 K = K + KSTEP
00590 GO TO 70
00591
00592 90 CONTINUE
00593
00594
00595
00596
00597
00598
00599
00600
00601 DO 110 J = K, N, NB
00602 JB = MIN( NB, N-J+1 )
00603
00604
00605
00606 DO 100 JJ = J, J + JB - 1
00607 A( JJ, JJ ) = DBLE( A( JJ, JJ ) )
00608 CALL ZGEMV( 'No transpose', J+JB-JJ, K-1, -CONE,
00609 $ A( JJ, 1 ), LDA, W( JJ, 1 ), LDW, CONE,
00610 $ A( JJ, JJ ), 1 )
00611 A( JJ, JJ ) = DBLE( A( JJ, JJ ) )
00612 100 CONTINUE
00613
00614
00615
00616 IF( J+JB.LE.N )
00617 $ CALL ZGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB,
00618 $ K-1, -CONE, A( J+JB, 1 ), LDA, W( J, 1 ),
00619 $ LDW, CONE, A( J+JB, J ), LDA )
00620 110 CONTINUE
00621
00622
00623
00624
00625 J = K - 1
00626 120 CONTINUE
00627 JJ = J
00628 JP = IPIV( J )
00629 IF( JP.LT.0 ) THEN
00630 JP = -JP
00631 J = J - 1
00632 END IF
00633 J = J - 1
00634 IF( JP.NE.JJ .AND. J.GE.1 )
00635 $ CALL ZSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA )
00636 IF( J.GE.1 )
00637 $ GO TO 120
00638
00639
00640
00641 KB = K - 1
00642
00643 END IF
00644 RETURN
00645
00646
00647
00648 END