256 SUBROUTINE dlaqr5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS,
257 $ SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,
258 $ LDU, NV, WV, LDWV, NH, WH, LDWH )
266 INTEGER IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
267 $ ldwh, ldwv, ldz, n, nh, nshfts, nv
271 DOUBLE PRECISION H( ldh, * ), SI( * ), SR( * ), U( ldu, * ),
272 $ v( ldv, * ), wh( ldwh, * ), wv( ldwv, * ),
278 DOUBLE PRECISION ZERO, ONE
279 parameter( zero = 0.0d0, one = 1.0d0 )
282 DOUBLE PRECISION ALPHA, BETA, H11, H12, H21, H22, REFSUM,
283 $ safmax, safmin, scl, smlnum, swap, tst1, tst2,
285 INTEGER I, I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN,
286 $ jrow, jtop, k, k1, kdu, kms, knz, krcol, kzs,
287 $ m, m22, mbot, mend, mstart, mtop, nbmps, ndcol,
289 LOGICAL ACCUM, BLK22, BMP22
292 DOUBLE PRECISION DLAMCH
297 INTRINSIC abs, dble, max, min, mod
300 DOUBLE PRECISION VT( 3 )
324 DO 10 i = 1, nshfts - 2, 2
325 IF( si( i ).NE.-si( i+1 ) )
THEN 329 sr( i+1 ) = sr( i+2 )
334 si( i+1 ) = si( i+2 )
344 ns = nshfts - mod( nshfts, 2 )
348 safmin = dlamch(
'SAFE MINIMUM' )
349 safmax = one / safmin
350 CALL dlabad( safmin, safmax )
351 ulp = dlamch(
'PRECISION' )
352 smlnum = safmin*( dble( n ) / ulp )
357 accum = ( kacc22.EQ.1 ) .OR. ( kacc22.EQ.2 )
361 blk22 = ( ns.GT.2 ) .AND. ( kacc22.EQ.2 )
366 $ h( ktop+2, ktop ) = zero
378 DO 220 incol = 3*( 1-nbmps ) + ktop - 1, kbot - 2, 3*nbmps - 2
381 $
CALL dlaset(
'ALL', kdu, kdu, zero, one, u, ldu )
395 DO 150 krcol = incol, min( incol+3*nbmps-3, kbot-2 )
404 mtop = max( 1, ( ( ktop-1 )-krcol+2 ) / 3+1 )
405 mbot = min( nbmps, ( kbot-krcol ) / 3 )
407 bmp22 = ( mbot.LT.nbmps ) .AND. ( krcol+3*( m22-1 ) ).EQ.
414 k = krcol + 3*( m-1 )
415 IF( k.EQ.ktop-1 )
THEN 416 CALL dlaqr1( 3, h( ktop, ktop ), ldh, sr( 2*m-1 ),
417 $ si( 2*m-1 ), sr( 2*m ), si( 2*m ),
420 CALL dlarfg( 3, alpha, v( 2, m ), 1, v( 1, m ) )
423 v( 2, m ) = h( k+2, k )
424 v( 3, m ) = h( k+3, k )
425 CALL dlarfg( 3, beta, v( 2, m ), 1, v( 1, m ) )
432 IF( h( k+3, k ).NE.zero .OR. h( k+3, k+1 ).NE.
433 $ zero .OR. h( k+3, k+2 ).EQ.zero )
THEN 448 CALL dlaqr1( 3, h( k+1, k+1 ), ldh, sr( 2*m-1 ),
449 $ si( 2*m-1 ), sr( 2*m ), si( 2*m ),
452 CALL dlarfg( 3, alpha, vt( 2 ), 1, vt( 1 ) )
453 refsum = vt( 1 )*( h( k+1, k )+vt( 2 )*
456 IF( abs( h( k+2, k )-refsum*vt( 2 ) )+
457 $ abs( refsum*vt( 3 ) ).GT.ulp*
458 $ ( abs( h( k, k ) )+abs( h( k+1,
459 $ k+1 ) )+abs( h( k+2, k+2 ) ) ) )
THEN 475 h( k+1, k ) = h( k+1, k ) - refsum
488 k = krcol + 3*( m22-1 )
490 IF( k.EQ.ktop-1 )
THEN 491 CALL dlaqr1( 2, h( k+1, k+1 ), ldh, sr( 2*m22-1 ),
492 $ si( 2*m22-1 ), sr( 2*m22 ), si( 2*m22 ),
495 CALL dlarfg( 2, beta, v( 2, m22 ), 1, v( 1, m22 ) )
498 v( 2, m22 ) = h( k+2, k )
499 CALL dlarfg( 2, beta, v( 2, m22 ), 1, v( 1, m22 ) )
508 jbot = min( ndcol, kbot )
509 ELSE IF( wantt )
THEN 514 DO 40 j = max( ktop, krcol ), jbot
515 mend = min( mbot, ( j-krcol+2 ) / 3 )
517 k = krcol + 3*( m-1 )
518 refsum = v( 1, m )*( h( k+1, j )+v( 2, m )*
519 $ h( k+2, j )+v( 3, m )*h( k+3, j ) )
520 h( k+1, j ) = h( k+1, j ) - refsum
521 h( k+2, j ) = h( k+2, j ) - refsum*v( 2, m )
522 h( k+3, j ) = h( k+3, j ) - refsum*v( 3, m )
526 k = krcol + 3*( m22-1 )
527 DO 50 j = max( k+1, ktop ), jbot
528 refsum = v( 1, m22 )*( h( k+1, j )+v( 2, m22 )*
530 h( k+1, j ) = h( k+1, j ) - refsum
531 h( k+2, j ) = h( k+2, j ) - refsum*v( 2, m22 )
540 jtop = max( ktop, incol )
541 ELSE IF( wantt )
THEN 547 IF( v( 1, m ).NE.zero )
THEN 548 k = krcol + 3*( m-1 )
549 DO 60 j = jtop, min( kbot, k+3 )
550 refsum = v( 1, m )*( h( j, k+1 )+v( 2, m )*
551 $ h( j, k+2 )+v( 3, m )*h( j, k+3 ) )
552 h( j, k+1 ) = h( j, k+1 ) - refsum
553 h( j, k+2 ) = h( j, k+2 ) - refsum*v( 2, m )
554 h( j, k+3 ) = h( j, k+3 ) - refsum*v( 3, m )
564 DO 70 j = max( 1, ktop-incol ), kdu
565 refsum = v( 1, m )*( u( j, kms+1 )+v( 2, m )*
566 $ u( j, kms+2 )+v( 3, m )*u( j, kms+3 ) )
567 u( j, kms+1 ) = u( j, kms+1 ) - refsum
568 u( j, kms+2 ) = u( j, kms+2 ) - refsum*v( 2, m )
569 u( j, kms+3 ) = u( j, kms+3 ) - refsum*v( 3, m )
571 ELSE IF( wantz )
THEN 578 refsum = v( 1, m )*( z( j, k+1 )+v( 2, m )*
579 $ z( j, k+2 )+v( 3, m )*z( j, k+3 ) )
580 z( j, k+1 ) = z( j, k+1 ) - refsum
581 z( j, k+2 ) = z( j, k+2 ) - refsum*v( 2, m )
582 z( j, k+3 ) = z( j, k+3 ) - refsum*v( 3, m )
590 k = krcol + 3*( m22-1 )
592 IF ( v( 1, m22 ).NE.zero )
THEN 593 DO 100 j = jtop, min( kbot, k+3 )
594 refsum = v( 1, m22 )*( h( j, k+1 )+v( 2, m22 )*
596 h( j, k+1 ) = h( j, k+1 ) - refsum
597 h( j, k+2 ) = h( j, k+2 ) - refsum*v( 2, m22 )
602 DO 110 j = max( 1, ktop-incol ), kdu
603 refsum = v( 1, m22 )*( u( j, kms+1 )+
604 $ v( 2, m22 )*u( j, kms+2 ) )
605 u( j, kms+1 ) = u( j, kms+1 ) - refsum
606 u( j, kms+2 ) = u( j, kms+2 ) -
609 ELSE IF( wantz )
THEN 610 DO 120 j = iloz, ihiz
611 refsum = v( 1, m22 )*( z( j, k+1 )+v( 2, m22 )*
613 z( j, k+1 ) = z( j, k+1 ) - refsum
614 z( j, k+2 ) = z( j, k+2 ) - refsum*v( 2, m22 )
623 IF( krcol+3*( mstart-1 ).LT.ktop )
624 $ mstart = mstart + 1
628 IF( krcol.EQ.kbot-2 )
630 DO 130 m = mstart, mend
631 k = min( kbot-1, krcol+3*( m-1 ) )
642 IF( h( k+1, k ).NE.zero )
THEN 643 tst1 = abs( h( k, k ) ) + abs( h( k+1, k+1 ) )
644 IF( tst1.EQ.zero )
THEN 646 $ tst1 = tst1 + abs( h( k, k-1 ) )
648 $ tst1 = tst1 + abs( h( k, k-2 ) )
650 $ tst1 = tst1 + abs( h( k, k-3 ) )
652 $ tst1 = tst1 + abs( h( k+2, k+1 ) )
654 $ tst1 = tst1 + abs( h( k+3, k+1 ) )
656 $ tst1 = tst1 + abs( h( k+4, k+1 ) )
658 IF( abs( h( k+1, k ) ).LE.max( smlnum, ulp*tst1 ) )
660 h12 = max( abs( h( k+1, k ) ), abs( h( k, k+1 ) ) )
661 h21 = min( abs( h( k+1, k ) ), abs( h( k, k+1 ) ) )
662 h11 = max( abs( h( k+1, k+1 ) ),
663 $ abs( h( k, k )-h( k+1, k+1 ) ) )
664 h22 = min( abs( h( k+1, k+1 ) ),
665 $ abs( h( k, k )-h( k+1, k+1 ) ) )
667 tst2 = h22*( h11 / scl )
669 IF( tst2.EQ.zero .OR. h21*( h12 / scl ).LE.
670 $ max( smlnum, ulp*tst2 ) )h( k+1, k ) = zero
677 mend = min( nbmps, ( kbot-krcol-1 ) / 3 )
678 DO 140 m = mtop, mend
679 k = krcol + 3*( m-1 )
680 refsum = v( 1, m )*v( 3, m )*h( k+4, k+3 )
681 h( k+4, k+1 ) = -refsum
682 h( k+4, k+2 ) = -refsum*v( 2, m )
683 h( k+4, k+3 ) = h( k+4, k+3 ) - refsum*v( 3, m )
702 IF( ( .NOT.blk22 ) .OR. ( incol.LT.ktop ) .OR.
703 $ ( ndcol.GT.kbot ) .OR. ( ns.LE.2 ) )
THEN 714 k1 = max( 1, ktop-incol )
715 nu = ( kdu-max( 0, ndcol-kbot ) ) - k1 + 1
719 DO 160 jcol = min( ndcol, kbot ) + 1, jbot, nh
720 jlen = min( nh, jbot-jcol+1 )
721 CALL dgemm(
'C',
'N', nu, jlen, nu, one, u( k1, k1 ),
722 $ ldu, h( incol+k1, jcol ), ldh, zero, wh,
724 CALL dlacpy(
'ALL', nu, jlen, wh, ldwh,
725 $ h( incol+k1, jcol ), ldh )
730 DO 170 jrow = jtop, max( ktop, incol ) - 1, nv
731 jlen = min( nv, max( ktop, incol )-jrow )
732 CALL dgemm(
'N',
'N', jlen, nu, nu, one,
733 $ h( jrow, incol+k1 ), ldh, u( k1, k1 ),
734 $ ldu, zero, wv, ldwv )
735 CALL dlacpy(
'ALL', jlen, nu, wv, ldwv,
736 $ h( jrow, incol+k1 ), ldh )
742 DO 180 jrow = iloz, ihiz, nv
743 jlen = min( nv, ihiz-jrow+1 )
744 CALL dgemm(
'N',
'N', jlen, nu, nu, one,
745 $ z( jrow, incol+k1 ), ldz, u( k1, k1 ),
746 $ ldu, zero, wv, ldwv )
747 CALL dlacpy(
'ALL', jlen, nu, wv, ldwv,
748 $ z( jrow, incol+k1 ), ldz )
766 kzs = ( j4-j2 ) - ( ns+1 )
771 DO 190 jcol = min( ndcol, kbot ) + 1, jbot, nh
772 jlen = min( nh, jbot-jcol+1 )
777 CALL dlacpy(
'ALL', knz, jlen, h( incol+1+j2, jcol ),
778 $ ldh, wh( kzs+1, 1 ), ldwh )
782 CALL dlaset(
'ALL', kzs, jlen, zero, zero, wh, ldwh )
783 CALL dtrmm(
'L',
'U',
'C',
'N', knz, jlen, one,
784 $ u( j2+1, 1+kzs ), ldu, wh( kzs+1, 1 ),
789 CALL dgemm(
'C',
'N', i2, jlen, j2, one, u, ldu,
790 $ h( incol+1, jcol ), ldh, one, wh, ldwh )
794 CALL dlacpy(
'ALL', j2, jlen, h( incol+1, jcol ), ldh,
795 $ wh( i2+1, 1 ), ldwh )
799 CALL dtrmm(
'L',
'L',
'C',
'N', j2, jlen, one,
800 $ u( 1, i2+1 ), ldu, wh( i2+1, 1 ), ldwh )
804 CALL dgemm(
'C',
'N', i4-i2, jlen, j4-j2, one,
805 $ u( j2+1, i2+1 ), ldu,
806 $ h( incol+1+j2, jcol ), ldh, one,
807 $ wh( i2+1, 1 ), ldwh )
811 CALL dlacpy(
'ALL', kdu, jlen, wh, ldwh,
812 $ h( incol+1, jcol ), ldh )
817 DO 200 jrow = jtop, max( incol, ktop ) - 1, nv
818 jlen = min( nv, max( incol, ktop )-jrow )
823 CALL dlacpy(
'ALL', jlen, knz, h( jrow, incol+1+j2 ),
824 $ ldh, wv( 1, 1+kzs ), ldwv )
828 CALL dlaset(
'ALL', jlen, kzs, zero, zero, wv, ldwv )
829 CALL dtrmm(
'R',
'U',
'N',
'N', jlen, knz, one,
830 $ u( j2+1, 1+kzs ), ldu, wv( 1, 1+kzs ),
835 CALL dgemm(
'N',
'N', jlen, i2, j2, one,
836 $ h( jrow, incol+1 ), ldh, u, ldu, one, wv,
841 CALL dlacpy(
'ALL', jlen, j2, h( jrow, incol+1 ), ldh,
842 $ wv( 1, 1+i2 ), ldwv )
846 CALL dtrmm(
'R',
'L',
'N',
'N', jlen, i4-i2, one,
847 $ u( 1, i2+1 ), ldu, wv( 1, 1+i2 ), ldwv )
851 CALL dgemm(
'N',
'N', jlen, i4-i2, j4-j2, one,
852 $ h( jrow, incol+1+j2 ), ldh,
853 $ u( j2+1, i2+1 ), ldu, one, wv( 1, 1+i2 ),
858 CALL dlacpy(
'ALL', jlen, kdu, wv, ldwv,
859 $ h( jrow, incol+1 ), ldh )
865 DO 210 jrow = iloz, ihiz, nv
866 jlen = min( nv, ihiz-jrow+1 )
871 CALL dlacpy(
'ALL', jlen, knz,
872 $ z( jrow, incol+1+j2 ), ldz,
873 $ wv( 1, 1+kzs ), ldwv )
877 CALL dlaset(
'ALL', jlen, kzs, zero, zero, wv,
879 CALL dtrmm(
'R',
'U',
'N',
'N', jlen, knz, one,
880 $ u( j2+1, 1+kzs ), ldu, wv( 1, 1+kzs ),
885 CALL dgemm(
'N',
'N', jlen, i2, j2, one,
886 $ z( jrow, incol+1 ), ldz, u, ldu, one,
891 CALL dlacpy(
'ALL', jlen, j2, z( jrow, incol+1 ),
892 $ ldz, wv( 1, 1+i2 ), ldwv )
896 CALL dtrmm(
'R',
'L',
'N',
'N', jlen, i4-i2, one,
897 $ u( 1, i2+1 ), ldu, wv( 1, 1+i2 ),
902 CALL dgemm(
'N',
'N', jlen, i4-i2, j4-j2, one,
903 $ z( jrow, incol+1+j2 ), ldz,
904 $ u( j2+1, i2+1 ), ldu, one,
905 $ wv( 1, 1+i2 ), ldwv )
909 CALL dlacpy(
'ALL', jlen, kdu, wv, ldwv,
910 $ z( jrow, incol+1 ), ldz )
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dtrmm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
DTRMM
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 dlabad(SMALL, LARGE)
DLABAD
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 dlarfg(N, ALPHA, X, INCX, TAU)
DLARFG generates an elementary reflector (Householder matrix).
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...