361 SUBROUTINE dggesx( 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 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
379 $ b( ldb, * ), beta( * ), rconde( 2 ),
380 $ rcondv( 2 ), vsl( ldvsl, * ), vsr( ldvsr, * ),
391 DOUBLE PRECISION ZERO, ONE
392 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+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 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
402 $ PR, SAFMAX, SAFMIN, SMLNUM
405 DOUBLE PRECISION DIF( 2 )
414 DOUBLE PRECISION DLAMCH, DLANGE
415 EXTERNAL lsame, ilaenv, dlamch, dlange
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,
'DGEQRF',
' ', n, 1, n, 0 )
498 maxwrk = max( maxwrk, minwrk - n +
499 $ n*ilaenv( 1,
'DORMQR',
' ', n, 1, n, -1 ) )
501 maxwrk = max( maxwrk, minwrk - n +
502 $ n*ilaenv( 1,
'DORGQR',
' ', n, 1, n, -1 ) )
506 $ lwrk = max( lwrk, n*n/2 )
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(
'DGGESX', -info )
530 ELSE IF (lquery)
THEN
544 safmin = dlamch(
'S' )
545 safmax = one / safmin
546 smlnum = sqrt( safmin ) / eps
547 bignum = one / smlnum
551 anrm = dlange(
'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 dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
565 bnrm = dlange(
'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 dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
583 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
584 $ work( iright ), work( iwrk ), ierr )
589 irows = ihi + 1 - ilo
593 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
594 $ work( iwrk ), lwork+1-iwrk, ierr )
599 CALL dormqr(
'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 dlaset(
'Full', n, n, zero, one, vsl, ldvsl )
608 IF( irows.GT.1 )
THEN
609 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
610 $ vsl( ilo+1, ilo ), ldvsl )
612 CALL dorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
613 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
619 $
CALL dlaset(
'Full', n, n, zero, one, vsr, ldvsr )
624 CALL dgghrd( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
625 $ ldvsl, vsr, ldvsr, ierr )
633 CALL dhgeqz(
'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 dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
659 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
663 $
CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
668 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
674 CALL dtgsen( 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 dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
706 $ work( iright ), n, vsl, ldvsl, ierr )
709 $
CALL dggbak(
'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 ) )
THEN
721 work( 1 ) = abs( a( i, i ) / alphar( i ) )
722 beta( i ) = beta( i )*work( 1 )
723 alphar( i ) = alphar( i )*work( 1 )
724 alphai( i ) = alphai( i )*work( 1 )
725 ELSE IF( ( alphai( i ) / safmax ).GT.
726 $ ( anrmto / anrm ) .OR.
727 $ ( 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 dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
756 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
757 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
761 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
762 CALL dlascl(
'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 )
subroutine xerbla(srname, info)
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
DGGBAK
subroutine dggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
DGGBAL
subroutine dggesx(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)
DGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...
subroutine dgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
DGGHRD
subroutine dhgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
DHGEQZ
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
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 dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR