448 SUBROUTINE dtgsen( IJOB, WANTQ, WANTZ, SELECT, N, A, LDA, B, LDB,
449 $ ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, M, PL,
450 $ PR, DIF, WORK, LWORK, IWORK, LIWORK, INFO )
458 INTEGER IJOB, INFO, LDA, LDB, LDQ, LDZ, LIWORK, LWORK,
460 DOUBLE PRECISION PL, PR
465 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
466 $ b( ldb, * ), beta( * ), dif( * ), q( ldq, * ),
467 $ work( * ), z( ldz, * )
474 PARAMETER ( IDIFJB = 3 )
475 DOUBLE PRECISION ZERO, ONE
476 parameter( zero = 0.0d+0, one = 1.0d+0 )
479 LOGICAL LQUERY, PAIR, SWAP, WANTD, WANTD1, WANTD2,
481 INTEGER I, IERR, IJB, K, KASE, KK, KS, LIWMIN, LWMIN,
483 DOUBLE PRECISION DSCALE, DSUM, EPS, RDSCAL, SMLNUM
493 DOUBLE PRECISION DLAMCH
497 INTRINSIC max, sign, sqrt
504 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
506 IF( ijob.LT.0 .OR. ijob.GT.5 )
THEN
508 ELSE IF( n.LT.0 )
THEN
510 ELSE IF( lda.LT.max( 1, n ) )
THEN
512 ELSE IF( ldb.LT.max( 1, n ) )
THEN
514 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN
516 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
521 CALL xerbla(
'DTGSEN', -info )
528 smlnum = dlamch(
'S' ) / eps
531 wantp = ijob.EQ.1 .OR. ijob.GE.4
532 wantd1 = ijob.EQ.2 .OR. ijob.EQ.4
533 wantd2 = ijob.EQ.3 .OR. ijob.EQ.5
534 wantd = wantd1 .OR. wantd2
541 IF( .NOT.lquery .OR. ijob.NE.0 )
THEN
547 IF( a( k+1, k ).EQ.zero )
THEN
552 IF(
SELECT( k ) .OR.
SELECT( k+1 ) )
563 IF( ijob.EQ.1 .OR. ijob.EQ.2 .OR. ijob.EQ.4 )
THEN
564 lwmin = max( 1, 4*n+16, 2*m*( n-m ) )
565 liwmin = max( 1, n+6 )
566 ELSE IF( ijob.EQ.3 .OR. ijob.EQ.5 )
THEN
567 lwmin = max( 1, 4*n+16, 4*m*( n-m ) )
568 liwmin = max( 1, 2*m*( n-m ), n+6 )
570 lwmin = max( 1, 4*n+16 )
577 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
579 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
584 CALL xerbla(
'DTGSEN', -info )
586 ELSE IF( lquery )
THEN
592 IF( m.EQ.n .OR. m.EQ.0 )
THEN
601 CALL dlassq( n, a( 1, i ), 1, dscale, dsum )
602 CALL dlassq( n, b( 1, i ), 1, dscale, dsum )
604 dif( 1 ) = dscale*sqrt( dsum )
621 IF( a( k+1, k ).NE.zero )
THEN
623 swap = swap .OR.
SELECT( k+1 )
637 $
CALL dtgexc( wantq, wantz, n, a, lda, b, ldb, q, ldq,
638 $ z, ldz, kk, ks, work, lwork, ierr )
670 CALL dlacpy(
'Full', n1, n2, a( 1, i ), lda, work, n1 )
671 CALL dlacpy(
'Full', n1, n2, b( 1, i ), ldb, work( n1*n2+1 ),
673 CALL dtgsyl(
'N', ijb, n1, n2, a, lda, a( i, i ), lda, work,
674 $ n1, b, ldb, b( i, i ), ldb, work( n1*n2+1 ), n1,
675 $ dscale, dif( 1 ), work( n1*n2*2+1 ),
676 $ lwork-2*n1*n2, iwork, ierr )
683 CALL dlassq( n1*n2, work, 1, rdscal, dsum )
684 pl = rdscal*sqrt( dsum )
685 IF( pl.EQ.zero )
THEN
688 pl = dscale / ( sqrt( dscale*dscale / pl+pl )*sqrt( pl ) )
692 CALL dlassq( n1*n2, work( n1*n2+1 ), 1, rdscal, dsum )
693 pr = rdscal*sqrt( dsum )
694 IF( pr.EQ.zero )
THEN
697 pr = dscale / ( sqrt( dscale*dscale / pr+pr )*sqrt( pr ) )
713 CALL dtgsyl(
'N', ijb, n1, n2, a, lda, a( i, i ), lda, work,
714 $ n1, b, ldb, b( i, i ), ldb, work( n1*n2+1 ),
715 $ n1, dscale, dif( 1 ), work( 2*n1*n2+1 ),
716 $ lwork-2*n1*n2, iwork, ierr )
720 CALL dtgsyl(
'N', ijb, n2, n1, a( i, i ), lda, a, lda, work,
721 $ n2, b( i, i ), ldb, b, ldb, work( n1*n2+1 ),
722 $ n2, dscale, dif( 2 ), work( 2*n1*n2+1 ),
723 $ lwork-2*n1*n2, iwork, ierr )
742 CALL dlacn2( mn2, work( mn2+1 ), work, iwork, dif( 1 ),
749 CALL dtgsyl(
'N', ijb, n1, n2, a, lda, a( i, i ), lda,
750 $ work, n1, b, ldb, b( i, i ), ldb,
751 $ work( n1*n2+1 ), n1, dscale, dif( 1 ),
752 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
758 CALL dtgsyl(
'T', ijb, n1, n2, a, lda, a( i, i ), lda,
759 $ work, n1, b, ldb, b( i, i ), ldb,
760 $ work( n1*n2+1 ), n1, dscale, dif( 1 ),
761 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
766 dif( 1 ) = dscale / dif( 1 )
771 CALL dlacn2( mn2, work( mn2+1 ), work, iwork, dif( 2 ),
778 CALL dtgsyl(
'N', ijb, n2, n1, a( i, i ), lda, a, lda,
779 $ work, n2, b( i, i ), ldb, b, ldb,
780 $ work( n1*n2+1 ), n2, dscale, dif( 2 ),
781 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
787 CALL dtgsyl(
'T', ijb, n2, n1, a( i, i ), lda, a, lda,
788 $ work, n2, b( i, i ), ldb, b, ldb,
789 $ work( n1*n2+1 ), n2, dscale, dif( 2 ),
790 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
795 dif( 2 ) = dscale / dif( 2 )
812 IF( a( k+1, k ).NE.zero )
THEN
821 work( 1 ) = a( k, k )
822 work( 2 ) = a( k+1, k )
823 work( 3 ) = a( k, k+1 )
824 work( 4 ) = a( k+1, k+1 )
825 work( 5 ) = b( k, k )
826 work( 6 ) = b( k+1, k )
827 work( 7 ) = b( k, k+1 )
828 work( 8 ) = b( k+1, k+1 )
829 CALL dlag2( work, 2, work( 5 ), 2, smlnum*eps, beta( k ),
830 $ beta( k+1 ), alphar( k ), alphar( k+1 ),
832 alphai( k+1 ) = -alphai( k )
836 IF( sign( one, b( k, k ) ).LT.zero )
THEN
841 a( k, i ) = -a( k, i )
842 b( k, i ) = -b( k, i )
843 IF( wantq ) q( i, k ) = -q( i, k )
847 alphar( k ) = a( k, k )
849 beta( k ) = b( k, k )
subroutine xerbla(srname, info)
subroutine dlacn2(n, v, x, isgn, est, kase, isave)
DLACN2 estimates the 1-norm of a square matrix, using reverse communication for evaluating matrix-vec...
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlag2(a, lda, b, ldb, safmin, scale1, scale2, wr1, wr2, wi)
DLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary ...
subroutine dlassq(n, x, incx, scale, sumsq)
DLASSQ updates a sum of squares represented in scaled form.
subroutine dtgexc(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, ifst, ilst, work, lwork, info)
DTGEXC
subroutine dtgsen(ijob, wantq, wantz, select, n, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, m, pl, pr, dif, work, lwork, iwork, liwork, info)
DTGSEN
subroutine dtgsyl(trans, ijob, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, dif, work, lwork, iwork, info)
DTGSYL