227 SUBROUTINE zgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
228 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
238 CHARACTER COMPQ, COMPZ
239 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
242 COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
243 $ z( ldz, * ), work( * )
249 COMPLEX*16 CONE, CZERO
250 parameter( cone = ( 1.0d+0, 0.0d+0 ),
251 $ czero = ( 0.0d+0, 0.0d+0 ) )
254 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
255 CHARACTER*1 COMPQ2, COMPZ2
256 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
257 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
258 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
260 COMPLEX*16 C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
266 EXTERNAL ilaenv, lsame
273 INTRINSIC dble, dcmplx, dconjg, max
280 nb = ilaenv( 1,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
281 lwkopt = max( 6*n*nb, 1 )
282 work( 1 ) = dcmplx( lwkopt )
283 initq = lsame( compq,
'I' )
284 wantq = initq .OR. lsame( compq,
'V' )
285 initz = lsame( compz,
'I' )
286 wantz = initz .OR. lsame( compz,
'V' )
287 lquery = ( lwork.EQ.-1 )
289 IF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
291 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
293 ELSE IF( n.LT.0 )
THEN
295 ELSE IF( ilo.LT.1 )
THEN
297 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
299 ELSE IF( lda.LT.max( 1, n ) )
THEN
301 ELSE IF( ldb.LT.max( 1, n ) )
THEN
303 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 )
THEN
305 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 )
THEN
307 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
311 CALL xerbla(
'ZGGHD3', -info )
313 ELSE IF( lquery )
THEN
320 $
CALL zlaset(
'All', n, n, czero, cone, q, ldq )
322 $
CALL zlaset(
'All', n, n, czero, cone, z, ldz )
327 $
CALL zlaset(
'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
339 nbmin = ilaenv( 2,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
340 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
344 nx = max( nb, ilaenv( 3,
'ZGGHD3',
' ', n, ilo, ihi, -1 ) )
349 IF( lwork.LT.lwkopt )
THEN
355 nbmin = max( 2, ilaenv( 2,
'ZGGHD3',
' ', n, ilo, ihi,
357 IF( lwork.GE.6*n*nbmin )
THEN
366 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
376 kacc22 = ilaenv( 16,
'ZGGHD3',
' ', n, ilo, ihi, -1 )
378 DO jcol = ilo, ihi-2, nb
379 nnb = min( nb, ihi-jcol-1 )
387 n2nb = ( ihi-jcol-1 ) / nnb - 1
388 nblst = ihi - jcol - n2nb*nnb
389 CALL zlaset(
'All', nblst, nblst, czero, cone, work, nblst )
390 pw = nblst * nblst + 1
392 CALL zlaset(
'All', 2*nnb, 2*nnb, czero, cone,
393 $ work( pw ), 2*nnb )
399 DO j = jcol, jcol+nnb-1
406 CALL zlartg( temp, a( i, j ), c, s, a( i-1, j ) )
407 a( i, j ) = dcmplx( c )
413 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
415 jrow = j + n2nb*nnb + 2
419 DO jj = ppw, ppw+len-1
420 temp = work( jj + nblst )
421 work( jj + nblst ) = ctemp*temp - s*work( jj )
422 work( jj ) = dconjg( s )*temp + ctemp*work( jj )
425 ppw = ppw - nblst - 1
428 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
430 DO jrow = j0, j+2, -nnb
433 DO i = jrow+nnb-1, jrow, -1
436 DO jj = ppw, ppw+len-1
437 temp = work( jj + 2*nnb )
438 work( jj + 2*nnb ) = ctemp*temp - s*work( jj )
439 work( jj ) = dconjg( s )*temp + ctemp*work( jj )
442 ppw = ppw - 2*nnb - 1
444 ppwo = ppwo + 4*nnb*nnb
463 DO i = min( jj+1, ihi ), j+2, -1
467 b( i, jj ) = ctemp*temp - dconjg( s )*b( i-1, jj )
468 b( i-1, jj ) = s*temp + ctemp*b( i-1, jj )
474 temp = b( jj+1, jj+1 )
475 CALL zlartg( temp, b( jj+1, jj ), c, s,
477 b( jj+1, jj ) = czero
478 CALL zrot( jj-top, b( top+1, jj+1 ), 1,
479 $ b( top+1, jj ), 1, c, s )
480 a( jj+1, j ) = dcmplx( c )
481 b( jj+1, j ) = -dconjg( s )
487 jj = mod( ihi-j-1, 3 )
488 DO i = ihi-j-3, jj+1, -3
489 ctemp = a( j+1+i, j )
498 temp1 = a( k, j+i+1 )
499 temp2 = a( k, j+i+2 )
500 temp3 = a( k, j+i+3 )
501 a( k, j+i+3 ) = c2*temp3 + dconjg( s2 )*temp2
502 temp2 = -s2*temp3 + c2*temp2
503 a( k, j+i+2 ) = c1*temp2 + dconjg( s1 )*temp1
504 temp1 = -s1*temp2 + c1*temp1
505 a( k, j+i+1 ) = ctemp*temp1 + dconjg( s )*temp
506 a( k, j+i ) = -s*temp1 + ctemp*temp
512 c = dble( a( j+1+i, j ) )
513 CALL zrot( ihi-top, a( top+1, j+i+1 ), 1,
514 $ a( top+1, j+i ), 1, c,
515 $ -dconjg( b( j+1+i, j ) ) )
521 IF ( j .LT. jcol + nnb - 1 )
THEN
534 jrow = ihi - nblst + 1
535 CALL zgemv(
'Conjugate', nblst, len, cone, work,
536 $ nblst, a( jrow, j+1 ), 1, czero,
539 DO i = jrow, jrow+nblst-len-1
540 work( ppw ) = a( i, j+1 )
543 CALL ztrmv(
'Lower',
'Conjugate',
'Non-unit',
544 $ nblst-len, work( len*nblst + 1 ), nblst,
545 $ work( pw+len ), 1 )
546 CALL zgemv(
'Conjugate', len, nblst-len, cone,
547 $ work( (len+1)*nblst - len + 1 ), nblst,
548 $ a( jrow+nblst-len, j+1 ), 1, cone,
549 $ work( pw+len ), 1 )
551 DO i = jrow, jrow+nblst-1
552 a( i, j+1 ) = work( ppw )
569 ppwo = 1 + nblst*nblst
571 DO jrow = j0, jcol+1, -nnb
573 DO i = jrow, jrow+nnb-1
574 work( ppw ) = a( i, j+1 )
578 DO i = jrow+nnb, jrow+nnb+len-1
579 work( ppw ) = a( i, j+1 )
582 CALL ztrmv(
'Upper',
'Conjugate',
'Non-unit', len,
583 $ work( ppwo + nnb ), 2*nnb, work( pw ),
585 CALL ztrmv(
'Lower',
'Conjugate',
'Non-unit', nnb,
586 $ work( ppwo + 2*len*nnb ),
587 $ 2*nnb, work( pw + len ), 1 )
588 CALL zgemv(
'Conjugate', nnb, len, cone,
589 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
590 $ cone, work( pw ), 1 )
591 CALL zgemv(
'Conjugate', len, nnb, cone,
592 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
593 $ a( jrow+nnb, j+1 ), 1, cone,
594 $ work( pw+len ), 1 )
596 DO i = jrow, jrow+len+nnb-1
597 a( i, j+1 ) = work( ppw )
600 ppwo = ppwo + 4*nnb*nnb
607 cola = n - jcol - nnb + 1
609 CALL zgemm(
'Conjugate',
'No Transpose', nblst,
610 $ cola, nblst, cone, work, nblst,
611 $ a( j, jcol+nnb ), lda, czero, work( pw ),
613 CALL zlacpy(
'All', nblst, cola, work( pw ), nblst,
614 $ a( j, jcol+nnb ), lda )
615 ppwo = nblst*nblst + 1
617 DO j = j0, jcol+1, -nnb
629 CALL zunm22(
'Left',
'Conjugate', 2*nnb, cola, nnb,
630 $ nnb, work( ppwo ), 2*nnb,
631 $ a( j, jcol+nnb ), lda, work( pw ),
637 CALL zgemm(
'Conjugate',
'No Transpose', 2*nnb,
638 $ cola, 2*nnb, cone, work( ppwo ), 2*nnb,
639 $ a( j, jcol+nnb ), lda, czero, work( pw ),
641 CALL zlacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
642 $ a( j, jcol+nnb ), lda )
644 ppwo = ppwo + 4*nnb*nnb
652 topq = max( 2, j - jcol + 1 )
658 CALL zgemm(
'No Transpose',
'No Transpose', nh,
659 $ nblst, nblst, cone, q( topq, j ), ldq,
660 $ work, nblst, czero, work( pw ), nh )
661 CALL zlacpy(
'All', nh, nblst, work( pw ), nh,
662 $ q( topq, j ), ldq )
663 ppwo = nblst*nblst + 1
665 DO j = j0, jcol+1, -nnb
667 topq = max( 2, j - jcol + 1 )
674 CALL zunm22(
'Right',
'No Transpose', nh, 2*nnb,
675 $ nnb, nnb, work( ppwo ), 2*nnb,
676 $ q( topq, j ), ldq, work( pw ),
682 CALL zgemm(
'No Transpose',
'No Transpose', nh,
683 $ 2*nnb, 2*nnb, cone, q( topq, j ), ldq,
684 $ work( ppwo ), 2*nnb, czero, work( pw ),
686 CALL zlacpy(
'All', nh, 2*nnb, work( pw ), nh,
687 $ q( topq, j ), ldq )
689 ppwo = ppwo + 4*nnb*nnb
695 IF ( wantz .OR. top.GT.0 )
THEN
700 CALL zlaset(
'All', nblst, nblst, czero, cone, work,
702 pw = nblst * nblst + 1
704 CALL zlaset(
'All', 2*nnb, 2*nnb, czero, cone,
705 $ work( pw ), 2*nnb )
711 DO j = jcol, jcol+nnb-1
712 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
714 jrow = j + n2nb*nnb + 2
720 DO jj = ppw, ppw+len-1
721 temp = work( jj + nblst )
722 work( jj + nblst ) = ctemp*temp -
723 $ dconjg( s )*work( jj )
724 work( jj ) = s*temp + ctemp*work( jj )
727 ppw = ppw - nblst - 1
730 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
732 DO jrow = j0, j+2, -nnb
735 DO i = jrow+nnb-1, jrow, -1
740 DO jj = ppw, ppw+len-1
741 temp = work( jj + 2*nnb )
742 work( jj + 2*nnb ) = ctemp*temp -
743 $ dconjg( s )*work( jj )
744 work( jj ) = s*temp + ctemp*work( jj )
747 ppw = ppw - 2*nnb - 1
749 ppwo = ppwo + 4*nnb*nnb
754 CALL zlaset(
'Lower', ihi - jcol - 1, nnb, czero, czero,
755 $ a( jcol + 2, jcol ), lda )
756 CALL zlaset(
'Lower', ihi - jcol - 1, nnb, czero, czero,
757 $ b( jcol + 2, jcol ), ldb )
764 CALL zgemm(
'No Transpose',
'No Transpose', top,
765 $ nblst, nblst, cone, a( 1, j ), lda,
766 $ work, nblst, czero, work( pw ), top )
767 CALL zlacpy(
'All', top, nblst, work( pw ), top,
769 ppwo = nblst*nblst + 1
771 DO j = j0, jcol+1, -nnb
776 CALL zunm22(
'Right',
'No Transpose', top, 2*nnb,
777 $ nnb, nnb, work( ppwo ), 2*nnb,
778 $ a( 1, j ), lda, work( pw ),
784 CALL zgemm(
'No Transpose',
'No Transpose', top,
785 $ 2*nnb, 2*nnb, cone, a( 1, j ), lda,
786 $ work( ppwo ), 2*nnb, czero,
788 CALL zlacpy(
'All', top, 2*nnb, work( pw ), top,
791 ppwo = ppwo + 4*nnb*nnb
795 CALL zgemm(
'No Transpose',
'No Transpose', top,
796 $ nblst, nblst, cone, b( 1, j ), ldb,
797 $ work, nblst, czero, work( pw ), top )
798 CALL zlacpy(
'All', top, nblst, work( pw ), top,
800 ppwo = nblst*nblst + 1
802 DO j = j0, jcol+1, -nnb
807 CALL zunm22(
'Right',
'No Transpose', top, 2*nnb,
808 $ nnb, nnb, work( ppwo ), 2*nnb,
809 $ b( 1, j ), ldb, work( pw ),
815 CALL zgemm(
'No Transpose',
'No Transpose', top,
816 $ 2*nnb, 2*nnb, cone, b( 1, j ), ldb,
817 $ work( ppwo ), 2*nnb, czero,
819 CALL zlacpy(
'All', top, 2*nnb, work( pw ), top,
822 ppwo = ppwo + 4*nnb*nnb
831 topq = max( 2, j - jcol + 1 )
837 CALL zgemm(
'No Transpose',
'No Transpose', nh,
838 $ nblst, nblst, cone, z( topq, j ), ldz,
839 $ work, nblst, czero, work( pw ), nh )
840 CALL zlacpy(
'All', nh, nblst, work( pw ), nh,
841 $ z( topq, j ), ldz )
842 ppwo = nblst*nblst + 1
844 DO j = j0, jcol+1, -nnb
846 topq = max( 2, j - jcol + 1 )
853 CALL zunm22(
'Right',
'No Transpose', nh, 2*nnb,
854 $ nnb, nnb, work( ppwo ), 2*nnb,
855 $ z( topq, j ), ldz, work( pw ),
861 CALL zgemm(
'No Transpose',
'No Transpose', nh,
862 $ 2*nnb, 2*nnb, cone, z( topq, j ), ldz,
863 $ work( ppwo ), 2*nnb, czero, work( pw ),
865 CALL zlacpy(
'All', nh, 2*nnb, work( pw ), nh,
866 $ z( topq, j ), ldz )
868 ppwo = ppwo + 4*nnb*nnb
879 IF ( jcol.NE.ilo )
THEN
887 $
CALL zgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb, q,
888 $ ldq, z, ldz, ierr )
889 work( 1 ) = dcmplx( lwkopt )