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 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 dgghd3(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
DGGHD3
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 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 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 dormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMQR
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine dggbal(JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, WORK, INFO)
DGGBAL
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 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 dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGQR