262 SUBROUTINE dlaqr5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS,
263 $ SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,
264 $ LDU, NV, WV, LDWV, NH, WH, LDWH )
272 INTEGER IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
273 $ LDWH, LDWV, LDZ, N, NH, NSHFTS, NV
277 DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), U( LDU, * ),
278 $ V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ),
284 DOUBLE PRECISION ZERO, ONE
285 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
288 DOUBLE PRECISION ALPHA, BETA, H11, H12, H21, H22, REFSUM,
289 $ SAFMAX, SAFMIN, SCL, SMLNUM, SWAP, TST1, TST2,
291 INTEGER I, I2, I4, INCOL, J, JBOT, JCOL, JLEN,
292 $ JROW, JTOP, K, K1, KDU, KMS, KRCOL,
293 $ m, m22, mbot, mtop, nbmps, ndcol,
298 DOUBLE PRECISION DLAMCH
303 INTRINSIC abs, dble, max, min, mod
306 DOUBLE PRECISION VT( 3 )
330 DO 10 i = 1, nshfts - 2, 2
331 IF( si( i ).NE.-si( i+1 ) )
THEN
335 sr( i+1 ) = sr( i+2 )
340 si( i+1 ) = si( i+2 )
350 ns = nshfts - mod( nshfts, 2 )
354 safmin = dlamch(
'SAFE MINIMUM' )
355 safmax = one / safmin
356 CALL dlabad( safmin, safmax )
357 ulp = dlamch(
'PRECISION' )
358 smlnum = safmin*( dble( n ) / ulp )
363 accum = ( kacc22.EQ.1 ) .OR. ( kacc22.EQ.2 )
368 $ h( ktop+2, ktop ) = zero
380 DO 180 incol = ktop - 2*nbmps + 1, kbot - 2, 2*nbmps
385 jtop = max( ktop, incol )
386 ELSE IF( wantt )
THEN
394 $
CALL dlaset(
'ALL', kdu, kdu, zero, one, u, ldu )
408 DO 145 krcol = incol, min( incol+2*nbmps-1, kbot-2 )
417 mtop = max( 1, ( ktop-krcol ) / 2+1 )
418 mbot = min( nbmps, ( kbot-krcol-1 ) / 2 )
420 bmp22 = ( mbot.LT.nbmps ) .AND. ( krcol+2*( m22-1 ) ).EQ.
431 k = krcol + 2*( m22-1 )
432 IF( k.EQ.ktop-1 )
THEN
433 CALL dlaqr1( 2, h( k+1, k+1 ), ldh, sr( 2*m22-1 ),
434 $ si( 2*m22-1 ), sr( 2*m22 ), si( 2*m22 ),
437 CALL dlarfg( 2, beta, v( 2, m22 ), 1, v( 1, m22 ) )
440 v( 2, m22 ) = h( k+2, k )
441 CALL dlarfg( 2, beta, v( 2, m22 ), 1, v( 1, m22 ) )
450 DO 30 j = jtop, min( kbot, k+3 )
451 refsum = v( 1, m22 )*( h( j, k+1 )+v( 2, m22 )*
453 h( j, k+1 ) = h( j, k+1 ) - refsum
454 h( j, k+2 ) = h( j, k+2 ) - refsum*v( 2, m22 )
461 jbot = min( ndcol, kbot )
462 ELSE IF( wantt )
THEN
468 refsum = v( 1, m22 )*( h( k+1, j )+v( 2, m22 )*
470 h( k+1, j ) = h( k+1, j ) - refsum
471 h( k+2, j ) = h( k+2, j ) - refsum*v( 2, m22 )
484 IF( h( k+1, k ).NE.zero )
THEN
485 tst1 = abs( h( k, k ) ) + abs( h( k+1, k+1 ) )
486 IF( tst1.EQ.zero )
THEN
488 $ tst1 = tst1 + abs( h( k, k-1 ) )
490 $ tst1 = tst1 + abs( h( k, k-2 ) )
492 $ tst1 = tst1 + abs( h( k, k-3 ) )
494 $ tst1 = tst1 + abs( h( k+2, k+1 ) )
496 $ tst1 = tst1 + abs( h( k+3, k+1 ) )
498 $ tst1 = tst1 + abs( h( k+4, k+1 ) )
500 IF( abs( h( k+1, k ) )
501 $ .LE.max( smlnum, ulp*tst1 ) )
THEN
502 h12 = max( abs( h( k+1, k ) ),
503 $ abs( h( k, k+1 ) ) )
504 h21 = min( abs( h( k+1, k ) ),
505 $ abs( h( k, k+1 ) ) )
506 h11 = max( abs( h( k+1, k+1 ) ),
507 $ abs( h( k, k )-h( k+1, k+1 ) ) )
508 h22 = min( abs( h( k+1, k+1 ) ),
509 $ abs( h( k, k )-h( k+1, k+1 ) ) )
511 tst2 = h22*( h11 / scl )
513 IF( tst2.EQ.zero .OR. h21*( h12 / scl ).LE.
514 $ max( smlnum, ulp*tst2 ) )
THEN
525 DO 50 j = max( 1, ktop-incol ), kdu
526 refsum = v( 1, m22 )*( u( j, kms+1 )+
527 $ v( 2, m22 )*u( j, kms+2 ) )
528 u( j, kms+1 ) = u( j, kms+1 ) - refsum
529 u( j, kms+2 ) = u( j, kms+2 ) - refsum*v( 2, m22 )
531 ELSE IF( wantz )
THEN
533 refsum = v( 1, m22 )*( z( j, k+1 )+v( 2, m22 )*
535 z( j, k+1 ) = z( j, k+1 ) - refsum
536 z( j, k+2 ) = z( j, k+2 ) - refsum*v( 2, m22 )
543 DO 80 m = mbot, mtop, -1
544 k = krcol + 2*( m-1 )
545 IF( k.EQ.ktop-1 )
THEN
546 CALL dlaqr1( 3, h( ktop, ktop ), ldh, sr( 2*m-1 ),
547 $ si( 2*m-1 ), sr( 2*m ), si( 2*m ),
550 CALL dlarfg( 3, alpha, v( 2, m ), 1, v( 1, m ) )
557 refsum = v( 1, m )*v( 3, m )*h( k+3, k+2 )
558 h( k+3, k ) = -refsum
559 h( k+3, k+1 ) = -refsum*v( 2, m )
560 h( k+3, k+2 ) = h( k+3, k+2 ) - refsum*v( 3, m )
566 v( 2, m ) = h( k+2, k )
567 v( 3, m ) = h( k+3, k )
568 CALL dlarfg( 3, beta, v( 2, m ), 1, v( 1, m ) )
575 IF( h( k+3, k ).NE.zero .OR. h( k+3, k+1 ).NE.
576 $ zero .OR. h( k+3, k+2 ).EQ.zero )
THEN
591 CALL dlaqr1( 3, h( k+1, k+1 ), ldh, sr( 2*m-1 ),
592 $ si( 2*m-1 ), sr( 2*m ), si( 2*m ),
595 CALL dlarfg( 3, alpha, vt( 2 ), 1, vt( 1 ) )
596 refsum = vt( 1 )*( h( k+1, k )+vt( 2 )*
599 IF( abs( h( k+2, k )-refsum*vt( 2 ) )+
600 $ abs( refsum*vt( 3 ) ).GT.ulp*
601 $ ( abs( h( k, k ) )+abs( h( k+1,
602 $ k+1 ) )+abs( h( k+2, k+2 ) ) ) )
THEN
618 h( k+1, k ) = h( k+1, k ) - refsum
634 DO 70 j = jtop, min( kbot, k+3 )
635 refsum = v( 1, m )*( h( j, k+1 )+v( 2, m )*
636 $ h( j, k+2 )+v( 3, m )*h( j, k+3 ) )
637 h( j, k+1 ) = h( j, k+1 ) - refsum
638 h( j, k+2 ) = h( j, k+2 ) - refsum*v( 2, m )
639 h( j, k+3 ) = h( j, k+3 ) - refsum*v( 3, m )
645 refsum = v( 1, m )*( h( k+1, k+1 )+v( 2, m )*
646 $ h( k+2, k+1 )+v( 3, m )*h( k+3, k+1 ) )
647 h( k+1, k+1 ) = h( k+1, k+1 ) - refsum
648 h( k+2, k+1 ) = h( k+2, k+1 ) - refsum*v( 2, m )
649 h( k+3, k+1 ) = h( k+3, k+1 ) - refsum*v( 3, m )
662 IF( h( k+1, k ).NE.zero )
THEN
663 tst1 = abs( h( k, k ) ) + abs( h( k+1, k+1 ) )
664 IF( tst1.EQ.zero )
THEN
666 $ tst1 = tst1 + abs( h( k, k-1 ) )
668 $ tst1 = tst1 + abs( h( k, k-2 ) )
670 $ tst1 = tst1 + abs( h( k, k-3 ) )
672 $ tst1 = tst1 + abs( h( k+2, k+1 ) )
674 $ tst1 = tst1 + abs( h( k+3, k+1 ) )
676 $ tst1 = tst1 + abs( h( k+4, k+1 ) )
678 IF( abs( h( k+1, k ) ).LE.max( smlnum, ulp*tst1 ) )
680 h12 = max( abs( h( k+1, k ) ), abs( h( k, k+1 ) ) )
681 h21 = min( abs( h( k+1, k ) ), abs( h( k, k+1 ) ) )
682 h11 = max( abs( h( k+1, k+1 ) ),
683 $ abs( h( k, k )-h( k+1, k+1 ) ) )
684 h22 = min( abs( h( k+1, k+1 ) ),
685 $ abs( h( k, k )-h( k+1, k+1 ) ) )
687 tst2 = h22*( h11 / scl )
689 IF( tst2.EQ.zero .OR. h21*( h12 / scl ).LE.
690 $ max( smlnum, ulp*tst2 ) )
THEN
700 jbot = min( ndcol, kbot )
701 ELSE IF( wantt )
THEN
707 DO 100 m = mbot, mtop, -1
708 k = krcol + 2*( m-1 )
709 DO 90 j = max( ktop, krcol + 2*m ), jbot
710 refsum = v( 1, m )*( h( k+1, j )+v( 2, m )*
711 $ h( k+2, j )+v( 3, m )*h( k+3, j ) )
712 h( k+1, j ) = h( k+1, j ) - refsum
713 h( k+2, j ) = h( k+2, j ) - refsum*v( 2, m )
714 h( k+3, j ) = h( k+3, j ) - refsum*v( 3, m )
726 DO 120 m = mbot, mtop, -1
727 k = krcol + 2*( m-1 )
729 i2 = max( 1, ktop-incol )
730 i2 = max( i2, kms-(krcol-incol)+1 )
731 i4 = min( kdu, krcol + 2*( mbot-1 ) - incol + 5 )
733 refsum = v( 1, m )*( u( j, kms+1 )+v( 2, m )*
734 $ u( j, kms+2 )+v( 3, m )*u( j, kms+3 ) )
735 u( j, kms+1 ) = u( j, kms+1 ) - refsum
736 u( j, kms+2 ) = u( j, kms+2 ) - refsum*v( 2, m )
737 u( j, kms+3 ) = u( j, kms+3 ) - refsum*v( 3, m )
740 ELSE IF( wantz )
THEN
746 DO 140 m = mbot, mtop, -1
747 k = krcol + 2*( m-1 )
748 DO 130 j = iloz, ihiz
749 refsum = v( 1, m )*( z( j, k+1 )+v( 2, m )*
750 $ z( j, k+2 )+v( 3, m )*z( j, k+3 ) )
751 z( j, k+1 ) = z( j, k+1 ) - refsum
752 z( j, k+2 ) = z( j, k+2 ) - refsum*v( 2, m )
753 z( j, k+3 ) = z( j, k+3 ) - refsum*v( 3, m )
774 k1 = max( 1, ktop-incol )
775 nu = ( kdu-max( 0, ndcol-kbot ) ) - k1 + 1
779 DO 150 jcol = min( ndcol, kbot ) + 1, jbot, nh
780 jlen = min( nh, jbot-jcol+1 )
781 CALL dgemm(
'C',
'N', nu, jlen, nu, one, u( k1, k1 ),
782 $ ldu, h( incol+k1, jcol ), ldh, zero, wh,
784 CALL dlacpy(
'ALL', nu, jlen, wh, ldwh,
785 $ h( incol+k1, jcol ), ldh )
790 DO 160 jrow = jtop, max( ktop, incol ) - 1, nv
791 jlen = min( nv, max( ktop, incol )-jrow )
792 CALL dgemm(
'N',
'N', jlen, nu, nu, one,
793 $ h( jrow, incol+k1 ), ldh, u( k1, k1 ),
794 $ ldu, zero, wv, ldwv )
795 CALL dlacpy(
'ALL', jlen, nu, wv, ldwv,
796 $ h( jrow, incol+k1 ), ldh )
802 DO 170 jrow = iloz, ihiz, nv
803 jlen = min( nv, ihiz-jrow+1 )
804 CALL dgemm(
'N',
'N', jlen, nu, nu, one,
805 $ z( jrow, incol+k1 ), ldz, u( k1, k1 ),
806 $ ldu, zero, wv, ldwv )
807 CALL dlacpy(
'ALL', jlen, nu, wv, ldwv,
808 $ z( jrow, incol+k1 ), ldz )
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dtrmm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
DTRMM
subroutine dlaqr5(WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS, SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, LDU, NV, WV, LDWV, NH, WH, LDWH)
DLAQR5 performs a single small-bulge multi-shift QR sweep.
subroutine dlaqr1(N, H, LDH, SR1, SI1, SR2, SI2, V)
DLAQR1 sets a scalar multiple of the first column of the product of 2-by-2 or 3-by-3 matrix H and spe...
subroutine dlarfg(N, ALPHA, X, INCX, TAU)
DLARFG generates an elementary reflector (Householder matrix).