281 SUBROUTINE dgges( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB,
282 $ SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR,
283 $ LDVSR, WORK, LWORK, BWORK, INFO )
290 CHARACTER JOBVSL, JOBVSR, SORT
291 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
295 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
296 $ b( ldb, * ), beta( * ), vsl( ldvsl, * ),
297 $ vsr( ldvsr, * ), work( * )
307 DOUBLE PRECISION ZERO, ONE
308 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
311 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
312 $ LQUERY, LST2SL, WANTST
313 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
314 $ ILO, IP, IRIGHT, IROWS, ITAU, IWRK, MAXWRK,
316 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
317 $ PVSR, SAFMAX, SAFMIN, SMLNUM
321 DOUBLE PRECISION DIF( 2 )
331 DOUBLE PRECISION DLAMCH, DLANGE
332 EXTERNAL lsame, ilaenv, dlamch, dlange
335 INTRINSIC abs, max, sqrt
341 IF( lsame( jobvsl,
'N' ) )
THEN
344 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
352 IF( lsame( jobvsr,
'N' ) )
THEN
355 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
363 wantst = lsame( sort,
'S' )
368 lquery = ( lwork.EQ.-1 )
369 IF( ijobvl.LE.0 )
THEN
371 ELSE IF( ijobvr.LE.0 )
THEN
373 ELSE IF( ( .NOT.wantst ) .AND. ( .NOT.lsame( sort,
'N' ) ) )
THEN
375 ELSE IF( n.LT.0 )
THEN
377 ELSE IF( lda.LT.max( 1, n ) )
THEN
379 ELSE IF( ldb.LT.max( 1, n ) )
THEN
381 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
383 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
396 minwrk = max( 8*n, 6*n + 16 )
397 maxwrk = minwrk - n +
398 $ n*ilaenv( 1,
'DGEQRF',
' ', n, 1, n, 0 )
399 maxwrk = max( maxwrk, minwrk - n +
400 $ n*ilaenv( 1,
'DORMQR',
' ', n, 1, n, -1 ) )
402 maxwrk = max( maxwrk, minwrk - n +
403 $ n*ilaenv( 1,
'DORGQR',
' ', n, 1, n, -1 ) )
411 IF( lwork.LT.minwrk .AND. .NOT.lquery )
416 CALL xerbla(
'DGGES ', -info )
418 ELSE IF( lquery )
THEN
432 safmin = dlamch(
'S' )
433 safmax = one / safmin
434 CALL dlabad( safmin, safmax )
435 smlnum = sqrt( safmin ) / eps
436 bignum = one / smlnum
440 anrm = dlange(
'M', n, n, a, lda, work )
442 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
445 ELSE IF( anrm.GT.bignum )
THEN
450 $
CALL dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
454 bnrm = dlange(
'M', n, n, b, ldb, work )
456 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
459 ELSE IF( bnrm.GT.bignum )
THEN
464 $
CALL dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
472 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
473 $ work( iright ), work( iwrk ), ierr )
478 irows = ihi + 1 - ilo
482 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
483 $ work( iwrk ), lwork+1-iwrk, ierr )
488 CALL dormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
489 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
490 $ lwork+1-iwrk, ierr )
496 CALL dlaset(
'Full', n, n, zero, one, vsl, ldvsl )
497 IF( irows.GT.1 )
THEN
498 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
499 $ vsl( ilo+1, ilo ), ldvsl )
501 CALL dorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
502 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
508 $
CALL dlaset(
'Full', n, n, zero, one, vsr, ldvsr )
513 CALL dgghrd( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
514 $ ldvsl, vsr, ldvsr, ierr )
520 CALL dhgeqz(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
521 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
522 $ work( iwrk ), lwork+1-iwrk, ierr )
524 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
526 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
543 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
545 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
549 $
CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
554 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
557 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb, alphar,
558 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
559 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
570 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
571 $ work( iright ), n, vsl, ldvsl, ierr )
574 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
575 $ work( iright ), n, vsr, ldvsr, ierr )
583 IF( alphai( i ).NE.zero )
THEN
584 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
585 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN
586 work( 1 ) = abs( a( i, i ) / alphar( i ) )
587 beta( i ) = beta( i )*work( 1 )
588 alphar( i ) = alphar( i )*work( 1 )
589 alphai( i ) = alphai( i )*work( 1 )
590 ELSE IF( ( alphai( i ) / safmax ).GT.
591 $ ( anrmto / anrm ) .OR.
592 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
594 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
595 beta( i ) = beta( i )*work( 1 )
596 alphar( i ) = alphar( i )*work( 1 )
597 alphai( i ) = alphai( i )*work( 1 )
605 IF( alphai( i ).NE.zero )
THEN
606 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
607 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
608 work( 1 ) = abs( b( i, i ) / beta( i ) )
609 beta( i ) = beta( i )*work( 1 )
610 alphar( i ) = alphar( i )*work( 1 )
611 alphai( i ) = alphai( i )*work( 1 )
620 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
621 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
622 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
626 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
627 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
639 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
640 IF( alphai( i ).EQ.zero )
THEN
644 IF( cursl .AND. .NOT.lastsl )
651 cursl = cursl .OR. lastsl
656 IF( cursl .AND. .NOT.lst2sl )
subroutine dlabad(SMALL, LARGE)
DLABAD
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 dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
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 xerbla(SRNAME, INFO)
XERBLA
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 dhgeqz(JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
DHGEQZ
subroutine dgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGEQRF
subroutine dgges(JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, WORK, LWORK, BWORK, INFO)
DGGES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE m...
subroutine dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGQR
subroutine dgghrd(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, INFO)
DGGHRD
subroutine dormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMQR
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