281 SUBROUTINE dgges3( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B,
282 $ LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
283 $ VSR, LDVSR, WORK, LWORK, BWORK, INFO )
291 CHARACTER JOBVSL, JOBVSR, SORT
292 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
296 DOUBLE PRECISION A( lda, * ), ALPHAI( * ), ALPHAR( * ),
297 $ b( ldb, * ), beta( * ), vsl( ldvsl, * ),
298 $ vsr( ldvsr, * ), work( * )
308 DOUBLE PRECISION ZERO, ONE
309 parameter( zero = 0.0d+0, one = 1.0d+0 )
312 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
313 $ lquery, lst2sl, wantst
314 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
315 $ ilo, ip, iright, irows, itau, iwrk, lwkopt
316 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
317 $ pvsr, safmax, safmin, smlnum
321 DOUBLE PRECISION DIF( 2 )
330 DOUBLE PRECISION DLAMCH, DLANGE
331 EXTERNAL lsame, dlamch, dlange
334 INTRINSIC abs, max, sqrt
340 IF( lsame( jobvsl,
'N' ) )
THEN 343 ELSE IF( lsame( jobvsl,
'V' ) )
THEN 351 IF( lsame( jobvsr,
'N' ) )
THEN 354 ELSE IF( lsame( jobvsr,
'V' ) )
THEN 362 wantst = lsame( sort,
'S' )
367 lquery = ( lwork.EQ.-1 )
368 IF( ijobvl.LE.0 )
THEN 370 ELSE IF( ijobvr.LE.0 )
THEN 372 ELSE IF( ( .NOT.wantst ) .AND. ( .NOT.lsame( sort,
'N' ) ) )
THEN 374 ELSE IF( n.LT.0 )
THEN 376 ELSE IF( lda.LT.max( 1, n ) )
THEN 378 ELSE IF( ldb.LT.max( 1, n ) )
THEN 380 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN 382 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN 384 ELSE IF( lwork.LT.6*n+16 .AND. .NOT.lquery )
THEN 391 CALL dgeqrf( n, n, b, ldb, work, work, -1, ierr )
392 lwkopt = max( 6*n+16, 3*n+int( work( 1 ) ) )
393 CALL dormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
395 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
397 CALL dorgqr( n, n, n, vsl, ldvsl, work, work, -1, ierr )
398 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
400 CALL dgghd3( jobvsl, jobvsr, n, 1, n, a, lda, b, ldb, vsl,
401 $ ldvsl, vsr, ldvsr, work, -1, ierr )
402 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
403 CALL dhgeqz(
'S', jobvsl, jobvsr, n, 1, n, a, lda, b, ldb,
404 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
406 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
408 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
409 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
410 $ sdim, pvsl, pvsr, dif, work, -1, idum, 1,
412 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
418 CALL xerbla(
'DGGES3 ', -info )
420 ELSE IF( lquery )
THEN 434 safmin = dlamch(
'S' )
435 safmax = one / safmin
436 CALL dlabad( safmin, safmax )
437 smlnum = sqrt( safmin ) / eps
438 bignum = one / smlnum
442 anrm = dlange(
'M', n, n, a, lda, work )
444 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 447 ELSE IF( anrm.GT.bignum )
THEN 452 $
CALL dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
456 bnrm = dlange(
'M', n, n, b, ldb, work )
458 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN 461 ELSE IF( bnrm.GT.bignum )
THEN 466 $
CALL dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
473 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
474 $ 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 )
487 CALL dormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
488 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
489 $ lwork+1-iwrk, ierr )
494 CALL dlaset(
'Full', n, n, zero, one, vsl, ldvsl )
495 IF( irows.GT.1 )
THEN 496 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
497 $ vsl( ilo+1, ilo ), ldvsl )
499 CALL dorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
500 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
506 $
CALL dlaset(
'Full', n, n, zero, one, vsr, ldvsr )
510 CALL dgghd3( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
511 $ ldvsl, vsr, ldvsr, work( iwrk ), lwork+1-iwrk,
517 CALL dhgeqz(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
518 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
519 $ work( iwrk ), lwork+1-iwrk, ierr )
521 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN 523 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN 539 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
541 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
545 $
CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
550 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
553 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb, alphar,
554 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
555 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
565 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
566 $ work( iright ), n, vsl, ldvsl, ierr )
569 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
570 $ work( iright ), n, vsr, ldvsr, ierr )
578 IF( alphai( i ).NE.zero )
THEN 579 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
580 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN 581 work( 1 ) = abs( a( i, i ) / alphar( i ) )
582 beta( i ) = beta( i )*work( 1 )
583 alphar( i ) = alphar( i )*work( 1 )
584 alphai( i ) = alphai( i )*work( 1 )
585 ELSE IF( ( alphai( i ) / safmax ).GT.
586 $ ( anrmto / anrm ) .OR.
587 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
589 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
590 beta( i ) = beta( i )*work( 1 )
591 alphar( i ) = alphar( i )*work( 1 )
592 alphai( i ) = alphai( i )*work( 1 )
600 IF( alphai( i ).NE.zero )
THEN 601 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
602 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN 603 work( 1 ) = abs( b( i, i ) / beta( i ) )
604 beta( i ) = beta( i )*work( 1 )
605 alphar( i ) = alphar( i )*work( 1 )
606 alphai( i ) = alphai( i )*work( 1 )
615 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
616 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
617 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
621 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
622 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
634 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
635 IF( alphai( i ).EQ.zero )
THEN 639 IF( cursl .AND. .NOT.lastsl )
646 cursl = cursl .OR. lastsl
651 IF( cursl .AND. .NOT.lst2sl )
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
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 dggbak(JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V, LDV, INFO)
DGGBAK
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 dggbal(JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, WORK, INFO)
DGGBAL
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 dormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMQR
subroutine dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGQR
subroutine dhgeqz(JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
DHGEQZ
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dgges3(JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, WORK, LWORK, BWORK, INFO)
DGGES3 computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE...
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine dgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGEQRF
subroutine dgghd3(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
DGGHD3