448 SUBROUTINE stgsen( 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,
465 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
466 $ b( ldb, * ), beta( * ), dif( * ), q( ldq, * ),
467 $ work( * ), z( ldz, * )
474 PARAMETER ( IDIFJB = 3 )
476 parameter( zero = 0.0e+0, one = 1.0e+0 )
479 LOGICAL LQUERY, PAIR, SWAP, WANTD, WANTD1, WANTD2,
481 INTEGER I, IERR, IJB, K, KASE, KK, KS, LIWMIN, LWMIN,
483 REAL DSCALE, DSUM, EPS, RDSCAL, SMLNUM
493 REAL SLAMCH, SROUNDUP_LWORK
494 EXTERNAL SLAMCH, SROUNDUP_LWORK
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(
'STGSEN', -info )
528 smlnum = slamch(
'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 )
574 work( 1 ) = sroundup_lwork(lwmin)
577 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
579 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
584 CALL xerbla(
'STGSEN', -info )
586 ELSE IF( lquery )
THEN
592 IF( m.EQ.n .OR. m.EQ.0 )
THEN
601 CALL slassq( n, a( 1, i ), 1, dscale, dsum )
602 CALL slassq( 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 stgexc( wantq, wantz, n, a, lda, b, ldb, q, ldq,
638 $ z, ldz, kk, ks, work, lwork, ierr )
670 CALL slacpy(
'Full', n1, n2, a( 1, i ), lda, work, n1 )
671 CALL slacpy(
'Full', n1, n2, b( 1, i ), ldb, work( n1*n2+1 ),
673 CALL stgsyl(
'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 slassq( 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 slassq( 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 stgsyl(
'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 stgsyl(
'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 slacn2( mn2, work( mn2+1 ), work, iwork, dif( 1 ),
749 CALL stgsyl(
'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 stgsyl(
'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 slacn2( mn2, work( mn2+1 ), work, iwork, dif( 2 ),
778 CALL stgsyl(
'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 stgsyl(
'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 slag2( 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 )
855 work( 1 ) = sroundup_lwork(lwmin)
subroutine xerbla(srname, info)
subroutine slacn2(n, v, x, isgn, est, kase, isave)
SLACN2 estimates the 1-norm of a square matrix, using reverse communication for evaluating matrix-vec...
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slag2(a, lda, b, ldb, safmin, scale1, scale2, wr1, wr2, wi)
SLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary ...
subroutine slassq(n, x, incx, scale, sumsq)
SLASSQ updates a sum of squares represented in scaled form.
subroutine stgexc(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, ifst, ilst, work, lwork, info)
STGEXC
subroutine stgsen(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)
STGSEN
subroutine stgsyl(trans, ijob, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, dif, work, lwork, iwork, info)
STGSYL