227 SUBROUTINE cgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB,
229 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
239 CHARACTER COMPQ, COMPZ
240 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
243 COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
244 $ Z( LDZ, * ), WORK( * )
251 PARAMETER ( CONE = ( 1.0e+0, 0.0e+0 ),
252 $ czero = ( 0.0e+0, 0.0e+0 ) )
255 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
256 CHARACTER*1 COMPQ2, COMPZ2
257 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
258 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
259 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
261 COMPLEX C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
268 EXTERNAL ilaenv, lsame, sroundup_lwork
276 INTRINSIC real, cmplx, conjg, max
283 nb = ilaenv( 1,
'CGGHD3',
' ', n, ilo, ihi, -1 )
290 work( 1 ) = sroundup_lwork( lwkopt )
291 initq = lsame( compq,
'I' )
292 wantq = initq .OR. lsame( compq,
'V' )
293 initz = lsame( compz,
'I' )
294 wantz = initz .OR. lsame( compz,
'V' )
295 lquery = ( lwork.EQ.-1 )
297 IF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
299 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
301 ELSE IF( n.LT.0 )
THEN
303 ELSE IF( ilo.LT.1 )
THEN
305 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
307 ELSE IF( lda.LT.max( 1, n ) )
THEN
309 ELSE IF( ldb.LT.max( 1, n ) )
THEN
311 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 )
THEN
313 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 )
THEN
315 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
319 CALL xerbla(
'CGGHD3', -info )
321 ELSE IF( lquery )
THEN
328 $
CALL claset(
'All', n, n, czero, cone, q, ldq )
330 $
CALL claset(
'All', n, n, czero, cone, z, ldz )
335 $
CALL claset(
'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
346 nbmin = ilaenv( 2,
'CGGHD3',
' ', n, ilo, ihi, -1 )
347 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
351 nx = max( nb, ilaenv( 3,
'CGGHD3',
' ', n, ilo, ihi, -1 ) )
356 IF( lwork.LT.lwkopt )
THEN
362 nbmin = max( 2, ilaenv( 2,
'CGGHD3',
' ', n, ilo, ihi,
364 IF( lwork.GE.6*n*nbmin )
THEN
373 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
383 kacc22 = ilaenv( 16,
'CGGHD3',
' ', n, ilo, ihi, -1 )
385 DO jcol = ilo, ihi-2, nb
386 nnb = min( nb, ihi-jcol-1 )
394 n2nb = ( ihi-jcol-1 ) / nnb - 1
395 nblst = ihi - jcol - n2nb*nnb
396 CALL claset(
'All', nblst, nblst, czero, cone, work,
398 pw = nblst * nblst + 1
400 CALL claset(
'All', 2*nnb, 2*nnb, czero, cone,
401 $ work( pw ), 2*nnb )
407 DO j = jcol, jcol+nnb-1
414 CALL clartg( temp, a( i, j ), c, s, a( i-1, j ) )
415 a( i, j ) = cmplx( c )
421 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
423 jrow = j + n2nb*nnb + 2
427 DO jj = ppw, ppw+len-1
428 temp = work( jj + nblst )
429 work( jj + nblst ) = ctemp*temp - s*work( jj )
430 work( jj ) = conjg( s )*temp + ctemp*work( jj )
433 ppw = ppw - nblst - 1
436 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
438 DO jrow = j0, j+2, -nnb
441 DO i = jrow+nnb-1, jrow, -1
444 DO jj = ppw, ppw+len-1
445 temp = work( jj + 2*nnb )
446 work( jj + 2*nnb ) = ctemp*temp - s*work( jj )
447 work( jj ) = conjg( s )*temp + ctemp*work( jj )
450 ppw = ppw - 2*nnb - 1
452 ppwo = ppwo + 4*nnb*nnb
471 DO i = min( jj+1, ihi ), j+2, -1
475 b( i, jj ) = ctemp*temp - conjg( s )*b( i-1, jj )
476 b( i-1, jj ) = s*temp + ctemp*b( i-1, jj )
482 temp = b( jj+1, jj+1 )
483 CALL clartg( temp, b( jj+1, jj ), c, s,
485 b( jj+1, jj ) = czero
486 CALL crot( jj-top, b( top+1, jj+1 ), 1,
487 $ b( top+1, jj ), 1, c, s )
488 a( jj+1, j ) = cmplx( c )
489 b( jj+1, j ) = -conjg( s )
495 jj = mod( ihi-j-1, 3 )
496 DO i = ihi-j-3, jj+1, -3
497 ctemp = a( j+1+i, j )
506 temp1 = a( k, j+i+1 )
507 temp2 = a( k, j+i+2 )
508 temp3 = a( k, j+i+3 )
509 a( k, j+i+3 ) = c2*temp3 + conjg( s2 )*temp2
510 temp2 = -s2*temp3 + c2*temp2
511 a( k, j+i+2 ) = c1*temp2 + conjg( s1 )*temp1
512 temp1 = -s1*temp2 + c1*temp1
513 a( k, j+i+1 ) = ctemp*temp1 + conjg( s )*temp
514 a( k, j+i ) = -s*temp1 + ctemp*temp
520 c = real( a( j+1+i, j ) )
521 CALL crot( ihi-top, a( top+1, j+i+1 ), 1,
522 $ a( top+1, j+i ), 1, c,
523 $ -conjg( b( j+1+i, j ) ) )
529 IF ( j .LT. jcol + nnb - 1 )
THEN
542 jrow = ihi - nblst + 1
543 CALL cgemv(
'Conjugate', nblst, len, cone, work,
544 $ nblst, a( jrow, j+1 ), 1, czero,
547 DO i = jrow, jrow+nblst-len-1
548 work( ppw ) = a( i, j+1 )
551 CALL ctrmv(
'Lower',
'Conjugate',
'Non-unit',
552 $ nblst-len, work( len*nblst + 1 ), nblst,
553 $ work( pw+len ), 1 )
554 CALL cgemv(
'Conjugate', len, nblst-len, cone,
555 $ work( (len+1)*nblst - len + 1 ), nblst,
556 $ a( jrow+nblst-len, j+1 ), 1, cone,
557 $ work( pw+len ), 1 )
559 DO i = jrow, jrow+nblst-1
560 a( i, j+1 ) = work( ppw )
577 ppwo = 1 + nblst*nblst
579 DO jrow = j0, jcol+1, -nnb
581 DO i = jrow, jrow+nnb-1
582 work( ppw ) = a( i, j+1 )
586 DO i = jrow+nnb, jrow+nnb+len-1
587 work( ppw ) = a( i, j+1 )
590 CALL ctrmv(
'Upper',
'Conjugate',
'Non-unit',
592 $ work( ppwo + nnb ), 2*nnb, work( pw ),
594 CALL ctrmv(
'Lower',
'Conjugate',
'Non-unit',
596 $ work( ppwo + 2*len*nnb ),
597 $ 2*nnb, work( pw + len ), 1 )
598 CALL cgemv(
'Conjugate', nnb, len, cone,
599 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
600 $ cone, work( pw ), 1 )
601 CALL cgemv(
'Conjugate', len, nnb, cone,
602 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
603 $ a( jrow+nnb, j+1 ), 1, cone,
604 $ work( pw+len ), 1 )
606 DO i = jrow, jrow+len+nnb-1
607 a( i, j+1 ) = work( ppw )
610 ppwo = ppwo + 4*nnb*nnb
617 cola = n - jcol - nnb + 1
619 CALL cgemm(
'Conjugate',
'No Transpose', nblst,
620 $ cola, nblst, cone, work, nblst,
621 $ a( j, jcol+nnb ), lda, czero, work( pw ),
623 CALL clacpy(
'All', nblst, cola, work( pw ), nblst,
624 $ a( j, jcol+nnb ), lda )
625 ppwo = nblst*nblst + 1
627 DO j = j0, jcol+1, -nnb
639 CALL cunm22(
'Left',
'Conjugate', 2*nnb, cola, nnb,
640 $ nnb, work( ppwo ), 2*nnb,
641 $ a( j, jcol+nnb ), lda, work( pw ),
647 CALL cgemm(
'Conjugate',
'No Transpose', 2*nnb,
648 $ cola, 2*nnb, cone, work( ppwo ), 2*nnb,
649 $ a( j, jcol+nnb ), lda, czero, work( pw ),
651 CALL clacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
652 $ a( j, jcol+nnb ), lda )
654 ppwo = ppwo + 4*nnb*nnb
662 topq = max( 2, j - jcol + 1 )
668 CALL cgemm(
'No Transpose',
'No Transpose', nh,
669 $ nblst, nblst, cone, q( topq, j ), ldq,
670 $ work, nblst, czero, work( pw ), nh )
671 CALL clacpy(
'All', nh, nblst, work( pw ), nh,
672 $ q( topq, j ), ldq )
673 ppwo = nblst*nblst + 1
675 DO j = j0, jcol+1, -nnb
677 topq = max( 2, j - jcol + 1 )
684 CALL cunm22(
'Right',
'No Transpose', nh, 2*nnb,
685 $ nnb, nnb, work( ppwo ), 2*nnb,
686 $ q( topq, j ), ldq, work( pw ),
692 CALL cgemm(
'No Transpose',
'No Transpose', nh,
693 $ 2*nnb, 2*nnb, cone, q( topq, j ), ldq,
694 $ work( ppwo ), 2*nnb, czero, work( pw ),
696 CALL clacpy(
'All', nh, 2*nnb, work( pw ), nh,
697 $ q( topq, j ), ldq )
699 ppwo = ppwo + 4*nnb*nnb
705 IF ( wantz .OR. top.GT.0 )
THEN
710 CALL claset(
'All', nblst, nblst, czero, cone, work,
712 pw = nblst * nblst + 1
714 CALL claset(
'All', 2*nnb, 2*nnb, czero, cone,
715 $ work( pw ), 2*nnb )
721 DO j = jcol, jcol+nnb-1
722 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
724 jrow = j + n2nb*nnb + 2
730 DO jj = ppw, ppw+len-1
731 temp = work( jj + nblst )
732 work( jj + nblst ) = ctemp*temp -
733 $ conjg( s )*work( jj )
734 work( jj ) = s*temp + ctemp*work( jj )
737 ppw = ppw - nblst - 1
740 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
742 DO jrow = j0, j+2, -nnb
745 DO i = jrow+nnb-1, jrow, -1
750 DO jj = ppw, ppw+len-1
751 temp = work( jj + 2*nnb )
752 work( jj + 2*nnb ) = ctemp*temp -
753 $ conjg( s )*work( jj )
754 work( jj ) = s*temp + ctemp*work( jj )
757 ppw = ppw - 2*nnb - 1
759 ppwo = ppwo + 4*nnb*nnb
764 CALL claset(
'Lower', ihi - jcol - 1, nnb, czero,
766 $ a( jcol + 2, jcol ), lda )
767 CALL claset(
'Lower', ihi - jcol - 1, nnb, czero,
769 $ b( jcol + 2, jcol ), ldb )
776 CALL cgemm(
'No Transpose',
'No Transpose', top,
777 $ nblst, nblst, cone, a( 1, j ), lda,
778 $ work, nblst, czero, work( pw ), top )
779 CALL clacpy(
'All', top, nblst, work( pw ), top,
781 ppwo = nblst*nblst + 1
783 DO j = j0, jcol+1, -nnb
788 CALL cunm22(
'Right',
'No Transpose', top,
790 $ nnb, nnb, work( ppwo ), 2*nnb,
791 $ a( 1, j ), lda, work( pw ),
797 CALL cgemm(
'No Transpose',
'No Transpose', top,
798 $ 2*nnb, 2*nnb, cone, a( 1, j ), lda,
799 $ work( ppwo ), 2*nnb, czero,
801 CALL clacpy(
'All', top, 2*nnb, work( pw ), top,
804 ppwo = ppwo + 4*nnb*nnb
808 CALL cgemm(
'No Transpose',
'No Transpose', top,
809 $ nblst, nblst, cone, b( 1, j ), ldb,
810 $ work, nblst, czero, work( pw ), top )
811 CALL clacpy(
'All', top, nblst, work( pw ), top,
813 ppwo = nblst*nblst + 1
815 DO j = j0, jcol+1, -nnb
820 CALL cunm22(
'Right',
'No Transpose', top,
822 $ nnb, nnb, work( ppwo ), 2*nnb,
823 $ b( 1, j ), ldb, work( pw ),
829 CALL cgemm(
'No Transpose',
'No Transpose', top,
830 $ 2*nnb, 2*nnb, cone, b( 1, j ), ldb,
831 $ work( ppwo ), 2*nnb, czero,
833 CALL clacpy(
'All', top, 2*nnb, work( pw ), top,
836 ppwo = ppwo + 4*nnb*nnb
845 topq = max( 2, j - jcol + 1 )
851 CALL cgemm(
'No Transpose',
'No Transpose', nh,
852 $ nblst, nblst, cone, z( topq, j ), ldz,
853 $ work, nblst, czero, work( pw ), nh )
854 CALL clacpy(
'All', nh, nblst, work( pw ), nh,
855 $ z( topq, j ), ldz )
856 ppwo = nblst*nblst + 1
858 DO j = j0, jcol+1, -nnb
860 topq = max( 2, j - jcol + 1 )
867 CALL cunm22(
'Right',
'No Transpose', nh, 2*nnb,
868 $ nnb, nnb, work( ppwo ), 2*nnb,
869 $ z( topq, j ), ldz, work( pw ),
875 CALL cgemm(
'No Transpose',
'No Transpose', nh,
876 $ 2*nnb, 2*nnb, cone, z( topq, j ), ldz,
877 $ work( ppwo ), 2*nnb, czero, work( pw ),
879 CALL clacpy(
'All', nh, 2*nnb, work( pw ), nh,
880 $ z( topq, j ), ldz )
882 ppwo = ppwo + 4*nnb*nnb
893 IF ( jcol.NE.ilo )
THEN
901 $
CALL cgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb,
903 $ ldq, z, ldz, ierr )
905 work( 1 ) = sroundup_lwork( lwkopt )