229 SUBROUTINE cgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
230 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
240 CHARACTER COMPQ, COMPZ
241 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
244 COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
245 $ z( ldz, * ), work( * )
252 parameter( cone = ( 1.0e+0, 0.0e+0 ),
253 $ czero = ( 0.0e+0, 0.0e+0 ) )
256 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
257 CHARACTER*1 COMPQ2, COMPZ2
258 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
259 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
260 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
262 COMPLEX C1, C2, CTEMP, S, S1, S2, TEMP, TEMP1, TEMP2,
268 EXTERNAL ilaenv, lsame
275 INTRINSIC real, cmplx, conjg, max
282 nb = ilaenv( 1,
'CGGHD3',
' ', n, ilo, ihi, -1 )
283 lwkopt = max( 6*n*nb, 1 )
284 work( 1 ) = cmplx( 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(
'CGGHD3', -info )
315 ELSE IF( lquery )
THEN
322 $
CALL claset(
'All', n, n, czero, cone, q, ldq )
324 $
CALL claset(
'All', n, n, czero, cone, z, ldz )
329 $
CALL claset(
'Lower', n-1, n-1, czero, czero, b(2, 1), ldb )
341 nbmin = ilaenv( 2,
'CGGHD3',
' ', n, ilo, ihi, -1 )
342 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
346 nx = max( nb, ilaenv( 3,
'CGGHD3',
' ', n, ilo, ihi, -1 ) )
351 IF( lwork.LT.lwkopt )
THEN
357 nbmin = max( 2, ilaenv( 2,
'CGGHD3',
' ', n, ilo, ihi,
359 IF( lwork.GE.6*n*nbmin )
THEN
368 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
378 kacc22 = ilaenv( 16,
'CGGHD3',
' ', n, ilo, ihi, -1 )
380 DO jcol = ilo, ihi-2, nb
381 nnb = min( nb, ihi-jcol-1 )
389 n2nb = ( ihi-jcol-1 ) / nnb - 1
390 nblst = ihi - jcol - n2nb*nnb
391 CALL claset(
'All', nblst, nblst, czero, cone, work, nblst )
392 pw = nblst * nblst + 1
394 CALL claset(
'All', 2*nnb, 2*nnb, czero, cone,
395 $ work( pw ), 2*nnb )
401 DO j = jcol, jcol+nnb-1
408 CALL clartg( temp, a( i, j ), c, s, a( i-1, j ) )
409 a( i, j ) = cmplx( 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 ) = conjg( 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 ) = conjg( 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 - conjg( 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 clartg( temp, b( jj+1, jj ), c, s,
479 b( jj+1, jj ) = czero
480 CALL crot( jj-top, b( top+1, jj+1 ), 1,
481 $ b( top+1, jj ), 1, c, s )
482 a( jj+1, j ) = cmplx( c )
483 b( jj+1, j ) = -conjg( 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 + conjg( s2 )*temp2
504 temp2 = -s2*temp3 + c2*temp2
505 a( k, j+i+2 ) = c1*temp2 + conjg( s1 )*temp1
506 temp1 = -s1*temp2 + c1*temp1
507 a( k, j+i+1 ) = ctemp*temp1 + conjg( s )*temp
508 a( k, j+i ) = -s*temp1 + ctemp*temp
514 c = real( a( j+1+i, j ) )
515 CALL crot( ihi-top, a( top+1, j+i+1 ), 1,
516 $ a( top+1, j+i ), 1, c,
517 $ -conjg( b( j+1+i, j ) ) )
523 IF ( j .LT. jcol + nnb - 1 )
THEN
536 jrow = ihi - nblst + 1
537 CALL cgemv(
'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 ctrmv(
'Lower',
'Conjugate',
'Non-unit',
546 $ nblst-len, work( len*nblst + 1 ), nblst,
547 $ work( pw+len ), 1 )
548 CALL cgemv(
'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 ctrmv(
'Upper',
'Conjugate',
'Non-unit', len,
585 $ work( ppwo + nnb ), 2*nnb, work( pw ),
587 CALL ctrmv(
'Lower',
'Conjugate',
'Non-unit', nnb,
588 $ work( ppwo + 2*len*nnb ),
589 $ 2*nnb, work( pw + len ), 1 )
590 CALL cgemv(
'Conjugate', nnb, len, cone,
591 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
592 $ cone, work( pw ), 1 )
593 CALL cgemv(
'Conjugate', len, nnb, cone,
594 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
595 $ a( jrow+nnb, j+1 ), 1, cone,
596 $ work( pw+len ), 1 )
598 DO i = jrow, jrow+len+nnb-1
599 a( i, j+1 ) = work( ppw )
602 ppwo = ppwo + 4*nnb*nnb
609 cola = n - jcol - nnb + 1
611 CALL cgemm(
'Conjugate',
'No Transpose', nblst,
612 $ cola, nblst, cone, work, nblst,
613 $ a( j, jcol+nnb ), lda, czero, work( pw ),
615 CALL clacpy(
'All', nblst, cola, work( pw ), nblst,
616 $ a( j, jcol+nnb ), lda )
617 ppwo = nblst*nblst + 1
619 DO j = j0, jcol+1, -nnb
631 CALL cunm22(
'Left',
'Conjugate', 2*nnb, cola, nnb,
632 $ nnb, work( ppwo ), 2*nnb,
633 $ a( j, jcol+nnb ), lda, work( pw ),
639 CALL cgemm(
'Conjugate',
'No Transpose', 2*nnb,
640 $ cola, 2*nnb, cone, work( ppwo ), 2*nnb,
641 $ a( j, jcol+nnb ), lda, czero, work( pw ),
643 CALL clacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
644 $ a( j, jcol+nnb ), lda )
646 ppwo = ppwo + 4*nnb*nnb
654 topq = max( 2, j - jcol + 1 )
660 CALL cgemm(
'No Transpose',
'No Transpose', nh,
661 $ nblst, nblst, cone, q( topq, j ), ldq,
662 $ work, nblst, czero, work( pw ), nh )
663 CALL clacpy(
'All', nh, nblst, work( pw ), nh,
664 $ q( topq, j ), ldq )
665 ppwo = nblst*nblst + 1
667 DO j = j0, jcol+1, -nnb
669 topq = max( 2, j - jcol + 1 )
676 CALL cunm22(
'Right',
'No Transpose', nh, 2*nnb,
677 $ nnb, nnb, work( ppwo ), 2*nnb,
678 $ q( topq, j ), ldq, work( pw ),
684 CALL cgemm(
'No Transpose',
'No Transpose', nh,
685 $ 2*nnb, 2*nnb, cone, q( topq, j ), ldq,
686 $ work( ppwo ), 2*nnb, czero, work( pw ),
688 CALL clacpy(
'All', nh, 2*nnb, work( pw ), nh,
689 $ q( topq, j ), ldq )
691 ppwo = ppwo + 4*nnb*nnb
697 IF ( wantz .OR. top.GT.0 )
THEN
702 CALL claset(
'All', nblst, nblst, czero, cone, work,
704 pw = nblst * nblst + 1
706 CALL claset(
'All', 2*nnb, 2*nnb, czero, cone,
707 $ work( pw ), 2*nnb )
713 DO j = jcol, jcol+nnb-1
714 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
716 jrow = j + n2nb*nnb + 2
722 DO jj = ppw, ppw+len-1
723 temp = work( jj + nblst )
724 work( jj + nblst ) = ctemp*temp -
725 $ conjg( s )*work( jj )
726 work( jj ) = s*temp + ctemp*work( jj )
729 ppw = ppw - nblst - 1
732 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
734 DO jrow = j0, j+2, -nnb
737 DO i = jrow+nnb-1, jrow, -1
742 DO jj = ppw, ppw+len-1
743 temp = work( jj + 2*nnb )
744 work( jj + 2*nnb ) = ctemp*temp -
745 $ conjg( s )*work( jj )
746 work( jj ) = s*temp + ctemp*work( jj )
749 ppw = ppw - 2*nnb - 1
751 ppwo = ppwo + 4*nnb*nnb
756 CALL claset(
'Lower', ihi - jcol - 1, nnb, czero, czero,
757 $ a( jcol + 2, jcol ), lda )
758 CALL claset(
'Lower', ihi - jcol - 1, nnb, czero, czero,
759 $ b( jcol + 2, jcol ), ldb )
766 CALL cgemm(
'No Transpose',
'No Transpose', top,
767 $ nblst, nblst, cone, a( 1, j ), lda,
768 $ work, nblst, czero, work( pw ), top )
769 CALL clacpy(
'All', top, nblst, work( pw ), top,
771 ppwo = nblst*nblst + 1
773 DO j = j0, jcol+1, -nnb
778 CALL cunm22(
'Right',
'No Transpose', top, 2*nnb,
779 $ nnb, nnb, work( ppwo ), 2*nnb,
780 $ a( 1, j ), lda, work( pw ),
786 CALL cgemm(
'No Transpose',
'No Transpose', top,
787 $ 2*nnb, 2*nnb, cone, a( 1, j ), lda,
788 $ work( ppwo ), 2*nnb, czero,
790 CALL clacpy(
'All', top, 2*nnb, work( pw ), top,
793 ppwo = ppwo + 4*nnb*nnb
797 CALL cgemm(
'No Transpose',
'No Transpose', top,
798 $ nblst, nblst, cone, b( 1, j ), ldb,
799 $ work, nblst, czero, work( pw ), top )
800 CALL clacpy(
'All', top, nblst, work( pw ), top,
802 ppwo = nblst*nblst + 1
804 DO j = j0, jcol+1, -nnb
809 CALL cunm22(
'Right',
'No Transpose', top, 2*nnb,
810 $ nnb, nnb, work( ppwo ), 2*nnb,
811 $ b( 1, j ), ldb, work( pw ),
817 CALL cgemm(
'No Transpose',
'No Transpose', top,
818 $ 2*nnb, 2*nnb, cone, b( 1, j ), ldb,
819 $ work( ppwo ), 2*nnb, czero,
821 CALL clacpy(
'All', top, 2*nnb, work( pw ), top,
824 ppwo = ppwo + 4*nnb*nnb
833 topq = max( 2, j - jcol + 1 )
839 CALL cgemm(
'No Transpose',
'No Transpose', nh,
840 $ nblst, nblst, cone, z( topq, j ), ldz,
841 $ work, nblst, czero, work( pw ), nh )
842 CALL clacpy(
'All', nh, nblst, work( pw ), nh,
843 $ z( topq, j ), ldz )
844 ppwo = nblst*nblst + 1
846 DO j = j0, jcol+1, -nnb
848 topq = max( 2, j - jcol + 1 )
855 CALL cunm22(
'Right',
'No Transpose', nh, 2*nnb,
856 $ nnb, nnb, work( ppwo ), 2*nnb,
857 $ z( topq, j ), ldz, work( pw ),
863 CALL cgemm(
'No Transpose',
'No Transpose', nh,
864 $ 2*nnb, 2*nnb, cone, z( topq, j ), ldz,
865 $ work( ppwo ), 2*nnb, czero, work( pw ),
867 CALL clacpy(
'All', nh, 2*nnb, work( pw ), nh,
868 $ z( topq, j ), ldz )
870 ppwo = ppwo + 4*nnb*nnb
881 IF ( jcol.NE.ilo )
THEN
889 $
CALL cgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb, q,
890 $ ldq, z, ldz, ierr )
891 work( 1 ) = cmplx( lwkopt )
subroutine xerbla(srname, info)
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
subroutine cgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
CGGHD3
subroutine cgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
CGGHRD
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
subroutine clartg(f, g, c, s, r)
CLARTG generates a plane rotation with real cosine and complex sine.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine crot(n, cx, incx, cy, incy, c, s)
CROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
subroutine ctrmv(uplo, trans, diag, n, a, lda, x, incx)
CTRMV
subroutine cunm22(side, trans, m, n, n1, n2, q, ldq, c, ldc, work, lwork, info)
CUNM22 multiplies a general matrix by a banded unitary matrix.