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 )
330 DOUBLE PRECISION DLAMCH, DLANGE
331 EXTERNAL lsame, ilaenv, 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
395 minwrk = max( 8*n, 6*n + 16 )
396 maxwrk = minwrk - n +
397 $ n*ilaenv( 1,
'DGEQRF',
' ', n, 1, n, 0 )
398 maxwrk = max( maxwrk, minwrk - n +
399 $ n*ilaenv( 1,
'DORMQR',
' ', n, 1, n, -1 ) )
401 maxwrk = max( maxwrk, minwrk - n +
402 $ n*ilaenv( 1,
'DORGQR',
' ', n, 1, n, -1 ) )
410 IF( lwork.LT.minwrk .AND. .NOT.lquery )
415 CALL xerbla(
'DGGES ', -info )
417 ELSE IF( lquery )
THEN
431 safmin = dlamch(
'S' )
432 safmax = one / safmin
433 smlnum = sqrt( safmin ) / eps
434 bignum = one / smlnum
438 anrm = dlange(
'M', n, n, a, lda, work )
440 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
443 ELSE IF( anrm.GT.bignum )
THEN
448 $
CALL dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
452 bnrm = dlange(
'M', n, n, b, ldb, work )
454 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
457 ELSE IF( bnrm.GT.bignum )
THEN
462 $
CALL dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
470 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
471 $ work( iright ), work( iwrk ), ierr )
476 irows = ihi + 1 - ilo
480 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
481 $ work( iwrk ), lwork+1-iwrk, ierr )
486 CALL dormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
487 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
488 $ 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 )
511 CALL dgghrd( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
512 $ ldvsl, vsr, ldvsr, ierr )
518 CALL dhgeqz(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
519 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
520 $ work( iwrk ), lwork+1-iwrk, ierr )
522 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
524 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
541 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
543 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
547 $
CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
552 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
555 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb, alphar,
556 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
557 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
568 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
569 $ work( iright ), n, vsl, ldvsl, ierr )
572 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
573 $ work( iright ), n, vsr, ldvsr, ierr )
581 IF( alphai( i ).NE.zero )
THEN
582 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
583 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN
584 work( 1 ) = abs( a( i, i ) / alphar( i ) )
585 beta( i ) = beta( i )*work( 1 )
586 alphar( i ) = alphar( i )*work( 1 )
587 alphai( i ) = alphai( i )*work( 1 )
588 ELSE IF( ( alphai( i ) / safmax ).GT.
589 $ ( anrmto / anrm ) .OR.
590 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
592 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
593 beta( i ) = beta( i )*work( 1 )
594 alphar( i ) = alphar( i )*work( 1 )
595 alphai( i ) = alphai( i )*work( 1 )
603 IF( alphai( i ).NE.zero )
THEN
604 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
605 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
606 work( 1 ) = abs( b( i, i ) / beta( i ) )
607 beta( i ) = beta( i )*work( 1 )
608 alphar( i ) = alphar( i )*work( 1 )
609 alphai( i ) = alphai( i )*work( 1 )
618 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
619 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
620 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
624 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
625 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
637 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
638 IF( alphai( i ).EQ.zero )
THEN
642 IF( cursl .AND. .NOT.lastsl )
649 cursl = cursl .OR. lastsl
654 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 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 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