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, * ),
240 $ z( ldz, * ), work( * )
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.1 .AND. .NOT.lquery )
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
425 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
427 DO jrow = j0, j+2, -nnb
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
664 topq = max( 2, j - jcol + 1 )
671 CALL zunm22(
'Right',
'No Transpose', nh, 2*nnb,
672 $ nnb, nnb, work( ppwo ), 2*nnb,
673 $ q( topq, j ), ldq, work( pw ),
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 )
subroutine xerbla(srname, info)
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
subroutine zgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
ZGGHD3
subroutine zgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
ZGGHRD
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlartg(f, g, c, s, r)
ZLARTG generates a plane rotation with real cosine and complex sine.
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zrot(n, cx, incx, cy, incy, c, s)
ZROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
subroutine ztrmv(uplo, trans, diag, n, a, lda, x, incx)
ZTRMV
subroutine zunm22(side, trans, m, n, n1, n2, q, ldq, c, ldc, work, lwork, info)
ZUNM22 multiplies a general matrix by a banded unitary matrix.