226 SUBROUTINE dgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB,
228 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
237 CHARACTER COMPQ, COMPZ
238 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
241 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
242 $ Z( LDZ, * ), WORK( * )
248 DOUBLE PRECISION ZERO, ONE
249 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
252 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
253 CHARACTER*1 COMPQ2, COMPZ2
254 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
255 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
256 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
257 DOUBLE PRECISION C, C1, C2, S, S1, S2, TEMP, TEMP1, TEMP2, TEMP3
262 EXTERNAL ilaenv, lsame
277 nb = ilaenv( 1,
'DGGHD3',
' ', n, ilo, ihi, -1 )
284 work( 1 ) = dble( lwkopt )
285 initq = lsame( compq,
'I' )
286 wantq = initq .OR. lsame( compq,
'V' )
287 initz = lsame( compz,
'I' )
288 wantz = initz .OR. lsame( compz,
'V' )
289 lquery = ( lwork.EQ.-1 )
291 IF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
293 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
295 ELSE IF( n.LT.0 )
THEN
297 ELSE IF( ilo.LT.1 )
THEN
299 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
301 ELSE IF( lda.LT.max( 1, n ) )
THEN
303 ELSE IF( ldb.LT.max( 1, n ) )
THEN
305 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 )
THEN
307 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 )
THEN
309 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
313 CALL xerbla(
'DGGHD3', -info )
315 ELSE IF( lquery )
THEN
322 $
CALL dlaset(
'All', n, n, zero, one, q, ldq )
324 $
CALL dlaset(
'All', n, n, zero, one, z, ldz )
329 $
CALL dlaset(
'Lower', n-1, n-1, zero, zero, b(2, 1), ldb )
340 nbmin = ilaenv( 2,
'DGGHD3',
' ', n, ilo, ihi, -1 )
341 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
345 nx = max( nb, ilaenv( 3,
'DGGHD3',
' ', n, ilo, ihi, -1 ) )
350 IF( lwork.LT.lwkopt )
THEN
356 nbmin = max( 2, ilaenv( 2,
'DGGHD3',
' ', n, ilo, ihi,
358 IF( lwork.GE.6*n*nbmin )
THEN
367 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
377 kacc22 = ilaenv( 16,
'DGGHD3',
' ', n, ilo, ihi, -1 )
379 DO jcol = ilo, ihi-2, nb
380 nnb = min( nb, ihi-jcol-1 )
388 n2nb = ( ihi-jcol-1 ) / nnb - 1
389 nblst = ihi - jcol - n2nb*nnb
390 CALL dlaset(
'All', nblst, nblst, zero, one, work,
392 pw = nblst * nblst + 1
394 CALL dlaset(
'All', 2*nnb, 2*nnb, zero, one,
395 $ work( pw ), 2*nnb )
401 DO j = jcol, jcol+nnb-1
408 CALL dlartg( temp, a( i, j ), c, s, a( i-1, j ) )
415 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
417 jrow = j + n2nb*nnb + 2
421 DO jj = ppw, ppw+len-1
422 temp = work( jj + nblst )
423 work( jj + nblst ) = c*temp - s*work( jj )
424 work( jj ) = s*temp + c*work( jj )
427 ppw = ppw - nblst - 1
430 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
432 DO jrow = j0, j+2, -nnb
435 DO i = jrow+nnb-1, jrow, -1
438 DO jj = ppw, ppw+len-1
439 temp = work( jj + 2*nnb )
440 work( jj + 2*nnb ) = c*temp - s*work( jj )
441 work( jj ) = s*temp + c*work( jj )
444 ppw = ppw - 2*nnb - 1
446 ppwo = ppwo + 4*nnb*nnb
465 DO i = min( jj+1, ihi ), j+2, -1
469 b( i, jj ) = c*temp - s*b( i-1, jj )
470 b( i-1, jj ) = s*temp + c*b( i-1, jj )
476 temp = b( jj+1, jj+1 )
477 CALL dlartg( temp, b( jj+1, jj ), c, s,
480 CALL drot( jj-top, b( top+1, jj+1 ), 1,
481 $ b( top+1, jj ), 1, c, s )
494 jj = mod( ihi-j-1, 3 )
495 DO i = ihi-j-3, jj+1, -3
505 temp1 = a( k, j+i+1 )
506 temp2 = a( k, j+i+2 )
507 temp3 = a( k, j+i+3 )
508 a( k, j+i+3 ) = c2*temp3 + s2*temp2
509 temp2 = -s2*temp3 + c2*temp2
510 a( k, j+i+2 ) = c1*temp2 + s1*temp1
511 temp1 = -s1*temp2 + c1*temp1
512 a( k, j+i+1 ) = c*temp1 + s*temp
513 a( k, j+i ) = -s*temp1 + c*temp
519 CALL drot( ihi-top, a( top+1, j+i+1 ), 1,
520 $ a( top+1, j+i ), 1, a( j+1+i, j ),
527 IF ( j .LT. jcol + nnb - 1 )
THEN
540 jrow = ihi - nblst + 1
541 CALL dgemv(
'Transpose', nblst, len, one, work,
542 $ nblst, a( jrow, j+1 ), 1, zero,
545 DO i = jrow, jrow+nblst-len-1
546 work( ppw ) = a( i, j+1 )
549 CALL dtrmv(
'Lower',
'Transpose',
'Non-unit',
550 $ nblst-len, work( len*nblst + 1 ), nblst,
551 $ work( pw+len ), 1 )
552 CALL dgemv(
'Transpose', len, nblst-len, one,
553 $ work( (len+1)*nblst - len + 1 ), nblst,
554 $ a( jrow+nblst-len, j+1 ), 1, one,
555 $ work( pw+len ), 1 )
557 DO i = jrow, jrow+nblst-1
558 a( i, j+1 ) = work( ppw )
575 ppwo = 1 + nblst*nblst
577 DO jrow = j0, jcol+1, -nnb
579 DO i = jrow, jrow+nnb-1
580 work( ppw ) = a( i, j+1 )
584 DO i = jrow+nnb, jrow+nnb+len-1
585 work( ppw ) = a( i, j+1 )
588 CALL dtrmv(
'Upper',
'Transpose',
'Non-unit',
590 $ work( ppwo + nnb ), 2*nnb, work( pw ),
592 CALL dtrmv(
'Lower',
'Transpose',
'Non-unit',
594 $ work( ppwo + 2*len*nnb ),
595 $ 2*nnb, work( pw + len ), 1 )
596 CALL dgemv(
'Transpose', nnb, len, one,
597 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
598 $ one, work( pw ), 1 )
599 CALL dgemv(
'Transpose', len, nnb, one,
600 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
601 $ a( jrow+nnb, j+1 ), 1, one,
602 $ work( pw+len ), 1 )
604 DO i = jrow, jrow+len+nnb-1
605 a( i, j+1 ) = work( ppw )
608 ppwo = ppwo + 4*nnb*nnb
615 cola = n - jcol - nnb + 1
617 CALL dgemm(
'Transpose',
'No Transpose', nblst,
618 $ cola, nblst, one, work, nblst,
619 $ a( j, jcol+nnb ), lda, zero, work( pw ),
621 CALL dlacpy(
'All', nblst, cola, work( pw ), nblst,
622 $ a( j, jcol+nnb ), lda )
623 ppwo = nblst*nblst + 1
625 DO j = j0, jcol+1, -nnb
637 CALL dorm22(
'Left',
'Transpose', 2*nnb, cola, nnb,
638 $ nnb, work( ppwo ), 2*nnb,
639 $ a( j, jcol+nnb ), lda, work( pw ),
645 CALL dgemm(
'Transpose',
'No Transpose', 2*nnb,
646 $ cola, 2*nnb, one, work( ppwo ), 2*nnb,
647 $ a( j, jcol+nnb ), lda, zero, work( pw ),
649 CALL dlacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
650 $ a( j, jcol+nnb ), lda )
652 ppwo = ppwo + 4*nnb*nnb
660 topq = max( 2, j - jcol + 1 )
666 CALL dgemm(
'No Transpose',
'No Transpose', nh,
667 $ nblst, nblst, one, q( topq, j ), ldq,
668 $ work, nblst, zero, work( pw ), nh )
669 CALL dlacpy(
'All', nh, nblst, work( pw ), nh,
670 $ q( topq, j ), ldq )
671 ppwo = nblst*nblst + 1
673 DO j = j0, jcol+1, -nnb
675 topq = max( 2, j - jcol + 1 )
682 CALL dorm22(
'Right',
'No Transpose', nh, 2*nnb,
683 $ nnb, nnb, work( ppwo ), 2*nnb,
684 $ q( topq, j ), ldq, work( pw ),
690 CALL dgemm(
'No Transpose',
'No Transpose', nh,
691 $ 2*nnb, 2*nnb, one, q( topq, j ), ldq,
692 $ work( ppwo ), 2*nnb, zero, work( pw ),
694 CALL dlacpy(
'All', nh, 2*nnb, work( pw ), nh,
695 $ q( topq, j ), ldq )
697 ppwo = ppwo + 4*nnb*nnb
703 IF ( wantz .OR. top.GT.0 )
THEN
708 CALL dlaset(
'All', nblst, nblst, zero, one, work,
710 pw = nblst * nblst + 1
712 CALL dlaset(
'All', 2*nnb, 2*nnb, zero, one,
713 $ work( pw ), 2*nnb )
719 DO j = jcol, jcol+nnb-1
720 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
722 jrow = j + n2nb*nnb + 2
728 DO jj = ppw, ppw+len-1
729 temp = work( jj + nblst )
730 work( jj + nblst ) = c*temp - s*work( jj )
731 work( jj ) = s*temp + c*work( jj )
734 ppw = ppw - nblst - 1
737 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
739 DO jrow = j0, j+2, -nnb
742 DO i = jrow+nnb-1, jrow, -1
747 DO jj = ppw, ppw+len-1
748 temp = work( jj + 2*nnb )
749 work( jj + 2*nnb ) = c*temp - s*work( jj )
750 work( jj ) = s*temp + c*work( jj )
753 ppw = ppw - 2*nnb - 1
755 ppwo = ppwo + 4*nnb*nnb
760 CALL dlaset(
'Lower', ihi - jcol - 1, nnb, zero, zero,
761 $ a( jcol + 2, jcol ), lda )
762 CALL dlaset(
'Lower', ihi - jcol - 1, nnb, zero, zero,
763 $ b( jcol + 2, jcol ), ldb )
770 CALL dgemm(
'No Transpose',
'No Transpose', top,
771 $ nblst, nblst, one, a( 1, j ), lda,
772 $ work, nblst, zero, work( pw ), top )
773 CALL dlacpy(
'All', top, nblst, work( pw ), top,
775 ppwo = nblst*nblst + 1
777 DO j = j0, jcol+1, -nnb
782 CALL dorm22(
'Right',
'No Transpose', top,
784 $ nnb, nnb, work( ppwo ), 2*nnb,
785 $ a( 1, j ), lda, work( pw ),
791 CALL dgemm(
'No Transpose',
'No Transpose', top,
792 $ 2*nnb, 2*nnb, one, a( 1, j ), lda,
793 $ work( ppwo ), 2*nnb, zero,
795 CALL dlacpy(
'All', top, 2*nnb, work( pw ), top,
798 ppwo = ppwo + 4*nnb*nnb
802 CALL dgemm(
'No Transpose',
'No Transpose', top,
803 $ nblst, nblst, one, b( 1, j ), ldb,
804 $ work, nblst, zero, work( pw ), top )
805 CALL dlacpy(
'All', top, nblst, work( pw ), top,
807 ppwo = nblst*nblst + 1
809 DO j = j0, jcol+1, -nnb
814 CALL dorm22(
'Right',
'No Transpose', top,
816 $ nnb, nnb, work( ppwo ), 2*nnb,
817 $ b( 1, j ), ldb, work( pw ),
823 CALL dgemm(
'No Transpose',
'No Transpose', top,
824 $ 2*nnb, 2*nnb, one, b( 1, j ), ldb,
825 $ work( ppwo ), 2*nnb, zero,
827 CALL dlacpy(
'All', top, 2*nnb, work( pw ), top,
830 ppwo = ppwo + 4*nnb*nnb
839 topq = max( 2, j - jcol + 1 )
845 CALL dgemm(
'No Transpose',
'No Transpose', nh,
846 $ nblst, nblst, one, z( topq, j ), ldz,
847 $ work, nblst, zero, work( pw ), nh )
848 CALL dlacpy(
'All', nh, nblst, work( pw ), nh,
849 $ z( topq, j ), ldz )
850 ppwo = nblst*nblst + 1
852 DO j = j0, jcol+1, -nnb
854 topq = max( 2, j - jcol + 1 )
861 CALL dorm22(
'Right',
'No Transpose', nh, 2*nnb,
862 $ nnb, nnb, work( ppwo ), 2*nnb,
863 $ z( topq, j ), ldz, work( pw ),
869 CALL dgemm(
'No Transpose',
'No Transpose', nh,
870 $ 2*nnb, 2*nnb, one, z( topq, j ), ldz,
871 $ work( ppwo ), 2*nnb, zero, work( pw ),
873 CALL dlacpy(
'All', nh, 2*nnb, work( pw ), nh,
874 $ z( topq, j ), ldz )
876 ppwo = ppwo + 4*nnb*nnb
887 IF ( jcol.NE.ilo )
THEN
895 $
CALL dgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb,
897 $ ldq, z, ldz, ierr )
899 work( 1 ) = dble( lwkopt )