225 SUBROUTINE zgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
226 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
235 CHARACTER COMPQ, COMPZ
236 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
239 COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
246 COMPLEX*16 CONE, CZERO
247 parameter( cone = ( 1.0d+0, 0.0d+0 ),
248 $ czero = ( 0.0d+0, 0.0d+0 ) )
251 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
252 CHARACTER*1 COMPQ2, COMPZ2
253 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
254 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
255 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
257 COMPLEX*16 C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
263 EXTERNAL ilaenv, lsame
270 INTRINSIC dble, dcmplx, dconjg,
max
277 nb = ilaenv( 1,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
278 lwkopt =
max( 6*n*nb, 1 )
279 work( 1 ) = dcmplx( lwkopt )
280 initq = lsame( compq,
'I' )
281 wantq = initq .OR. lsame( compq,
'V' )
282 initz = lsame( compz,
'I' )
283 wantz = initz .OR. lsame( compz,
'V' )
284 lquery = ( lwork.EQ.-1 )
286 IF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
288 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
290 ELSE IF( n.LT.0 )
THEN
292 ELSE IF( ilo.LT.1 )
THEN
294 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
296 ELSE IF( lda.LT.
max( 1, n ) )
THEN
298 ELSE IF( ldb.LT.
max( 1, n ) )
THEN
300 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 )
THEN
302 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 )
THEN
304 ELSE IF( lwork.LT.
THEN
308 CALL xerbla(
'ZGGHD3', -info )
310 ELSE IF( lquery )
THEN
317 $
CALL zlaset(
'All', n, n, czero, cone, q, ldq )
319 $
CALL zlaset(
'All', n, n, czero, cone, z, ldz )
324 $
CALL zlaset(
'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
336 nbmin = ilaenv( 2,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
337 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
341 nx =
max( nb, ilaenv( 3,
'ZGGHD3',
' ', n, ilo, ihi, -1 ) )
346 IF( lwork.LT.lwkopt )
THEN
352 nbmin =
max( 2, ilaenv( 2,
'ZGGHD3',
' ', n, ilo, ihi,
354 IF( lwork.GE.6*n*nbmin )
THEN
363 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
373 kacc22 = ilaenv( 16,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
375 DO jcol = ilo, ihi-2, nb
376 nnb =
min( nb, ihi-jcol-1 )
384 n2nb = ( ihi-jcol-1 ) / nnb - 1
385 nblst = ihi - jcol - n2nb*nnb
386 CALL zlaset(
'All', nblst, nblst, czero, cone, work, nblst )
387 pw = nblst * nblst + 1
389 CALL zlaset(
'All', 2*nnb, 2*nnb, czero, cone,
390 $ work( pw ), 2*nnb )
396 DO j = jcol, jcol+nnb-1
403 CALL zlartg( temp, a( i, j ), c, s, a( i-1, j ) )
404 a( i, j ) = dcmplx( c )
410 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
412 jrow = j + n2nb*nnb + 2
416 DO jj = ppw, ppw+len-1
417 temp = work( jj + nblst )
418 work( jj + nblst ) = ctemp*temp - s*work( jj )
419 work( jj ) = dconjg( s )*temp + ctemp*work( jj )
422 ppw = ppw - nblst - 1
430 DO i = jrow+nnb-1, jrow, -1
433 DO jj = ppw, ppw+len-1
434 temp = work( jj + 2*nnb )
435 work( jj + 2*nnb ) = ctemp*temp - s*work( jj )
436 work( jj ) = dconjg( s )*temp + ctemp*work( jj )
439 ppw = ppw - 2*nnb - 1
441 ppwo = ppwo + 4*nnb*nnb
460 DO i =
min( jj+1, ihi ), j+2, -1
464 b( i, jj ) = ctemp*temp - dconjg( s )*b( i-1, jj )
465 b( i-1, jj ) = s*temp + ctemp*b( i-1, jj )
471 temp = b( jj+1, jj+1 )
472 CALL zlartg( temp, b( jj+1, jj ), c, s,
474 b( jj+1, jj ) = czero
475 CALL zrot( jj-top, b( top+1, jj+1 ), 1,
476 $ b( top+1, jj ), 1, c, s )
477 a( jj+1, j ) = dcmplx( c )
478 b( jj+1, j ) = -dconjg( s )
484 jj = mod( ihi-j-1, 3 )
485 DO i = ihi-j-3, jj+1, -3
486 ctemp = a( j+1+i, j )
495 temp1 = a( k, j+i+1 )
496 temp2 = a( k, j+i+2 )
497 temp3 = a( k, j+i+3 )
498 a( k, j+i+3 ) = c2*temp3 + dconjg( s2 )*temp2
499 temp2 = -s2*temp3 + c2*temp2
500 a( k, j+i+2 ) = c1*temp2 + dconjg( s1 )*temp1
501 temp1 = -s1*temp2 + c1*temp1
502 a( k, j+i+1 ) = ctemp*temp1 + dconjg( s )*temp
503 a( k, j+i ) = -s*temp1 + ctemp*temp
509 c = dble( a( j+1+i, j ) )
510 CALL zrot( ihi-top, a( top+1, j+i+1 ), 1,
511 $ a( top+1, j+i ), 1, c,
512 $ -dconjg( b( j+1+i, j ) ) )
518 IF ( j .LT. jcol + nnb - 1 )
THEN
531 jrow = ihi - nblst + 1
532 CALL zgemv(
'Conjugate', nblst, len, cone, work,
533 $ nblst, a( jrow, j+1 ), 1, czero,
536 DO i = jrow, jrow+nblst-len-1
537 work( ppw ) = a( i, j+1 )
540 CALL ztrmv(
'Lower',
'Conjugate',
'Non-unit',
541 $ nblst-len, work( len*nblst + 1 ), nblst,
542 $ work( pw+len ), 1 )
543 CALL zgemv(
'Conjugate', len, nblst-len, cone,
544 $ work( (len+1)*nblst - len + 1 ), nblst,
545 $ a( jrow+nblst-len, j+1 ), 1, cone,
546 $ work( pw+len ), 1 )
548 DO i = jrow, jrow+nblst-1
549 a( i, j+1 ) = work( ppw )
566 ppwo = 1 + nblst*nblst
568 DO jrow = j0, jcol+1, -nnb
570 DO i = jrow, jrow+nnb-1
571 work( ppw ) = a( i, j+1 )
575 DO i = jrow+nnb, jrow+nnb+len-1
576 work( ppw ) = a( i, j+1 )
579 CALL ztrmv(
'Upper',
'Conjugate',
'Non-unit', len,
580 $ work( ppwo + nnb ), 2*nnb, work( pw ),
582 CALL ztrmv(
'Lower',
'Conjugate',
'Non-unit', nnb,
583 $ work( ppwo + 2*len*nnb ),
584 $ 2*nnb, work( pw + len ), 1 )
585 CALL zgemv(
'Conjugate', nnb, len, cone,
586 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
587 $ cone, work( pw ), 1 )
588 CALL zgemv(
'Conjugate', len, nnb, cone,
589 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
590 $ a( jrow+nnb, j+1 ), 1, cone,
591 $ work( pw+len ), 1 )
593 DO i = jrow, jrow+len+nnb-1
594 a( i, j+1 ) = work( ppw )
597 ppwo = ppwo + 4*nnb*nnb
604 cola = n - jcol - nnb + 1
606 CALL zgemm(
'Conjugate',
'No Transpose', nblst,
607 $ cola, nblst, cone, work, nblst,
608 $ a( j, jcol+nnb ), lda, czero, work( pw ),
610 CALL zlacpy(
'All', nblst, cola, work( pw ), nblst,
611 $ a( j, jcol+nnb ), lda )
612 ppwo = nblst*nblst + 1
614 DO j = j0, jcol+1, -nnb
626 CALL zunm22(
'Left',
'Conjugate', 2*nnb, cola, nnb,
627 $ nnb, work( ppwo ), 2*nnb,
628 $ a( j, jcol+nnb ), lda, work( pw ),
634 CALL zgemm(
'Conjugate',
'No Transpose', 2*nnb,
635 $ cola, 2*nnb, cone, work( ppwo ), 2*nnb,
636 $ a( j, jcol+nnb ), lda, czero, work( pw ),
638 CALL zlacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
639 $ a( j, jcol+nnb ), lda )
641 ppwo = ppwo + 4*nnb*nnb
649 topq =
max( 2, j - jcol + 1 )
655 CALL zgemm(
'No Transpose',
'No Transpose', nh,
656 $ nblst, nblst, cone, q( topq, j ), ldq,
657 $ work, nblst, czero, work( pw ), nh )
658 CALL zlacpy(
'All', nh, nblst, work( pw ), nh,
659 $ q( topq, j ), ldq )
660 ppwo = nblst*nblst + 1
662 DO j = j0, jcol+1, -nnb
671 CALL zunm22(
'Right',
'No Transpose', nh, 2*nnb,
672 $ nnb, nnb, work( ppwo ), 2*nnb,
679 CALL zgemm(
'No Transpose',
'No Transpose', nh,
680 $ 2*nnb, 2*nnb, cone, q( topq, j ), ldq,
681 $ work( ppwo ), 2*nnb, czero, work( pw ),
683 CALL zlacpy(
'All', nh, 2*nnb, work( pw ), nh,
684 $ q( topq, j ), ldq )
686 ppwo = ppwo + 4*nnb*nnb
692 IF ( wantz .OR. top.GT.0 )
THEN
697 CALL zlaset(
'All', nblst, nblst, czero, cone, work,
699 pw = nblst * nblst + 1
701 CALL zlaset(
'All', 2*nnb, 2*nnb, czero, cone,
702 $ work( pw ), 2*nnb )
708 DO j = jcol, jcol+nnb-1
709 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
711 jrow = j + n2nb*nnb + 2
717 DO jj = ppw, ppw+len-1
718 temp = work( jj + nblst )
719 work( jj + nblst ) = ctemp*temp -
720 $ dconjg( s )*work( jj )
721 work( jj ) = s*temp + ctemp*work( jj )
724 ppw = ppw - nblst - 1
727 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
729 DO jrow = j0, j+2, -nnb
732 DO i = jrow+nnb-1, jrow, -1
737 DO jj = ppw, ppw+len-1
738 temp = work( jj + 2*nnb )
739 work( jj + 2*nnb ) = ctemp*temp -
740 $ dconjg( s )*work( jj )
741 work( jj ) = s*temp + ctemp*work( jj )
744 ppw = ppw - 2*nnb - 1
746 ppwo = ppwo + 4*nnb*nnb
751 CALL zlaset(
'Lower', ihi - jcol - 1, nnb, czero, czero,
752 $ a( jcol + 2, jcol ), lda )
753 CALL zlaset(
'Lower', ihi - jcol - 1, nnb, czero, czero,
754 $ b( jcol + 2, jcol ), ldb )
761 CALL zgemm(
'No Transpose',
'No Transpose', top,
762 $ nblst, nblst, cone, a( 1, j ), lda,
763 $ work, nblst, czero, work( pw ), top )
764 CALL zlacpy(
'All', top, nblst, work( pw ), top,
766 ppwo = nblst*nblst + 1
768 DO j = j0, jcol+1, -nnb
773 CALL zunm22(
'Right',
'No Transpose', top, 2*nnb,
774 $ nnb, nnb, work( ppwo ), 2*nnb,
775 $ a( 1, j ), lda, work( pw ),
781 CALL zgemm(
'No Transpose',
'No Transpose', top,
782 $ 2*nnb, 2*nnb, cone, a( 1, j ), lda,
783 $ work( ppwo ), 2*nnb, czero,
785 CALL zlacpy(
'All', top, 2*nnb, work( pw ), top,
788 ppwo = ppwo + 4*nnb*nnb
792 CALL zgemm(
'No Transpose',
'No Transpose', top,
793 $ nblst, nblst, cone, b( 1, j ), ldb,
794 $ work, nblst, czero, work( pw ), top )
795 CALL zlacpy(
'All', top, nblst, work( pw ), top,
797 ppwo = nblst*nblst + 1
799 DO j = j0, jcol+1, -nnb
804 CALL zunm22(
'Right',
'No Transpose', top, 2*nnb,
805 $ nnb, nnb, work( ppwo ), 2*nnb,
806 $ b( 1, j ), ldb, work( pw ),
812 CALL zgemm(
'No Transpose',
'No Transpose', top,
813 $ 2*nnb, 2*nnb, cone, b( 1, j ), ldb,
814 $ work( ppwo ), 2*nnb, czero,
816 CALL zlacpy(
'All', top, 2*nnb, work( pw ), top
819 ppwo = ppwo + 4*nnb*nnb
828 topq =
max( 2, j - jcol + 1 )
834 CALL zgemm(
'No Transpose',
'No Transpose', nh,
835 $ nblst, nblst, cone, z( topq, j ), ldz,
836 $ work, nblst, czero, work( pw ), nh )
837 CALL zlacpy(
'All', nh, nblst, work( pw ), nh,
838 $ z( topq, j ), ldz )
839 ppwo = nblst*nblst + 1
841 DO j = j0, jcol+1, -nnb
843 topq =
max( 2, j - jcol + 1 )
850 CALL zunm22(
'Right',
'No Transpose', nh, 2*nnb,
851 $ nnb, nnb, work( ppwo ), 2*nnb,
852 $ z( topq, j ), ldz, work( pw ),
858 CALL zgemm(
'No Transpose',
'No Transpose', nh,
859 $ 2*nnb, 2*nnb, cone, z( topq, j ), ldz,
860 $ work( ppwo ), 2*nnb, czero, work( pw ),
862 CALL zlacpy(
'All', nh, 2*nnb, work( pw ), nh,
863 $ z( topq, j ), ldz )
865 ppwo = ppwo + 4*nnb*nnb
876 IF ( jcol.NE.ilo )
THEN
884 $
CALL zgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb, q,
885 $ ldq, z, ldz, ierr )
886 work( 1 ) = dcmplx( lwkopt )