361 SUBROUTINE sggesx( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
362 $ B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
363 $ VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,
364 $ LIWORK, BWORK, INFO )
371 CHARACTER JOBVSL, JOBVSR, SENSE, SORT
372 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
378 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
379 $ b( ldb, * ), beta( * ), rconde( 2 ),
380 $ rcondv( 2 ), vsl( ldvsl, * ), vsr( ldvsr, * ),
392 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
395 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
396 $ LQUERY, LST2SL, WANTSB, WANTSE, WANTSN, WANTST,
398 INTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
399 $ ILEFT, ILO, IP, IRIGHT, IROWS, ITAU, IWRK,
400 $ LIWMIN, LWRK, MAXWRK, MINWRK
401 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
402 $ PR, SAFMAX, SAFMIN, SMLNUM
414 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
415 EXTERNAL lsame, ilaenv, slamch, slange, sroundup_lwork
418 INTRINSIC abs, max, sqrt
424 IF( lsame( jobvsl,
'N' ) )
THEN
427 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
435 IF( lsame( jobvsr,
'N' ) )
THEN
438 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
446 wantst = lsame( sort,
'S' )
447 wantsn = lsame( sense,
'N' )
448 wantse = lsame( sense,
'E' )
449 wantsv = lsame( sense,
'V' )
450 wantsb = lsame( sense,
'B' )
451 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
454 ELSE IF( wantse )
THEN
456 ELSE IF( wantsv )
THEN
458 ELSE IF( wantsb )
THEN
465 IF( ijobvl.LE.0 )
THEN
467 ELSE IF( ijobvr.LE.0 )
THEN
469 ELSE IF( ( .NOT.wantst ) .AND. ( .NOT.lsame( sort,
'N' ) ) )
THEN
471 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsv .OR. wantsb ) .OR.
472 $ ( .NOT.wantst .AND. .NOT.wantsn ) )
THEN
474 ELSE IF( n.LT.0 )
THEN
476 ELSE IF( lda.LT.max( 1, n ) )
THEN
478 ELSE IF( ldb.LT.max( 1, n ) )
THEN
480 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
482 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
495 minwrk = max( 8*n, 6*n + 16 )
496 maxwrk = minwrk - n +
497 $ n*ilaenv( 1,
'SGEQRF',
' ', n, 1, n, 0 )
498 maxwrk = max( maxwrk, minwrk - n +
499 $ n*ilaenv( 1,
'SORMQR',
' ', n, 1, n, -1 ) )
501 maxwrk = max( maxwrk, minwrk - n +
502 $ n*ilaenv( 1,
'SORGQR',
' ', n, 1, n, -1 ) )
506 $ lwrk = max( lwrk, n*n/2 )
512 work( 1 ) = sroundup_lwork(lwrk)
513 IF( wantsn .OR. n.EQ.0 )
THEN
520 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
522 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
528 CALL xerbla(
'SGGESX', -info )
530 ELSE IF (lquery)
THEN
544 safmin = slamch(
'S' )
545 safmax = one / safmin
546 smlnum = sqrt( safmin ) / eps
547 bignum = one / smlnum
551 anrm = slange(
'M', n, n, a, lda, work )
553 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
556 ELSE IF( anrm.GT.bignum )
THEN
561 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
565 bnrm = slange(
'M', n, n, b, ldb, work )
567 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
570 ELSE IF( bnrm.GT.bignum )
THEN
575 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
583 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
584 $ work( iright ), work( iwrk ), ierr )
589 irows = ihi + 1 - ilo
593 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
594 $ work( iwrk ), lwork+1-iwrk, ierr )
599 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
600 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
601 $ lwork+1-iwrk, ierr )
607 CALL slaset(
'Full', n, n, zero, one, vsl, ldvsl )
608 IF( irows.GT.1 )
THEN
609 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
610 $ vsl( ilo+1, ilo ), ldvsl )
612 CALL sorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
613 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
619 $
CALL slaset(
'Full', n, n, zero, one, vsr, ldvsr )
624 CALL sgghrd( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
625 $ ldvsl, vsr, ldvsr, ierr )
633 CALL shgeqz(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
634 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
635 $ work( iwrk ), lwork+1-iwrk, ierr )
637 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
639 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
657 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
659 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
663 $
CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
668 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
674 CALL stgsen( ijob, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
675 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
676 $ sdim, pl, pr, dif, work( iwrk ), lwork-iwrk+1,
677 $ iwork, liwork, ierr )
680 $ maxwrk = max( maxwrk, 2*sdim*( n-sdim ) )
681 IF( ierr.EQ.-22 )
THEN
687 IF( ijob.EQ.1 .OR. ijob.EQ.4 )
THEN
691 IF( ijob.EQ.2 .OR. ijob.EQ.4 )
THEN
692 rcondv( 1 ) = dif( 1 )
693 rcondv( 2 ) = dif( 2 )
705 $
CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
706 $ work( iright ), n, vsl, ldvsl, ierr )
709 $
CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
710 $ work( iright ), n, vsr, ldvsr, ierr )
718 IF( alphai( i ).NE.zero )
THEN
719 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
720 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
722 work( 1 ) = abs( a( i, i ) / alphar( i ) )
723 beta( i ) = beta( i )*work( 1 )
724 alphar( i ) = alphar( i )*work( 1 )
725 alphai( i ) = alphai( i )*work( 1 )
726 ELSE IF( ( alphai( i ) / safmax ).GT.( anrmto / anrm )
727 $ .OR. ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
729 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
730 beta( i ) = beta( i )*work( 1 )
731 alphar( i ) = alphar( i )*work( 1 )
732 alphai( i ) = alphai( i )*work( 1 )
740 IF( alphai( i ).NE.zero )
THEN
741 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
742 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
743 work( 1 ) = abs( b( i, i ) / beta( i ) )
744 beta( i ) = beta( i )*work( 1 )
745 alphar( i ) = alphar( i )*work( 1 )
746 alphai( i ) = alphai( i )*work( 1 )
755 CALL slascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
756 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
757 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
761 CALL slascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
762 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
774 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
775 IF( alphai( i ).EQ.zero )
THEN
779 IF( cursl .AND. .NOT.lastsl )
786 cursl = cursl .OR. lastsl
791 IF( cursl .AND. .NOT.lst2sl )
808 work( 1 ) = sroundup_lwork(maxwrk)
subroutine xerbla(srname, info)
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
subroutine sggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
SGGBAK
subroutine sggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
SGGBAL
subroutine sggesx(jobvsl, jobvsr, sort, selctg, sense, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, rconde, rcondv, work, lwork, iwork, liwork, bwork, info)
SGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...
subroutine sgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
SGGHRD
subroutine shgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
SHGEQZ
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
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 sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR