279 SUBROUTINE dgges3( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B,
280 $ LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
281 $ VSR, LDVSR, WORK, LWORK, BWORK, INFO )
288 CHARACTER JOBVSL, JOBVSR, SORT
289 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
293 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
294 $ b( ldb, * ), beta( * ), vsl( ldvsl, * ),
295 $ vsr( ldvsr, * ), work( * )
305 DOUBLE PRECISION ZERO, ONE
306 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
309 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
310 $ LQUERY, LST2SL, WANTST
311 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
312 $ ILO, IP, IRIGHT, IROWS, ITAU, IWRK, LWKOPT
313 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
314 $ PVSR, SAFMAX, SAFMIN, SMLNUM
318 DOUBLE PRECISION DIF( 2 )
326 DOUBLE PRECISION DLAMCH, DLANGE
327 EXTERNAL lsame, dlamch, dlange
330 INTRINSIC abs, max, sqrt
336 IF( lsame( jobvsl,
'N' ) )
THEN
339 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
347 IF( lsame( jobvsr,
'N' ) )
THEN
350 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
358 wantst = lsame( sort,
'S' )
363 lquery = ( lwork.EQ.-1 )
364 IF( ijobvl.LE.0 )
THEN
366 ELSE IF( ijobvr.LE.0 )
THEN
368 ELSE IF( ( .NOT.wantst ) .AND. ( .NOT.lsame( sort,
'N' ) ) )
THEN
370 ELSE IF( n.LT.0 )
THEN
372 ELSE IF( lda.LT.max( 1, n ) )
THEN
374 ELSE IF( ldb.LT.max( 1, n ) )
THEN
376 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
378 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
380 ELSE IF( lwork.LT.6*n+16 .AND. .NOT.lquery )
THEN
387 CALL dgeqrf( n, n, b, ldb, work, work, -1, ierr )
388 lwkopt = max( 6*n+16, 3*n+int( work( 1 ) ) )
389 CALL dormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
391 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
393 CALL dorgqr( n, n, n, vsl, ldvsl, work, work, -1, ierr )
394 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
396 CALL dgghd3( jobvsl, jobvsr, n, 1, n, a, lda, b, ldb, vsl,
397 $ ldvsl, vsr, ldvsr, work, -1, ierr )
398 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
399 CALL dlaqz0(
'S', jobvsl, jobvsr, n, 1, n, a, lda, b, ldb,
400 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
401 $ work, -1, 0, ierr )
402 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
404 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
405 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
406 $ sdim, pvsl, pvsr, dif, work, -1, idum, 1,
408 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
414 CALL xerbla(
'DGGES3 ', -info )
416 ELSE IF( lquery )
THEN
430 safmin = dlamch(
'S' )
431 safmax = one / safmin
432 smlnum = sqrt( safmin ) / eps
433 bignum = one / smlnum
437 anrm = dlange(
'M', n, n, a, lda, work )
439 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
442 ELSE IF( anrm.GT.bignum )
THEN
447 $
CALL dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
451 bnrm = dlange(
'M', n, n, b, ldb, work )
453 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
456 ELSE IF( bnrm.GT.bignum )
THEN
461 $
CALL dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
468 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
469 $ work( iright ), work( iwrk ), ierr )
473 irows = ihi + 1 - ilo
477 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
478 $ work( iwrk ), lwork+1-iwrk, ierr )
482 CALL dormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
483 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
484 $ lwork+1-iwrk, ierr )
489 CALL dlaset(
'Full', n, n, zero, one, vsl, ldvsl )
490 IF( irows.GT.1 )
THEN
491 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
492 $ vsl( ilo+1, ilo ), ldvsl )
494 CALL dorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
495 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
501 $
CALL dlaset(
'Full', n, n, zero, one, vsr, ldvsr )
505 CALL dgghd3( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
506 $ ldvsl, vsr, ldvsr, work( iwrk ), lwork+1-iwrk,
512 CALL dlaqz0(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
513 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
514 $ work( iwrk ), lwork+1-iwrk, 0, ierr )
516 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
518 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
534 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
536 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
540 $
CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
545 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
548 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb, alphar,
549 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
550 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
560 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
561 $ work( iright ), n, vsl, ldvsl, ierr )
564 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
565 $ work( iright ), n, vsr, ldvsr, ierr )
573 IF( alphai( i ).NE.zero )
THEN
574 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
575 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN
576 work( 1 ) = abs( a( i, i ) / alphar( i ) )
577 beta( i ) = beta( i )*work( 1 )
578 alphar( i ) = alphar( i )*work( 1 )
579 alphai( i ) = alphai( i )*work( 1 )
580 ELSE IF( ( alphai( i ) / safmax ).GT.
581 $ ( anrmto / anrm ) .OR.
582 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
584 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
585 beta( i ) = beta( i )*work( 1 )
586 alphar( i ) = alphar( i )*work( 1 )
587 alphai( i ) = alphai( i )*work( 1 )
595 IF( alphai( i ).NE.zero )
THEN
596 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
597 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
598 work( 1 ) = abs( b( i, i ) / beta( i ) )
599 beta( i ) = beta( i )*work( 1 )
600 alphar( i ) = alphar( i )*work( 1 )
601 alphai( i ) = alphai( i )*work( 1 )
610 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
611 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
612 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
616 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
617 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
629 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
630 IF( alphai( i ).EQ.zero )
THEN
634 IF( cursl .AND. .NOT.lastsl )
641 cursl = cursl .OR. lastsl
646 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 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 dgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
DGGHD3
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
recursive subroutine dlaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, rec, info)
DLAQZ0
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