279 SUBROUTINE dgges( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B,
281 $ SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR,
282 $ LDVSR, WORK, LWORK, BWORK, INFO )
289 CHARACTER JOBVSL, JOBVSR, SORT
290 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
294 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
295 $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),
296 $ vsr( ldvsr, * ), work( * )
306 DOUBLE PRECISION ZERO, ONE
307 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
310 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
311 $ LQUERY, LST2SL, WANTST
312 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
313 $ ilo, ip, iright, irows, itau, iwrk, maxwrk,
315 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
316 $ PVSR, SAFMAX, SAFMIN, SMLNUM
320 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.
373 $ ( .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,
412 IF( lwork.LT.minwrk .AND. .NOT.lquery )
417 CALL xerbla(
'DGGES ', -info )
419 ELSE IF( lquery )
THEN
433 safmin = dlamch(
'S' )
434 safmax = one / safmin
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,
555 bwork( i ) = selctg( alphar( i ), alphai( i ),
559 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
561 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
562 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
573 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
574 $ work( iright ), n, vsl, ldvsl, ierr )
577 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
578 $ work( iright ), n, vsr, ldvsr, ierr )
586 IF( alphai( i ).NE.zero )
THEN
587 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
588 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN
589 work( 1 ) = abs( a( i, i ) / alphar( i ) )
590 beta( i ) = beta( i )*work( 1 )
591 alphar( i ) = alphar( i )*work( 1 )
592 alphai( i ) = alphai( i )*work( 1 )
593 ELSE IF( ( alphai( i ) / safmax ).GT.
594 $ ( anrmto / anrm ) .OR.
595 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
597 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
598 beta( i ) = beta( i )*work( 1 )
599 alphar( i ) = alphar( i )*work( 1 )
600 alphai( i ) = alphai( i )*work( 1 )
608 IF( alphai( i ).NE.zero )
THEN
609 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
610 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
611 work( 1 ) = abs( b( i, i ) / beta( i ) )
612 beta( i ) = beta( i )*work( 1 )
613 alphar( i ) = alphar( i )*work( 1 )
614 alphai( i ) = alphai( i )*work( 1 )
623 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
624 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
626 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
631 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
632 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
644 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
645 IF( alphai( i ).EQ.zero )
THEN
649 IF( cursl .AND. .NOT.lastsl )
656 cursl = cursl .OR. lastsl
661 IF( cursl .AND. .NOT.lst2sl )