451 SUBROUTINE dtgsen( IJOB, WANTQ, WANTZ, SELECT, N, A, LDA, B, LDB,
452 $ alphar, alphai, beta, q, ldq, z, ldz, m, pl,
453 $ pr, dif, work, lwork, iwork, liwork, info )
462 INTEGER IJOB, INFO, LDA, LDB, LDQ, LDZ, LIWORK, LWORK,
464 DOUBLE PRECISION PL, PR
469 DOUBLE PRECISION A( lda, * ), ALPHAI( * ), ALPHAR( * ),
470 $ b( ldb, * ), beta( * ), dif( * ), q( ldq, * ),
471 $ work( * ), z( ldz, * )
478 parameter ( idifjb = 3 )
479 DOUBLE PRECISION ZERO, ONE
480 parameter ( zero = 0.0d+0, one = 1.0d+0 )
483 LOGICAL LQUERY, PAIR, SWAP, WANTD, WANTD1, WANTD2,
485 INTEGER I, IERR, IJB, K, KASE, KK, KS, LIWMIN, LWMIN,
487 DOUBLE PRECISION DSCALE, DSUM, EPS, RDSCAL, SMLNUM
497 DOUBLE PRECISION DLAMCH
501 INTRINSIC max, sign, sqrt
508 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
510 IF( ijob.LT.0 .OR. ijob.GT.5 )
THEN
512 ELSE IF( n.LT.0 )
THEN
514 ELSE IF( lda.LT.max( 1, n ) )
THEN
516 ELSE IF( ldb.LT.max( 1, n ) )
THEN
518 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN
520 ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) )
THEN
525 CALL xerbla(
'DTGSEN', -info )
532 smlnum = dlamch(
'S' ) / eps
535 wantp = ijob.EQ.1 .OR. ijob.GE.4
536 wantd1 = ijob.EQ.2 .OR. ijob.EQ.4
537 wantd2 = ijob.EQ.3 .OR. ijob.EQ.5
538 wantd = wantd1 .OR. wantd2
545 IF( .NOT.lquery .OR. ijob.NE.0 )
THEN
551 IF( a( k+1, k ).EQ.zero )
THEN
556 IF(
SELECT( k ) .OR.
SELECT( k+1 ) )
567 IF( ijob.EQ.1 .OR. ijob.EQ.2 .OR. ijob.EQ.4 )
THEN
568 lwmin = max( 1, 4*n+16, 2*m*( n-m ) )
569 liwmin = max( 1, n+6 )
570 ELSE IF( ijob.EQ.3 .OR. ijob.EQ.5 )
THEN
571 lwmin = max( 1, 4*n+16, 4*m*( n-m ) )
572 liwmin = max( 1, 2*m*( n-m ), n+6 )
574 lwmin = max( 1, 4*n+16 )
581 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
583 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
588 CALL xerbla(
'DTGSEN', -info )
590 ELSE IF( lquery )
THEN
596 IF( m.EQ.n .OR. m.EQ.0 )
THEN
605 CALL dlassq( n, a( 1, i ), 1, dscale, dsum )
606 CALL dlassq( n, b( 1, i ), 1, dscale, dsum )
608 dif( 1 ) = dscale*sqrt( dsum )
625 IF( a( k+1, k ).NE.zero )
THEN
627 swap = swap .OR.
SELECT( k+1 )
641 $
CALL dtgexc( wantq, wantz, n, a, lda, b, ldb, q, ldq,
642 $ z, ldz, kk, ks, work, lwork, ierr )
674 CALL dlacpy(
'Full', n1, n2, a( 1, i ), lda, work, n1 )
675 CALL dlacpy(
'Full', n1, n2, b( 1, i ), ldb, work( n1*n2+1 ),
677 CALL dtgsyl(
'N', ijb, n1, n2, a, lda, a( i, i ), lda, work,
678 $ n1, b, ldb, b( i, i ), ldb, work( n1*n2+1 ), n1,
679 $ dscale, dif( 1 ), work( n1*n2*2+1 ),
680 $ lwork-2*n1*n2, iwork, ierr )
687 CALL dlassq( n1*n2, work, 1, rdscal, dsum )
688 pl = rdscal*sqrt( dsum )
689 IF( pl.EQ.zero )
THEN
692 pl = dscale / ( sqrt( dscale*dscale / pl+pl )*sqrt( pl ) )
696 CALL dlassq( n1*n2, work( n1*n2+1 ), 1, rdscal, dsum )
697 pr = rdscal*sqrt( dsum )
698 IF( pr.EQ.zero )
THEN
701 pr = dscale / ( sqrt( dscale*dscale / pr+pr )*sqrt( pr ) )
717 CALL dtgsyl(
'N', ijb, n1, n2, a, lda, a( i, i ), lda, work,
718 $ n1, b, ldb, b( i, i ), ldb, work( n1*n2+1 ),
719 $ n1, dscale, dif( 1 ), work( 2*n1*n2+1 ),
720 $ lwork-2*n1*n2, iwork, ierr )
724 CALL dtgsyl(
'N', ijb, n2, n1, a( i, i ), lda, a, lda, work,
725 $ n2, b( i, i ), ldb, b, ldb, work( n1*n2+1 ),
726 $ n2, dscale, dif( 2 ), work( 2*n1*n2+1 ),
727 $ lwork-2*n1*n2, iwork, ierr )
746 CALL dlacn2( mn2, work( mn2+1 ), work, iwork, dif( 1 ),
753 CALL dtgsyl(
'N', ijb, n1, n2, a, lda, a( i, i ), lda,
754 $ work, n1, b, ldb, b( i, i ), ldb,
755 $ work( n1*n2+1 ), n1, dscale, dif( 1 ),
756 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
762 CALL dtgsyl(
'T', ijb, n1, n2, a, lda, a( i, i ), lda,
763 $ work, n1, b, ldb, b( i, i ), ldb,
764 $ work( n1*n2+1 ), n1, dscale, dif( 1 ),
765 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
770 dif( 1 ) = dscale / dif( 1 )
775 CALL dlacn2( mn2, work( mn2+1 ), work, iwork, dif( 2 ),
782 CALL dtgsyl(
'N', ijb, n2, n1, a( i, i ), lda, a, lda,
783 $ work, n2, b( i, i ), ldb, b, ldb,
784 $ work( n1*n2+1 ), n2, dscale, dif( 2 ),
785 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
791 CALL dtgsyl(
'T', ijb, n2, n1, a( i, i ), lda, a, lda,
792 $ work, n2, b( i, i ), ldb, b, ldb,
793 $ work( n1*n2+1 ), n2, dscale, dif( 2 ),
794 $ work( 2*n1*n2+1 ), lwork-2*n1*n2, iwork,
799 dif( 2 ) = dscale / dif( 2 )
816 IF( a( k+1, k ).NE.zero )
THEN
825 work( 1 ) = a( k, k )
826 work( 2 ) = a( k+1, k )
827 work( 3 ) = a( k, k+1 )
828 work( 4 ) = a( k+1, k+1 )
829 work( 5 ) = b( k, k )
830 work( 6 ) = b( k+1, k )
831 work( 7 ) = b( k, k+1 )
832 work( 8 ) = b( k+1, k+1 )
833 CALL dlag2( work, 2, work( 5 ), 2, smlnum*eps, beta( k ),
834 $ beta( k+1 ), alphar( k ), alphar( k+1 ),
836 alphai( k+1 ) = -alphai( k )
840 IF( sign( one, b( k, k ) ).LT.zero )
THEN
845 a( k, i ) = -a( k, i )
846 b( k, i ) = -b( k, i )
847 IF( wantq ) q( i, k ) = -q( i, k )
851 alphar( k ) = a( k, k )
853 beta( k ) = b( k, k )
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine xerbla(SRNAME, INFO)
XERBLA
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 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 dlassq(N, X, INCX, SCALE, SUMSQ)
DLASSQ updates a sum of squares represented in scaled form.
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
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...