223 SUBROUTINE zgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB,
225 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
234 CHARACTER COMPQ, COMPZ
235 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
238 COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
239 $ Z( LDZ, * ), WORK( * )
245 COMPLEX*16 CONE, CZERO
246 PARAMETER ( CONE = ( 1.0d+0, 0.0d+0 ),
247 $ czero = ( 0.0d+0, 0.0d+0 ) )
250 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
251 CHARACTER*1 COMPQ2, COMPZ2
252 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
253 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
254 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
256 COMPLEX*16 C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
262 EXTERNAL ilaenv, lsame
270 INTRINSIC dble, dcmplx, dconjg, max
277 nb = ilaenv( 1,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
284 work( 1 ) = dcmplx( 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(
'ZGGHD3', -info )
315 ELSE IF( lquery )
THEN
322 $
CALL zlaset(
'All', n, n, czero, cone, q, ldq )
324 $
CALL zlaset(
'All', n, n, czero, cone, z, ldz )
329 $
CALL zlaset(
'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
340 nbmin = ilaenv( 2,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
341 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
345 nx = max( nb, ilaenv( 3,
'ZGGHD3',
' ', n, ilo, ihi, -1 ) )
350 IF( lwork.LT.lwkopt )
THEN
356 nbmin = max( 2, ilaenv( 2,
'ZGGHD3',
' ', 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,
'ZGGHD3',
' ', 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 zlaset(
'All', nblst, nblst, czero, cone, work,
392 pw = nblst * nblst + 1
394 CALL zlaset(
'All', 2*nnb, 2*nnb, czero, cone,
395 $ work( pw ), 2*nnb )
401 DO j = jcol, jcol+nnb-1
408 CALL zlartg( temp, a( i, j ), c, s, a( i-1, j ) )
409 a( i, j ) = dcmplx( c )
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 ) = ctemp*temp - s*work( jj )
424 work( jj ) = dconjg( s )*temp + ctemp*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 ) = ctemp*temp - s*work( jj )
441 work( jj ) = dconjg( s )*temp + ctemp*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 ) = ctemp*temp - dconjg( s )*b( i-1, jj )
470 b( i-1, jj ) = s*temp + ctemp*b( i-1, jj )
476 temp = b( jj+1, jj+1 )
477 CALL zlartg( temp, b( jj+1, jj ), c, s,
479 b( jj+1, jj ) = czero
480 CALL zrot( jj-top, b( top+1, jj+1 ), 1,
481 $ b( top+1, jj ), 1, c, s )
482 a( jj+1, j ) = dcmplx( c )
483 b( jj+1, j ) = -dconjg( s )
489 jj = mod( ihi-j-1, 3 )
490 DO i = ihi-j-3, jj+1, -3
491 ctemp = a( j+1+i, j )
500 temp1 = a( k, j+i+1 )
501 temp2 = a( k, j+i+2 )
502 temp3 = a( k, j+i+3 )
503 a( k, j+i+3 ) = c2*temp3 + dconjg( s2 )*temp2
504 temp2 = -s2*temp3 + c2*temp2
505 a( k, j+i+2 ) = c1*temp2 + dconjg( s1 )*temp1
506 temp1 = -s1*temp2 + c1*temp1
507 a( k, j+i+1 ) = ctemp*temp1 + dconjg( s )*temp
508 a( k, j+i ) = -s*temp1 + ctemp*temp
514 c = dble( a( j+1+i, j ) )
515 CALL zrot( ihi-top, a( top+1, j+i+1 ), 1,
516 $ a( top+1, j+i ), 1, c,
517 $ -dconjg( b( j+1+i, j ) ) )
523 IF ( j .LT. jcol + nnb - 1 )
THEN
536 jrow = ihi - nblst + 1
537 CALL zgemv(
'Conjugate', nblst, len, cone, work,
538 $ nblst, a( jrow, j+1 ), 1, czero,
541 DO i = jrow, jrow+nblst-len-1
542 work( ppw ) = a( i, j+1 )
545 CALL ztrmv(
'Lower',
'Conjugate',
'Non-unit',
546 $ nblst-len, work( len*nblst + 1 ), nblst,
547 $ work( pw+len ), 1 )
548 CALL zgemv(
'Conjugate', len, nblst-len, cone,
549 $ work( (len+1)*nblst - len + 1 ), nblst,
550 $ a( jrow+nblst-len, j+1 ), 1, cone,
551 $ work( pw+len ), 1 )
553 DO i = jrow, jrow+nblst-1
554 a( i, j+1 ) = work( ppw )
571 ppwo = 1 + nblst*nblst
573 DO jrow = j0, jcol+1, -nnb
575 DO i = jrow, jrow+nnb-1
576 work( ppw ) = a( i, j+1 )
580 DO i = jrow+nnb, jrow+nnb+len-1
581 work( ppw ) = a( i, j+1 )
584 CALL ztrmv(
'Upper',
'Conjugate',
'Non-unit',
586 $ work( ppwo + nnb ), 2*nnb, work( pw ),
588 CALL ztrmv(
'Lower',
'Conjugate',
'Non-unit',
590 $ work( ppwo + 2*len*nnb ),
591 $ 2*nnb, work( pw + len ), 1 )
592 CALL zgemv(
'Conjugate', nnb, len, cone,
593 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
594 $ cone, work( pw ), 1 )
595 CALL zgemv(
'Conjugate', len, nnb, cone,
596 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
597 $ a( jrow+nnb, j+1 ), 1, cone,
598 $ work( pw+len ), 1 )
600 DO i = jrow, jrow+len+nnb-1
601 a( i, j+1 ) = work( ppw )
604 ppwo = ppwo + 4*nnb*nnb
611 cola = n - jcol - nnb + 1
613 CALL zgemm(
'Conjugate',
'No Transpose', nblst,
614 $ cola, nblst, cone, work, nblst,
615 $ a( j, jcol+nnb ), lda, czero, work( pw ),
617 CALL zlacpy(
'All', nblst, cola, work( pw ), nblst,
618 $ a( j, jcol+nnb ), lda )
619 ppwo = nblst*nblst + 1
621 DO j = j0, jcol+1, -nnb
633 CALL zunm22(
'Left',
'Conjugate', 2*nnb, cola, nnb,
634 $ nnb, work( ppwo ), 2*nnb,
635 $ a( j, jcol+nnb ), lda, work( pw ),
641 CALL zgemm(
'Conjugate',
'No Transpose', 2*nnb,
642 $ cola, 2*nnb, cone, work( ppwo ), 2*nnb,
643 $ a( j, jcol+nnb ), lda, czero, work( pw ),
645 CALL zlacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
646 $ a( j, jcol+nnb ), lda )
648 ppwo = ppwo + 4*nnb*nnb
656 topq = max( 2, j - jcol + 1 )
662 CALL zgemm(
'No Transpose',
'No Transpose', nh,
663 $ nblst, nblst, cone, q( topq, j ), ldq,
664 $ work, nblst, czero, work( pw ), nh )
665 CALL zlacpy(
'All', nh, nblst, work( pw ), nh,
666 $ q( topq, j ), ldq )
667 ppwo = nblst*nblst + 1
669 DO j = j0, jcol+1, -nnb
671 topq = max( 2, j - jcol + 1 )
678 CALL zunm22(
'Right',
'No Transpose', nh, 2*nnb,
679 $ nnb, nnb, work( ppwo ), 2*nnb,
680 $ q( topq, j ), ldq, work( pw ),
686 CALL zgemm(
'No Transpose',
'No Transpose', nh,
687 $ 2*nnb, 2*nnb, cone, q( topq, j ), ldq,
688 $ work( ppwo ), 2*nnb, czero, work( pw ),
690 CALL zlacpy(
'All', nh, 2*nnb, work( pw ), nh,
691 $ q( topq, j ), ldq )
693 ppwo = ppwo + 4*nnb*nnb
699 IF ( wantz .OR. top.GT.0 )
THEN
704 CALL zlaset(
'All', nblst, nblst, czero, cone, work,
706 pw = nblst * nblst + 1
708 CALL zlaset(
'All', 2*nnb, 2*nnb, czero, cone,
709 $ work( pw ), 2*nnb )
715 DO j = jcol, jcol+nnb-1
716 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
718 jrow = j + n2nb*nnb + 2
724 DO jj = ppw, ppw+len-1
725 temp = work( jj + nblst )
726 work( jj + nblst ) = ctemp*temp -
727 $ dconjg( s )*work( jj )
728 work( jj ) = s*temp + ctemp*work( jj )
731 ppw = ppw - nblst - 1
734 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
736 DO jrow = j0, j+2, -nnb
739 DO i = jrow+nnb-1, jrow, -1
744 DO jj = ppw, ppw+len-1
745 temp = work( jj + 2*nnb )
746 work( jj + 2*nnb ) = ctemp*temp -
747 $ dconjg( s )*work( jj )
748 work( jj ) = s*temp + ctemp*work( jj )
751 ppw = ppw - 2*nnb - 1
753 ppwo = ppwo + 4*nnb*nnb
758 CALL zlaset(
'Lower', ihi - jcol - 1, nnb, czero,
760 $ a( jcol + 2, jcol ), lda )
761 CALL zlaset(
'Lower', ihi - jcol - 1, nnb, czero,
763 $ b( jcol + 2, jcol ), ldb )
770 CALL zgemm(
'No Transpose',
'No Transpose', top,
771 $ nblst, nblst, cone, a( 1, j ), lda,
772 $ work, nblst, czero, work( pw ), top )
773 CALL zlacpy(
'All', top, nblst, work( pw ), top,
775 ppwo = nblst*nblst + 1
777 DO j = j0, jcol+1, -nnb
782 CALL zunm22(
'Right',
'No Transpose', top,
784 $ nnb, nnb, work( ppwo ), 2*nnb,
785 $ a( 1, j ), lda, work( pw ),
791 CALL zgemm(
'No Transpose',
'No Transpose', top,
792 $ 2*nnb, 2*nnb, cone, a( 1, j ), lda,
793 $ work( ppwo ), 2*nnb, czero,
795 CALL zlacpy(
'All', top, 2*nnb, work( pw ), top,
798 ppwo = ppwo + 4*nnb*nnb
802 CALL zgemm(
'No Transpose',
'No Transpose', top,
803 $ nblst, nblst, cone, b( 1, j ), ldb,
804 $ work, nblst, czero, work( pw ), top )
805 CALL zlacpy(
'All', top, nblst, work( pw ), top,
807 ppwo = nblst*nblst + 1
809 DO j = j0, jcol+1, -nnb
814 CALL zunm22(
'Right',
'No Transpose', top,
816 $ nnb, nnb, work( ppwo ), 2*nnb,
817 $ b( 1, j ), ldb, work( pw ),
823 CALL zgemm(
'No Transpose',
'No Transpose', top,
824 $ 2*nnb, 2*nnb, cone, b( 1, j ), ldb,
825 $ work( ppwo ), 2*nnb, czero,
827 CALL zlacpy(
'All', top, 2*nnb, work( pw ), top,
830 ppwo = ppwo + 4*nnb*nnb
839 topq = max( 2, j - jcol + 1 )
845 CALL zgemm(
'No Transpose',
'No Transpose', nh,
846 $ nblst, nblst, cone, z( topq, j ), ldz,
847 $ work, nblst, czero, work( pw ), nh )
848 CALL zlacpy(
'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 zunm22(
'Right',
'No Transpose', nh, 2*nnb,
862 $ nnb, nnb, work( ppwo ), 2*nnb,
863 $ z( topq, j ), ldz, work( pw ),
869 CALL zgemm(
'No Transpose',
'No Transpose', nh,
870 $ 2*nnb, 2*nnb, cone, z( topq, j ), ldz,
871 $ work( ppwo ), 2*nnb, czero, work( pw ),
873 CALL zlacpy(
'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 zgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb,
897 $ ldq, z, ldz, ierr )
899 work( 1 ) = dcmplx( lwkopt )