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,
314 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
315 $ PVSR, SAFMAX, SAFMIN, SMLNUM
319 DOUBLE PRECISION DIF( 2 )
328 DOUBLE PRECISION DLAMCH, DLANGE
329 EXTERNAL lsame, dlamch, dlange
332 INTRINSIC abs, max, sqrt
338 IF( lsame( jobvsl,
'N' ) )
THEN
341 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
349 IF( lsame( jobvsr,
'N' ) )
THEN
352 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
360 wantst = lsame( sort,
'S' )
365 lquery = ( lwork.EQ.-1 )
372 IF( ijobvl.LE.0 )
THEN
374 ELSE IF( ijobvr.LE.0 )
THEN
376 ELSE IF( ( .NOT.wantst ) .AND.
377 $ ( .NOT.lsame( sort,
'N' ) ) )
THEN
379 ELSE IF( n.LT.0 )
THEN
381 ELSE IF( lda.LT.max( 1, n ) )
THEN
383 ELSE IF( ldb.LT.max( 1, n ) )
THEN
385 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
387 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
389 ELSE IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
396 CALL dgeqrf( n, n, b, ldb, work, work, -1, ierr )
397 lwkopt = max( lwkmin, 3*n+int( work( 1 ) ) )
398 CALL dormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
400 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
402 CALL dorgqr( n, n, n, vsl, ldvsl, work, work, -1, ierr )
403 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
405 CALL dgghd3( jobvsl, jobvsr, n, 1, n, a, lda, b, ldb, vsl,
406 $ ldvsl, vsr, ldvsr, work, -1, ierr )
407 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
408 CALL dlaqz0(
'S', jobvsl, jobvsr, n, 1, n, a, lda, b, ldb,
409 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
410 $ work, -1, 0, ierr )
411 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
413 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
414 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
415 $ sdim, pvsl, pvsr, dif, work, -1, idum, 1,
417 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
427 CALL xerbla(
'DGGES3 ', -info )
429 ELSE IF( lquery )
THEN
443 safmin = dlamch(
'S' )
444 safmax = one / safmin
445 smlnum = sqrt( safmin ) / eps
446 bignum = one / smlnum
450 anrm = dlange(
'M', n, n, a, lda, work )
452 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
455 ELSE IF( anrm.GT.bignum )
THEN
460 $
CALL dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
464 bnrm = dlange(
'M', n, n, b, ldb, work )
466 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
469 ELSE IF( bnrm.GT.bignum )
THEN
474 $
CALL dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
481 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
482 $ work( iright ), work( iwrk ), ierr )
486 irows = ihi + 1 - ilo
490 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
491 $ work( iwrk ), lwork+1-iwrk, ierr )
495 CALL dormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
496 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
497 $ lwork+1-iwrk, ierr )
502 CALL dlaset(
'Full', n, n, zero, one, vsl, ldvsl )
503 IF( irows.GT.1 )
THEN
504 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
505 $ vsl( ilo+1, ilo ), ldvsl )
507 CALL dorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
508 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
514 $
CALL dlaset(
'Full', n, n, zero, one, vsr, ldvsr )
518 CALL dgghd3( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
519 $ ldvsl, vsr, ldvsr, work( iwrk ), lwork+1-iwrk,
525 CALL dlaqz0(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
526 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
527 $ work( iwrk ), lwork+1-iwrk, 0, ierr )
529 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
531 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
547 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
549 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
553 $
CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n,
559 bwork( i ) = selctg( alphar( i ), alphai( i ),
563 CALL dtgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
565 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
566 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
576 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
577 $ work( iright ), n, vsl, ldvsl, ierr )
580 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
581 $ work( iright ), n, vsr, ldvsr, ierr )
589 IF( alphai( i ).NE.zero )
THEN
590 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
591 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN
592 work( 1 ) = abs( a( i, i ) / alphar( i ) )
593 beta( i ) = beta( i )*work( 1 )
594 alphar( i ) = alphar( i )*work( 1 )
595 alphai( i ) = alphai( i )*work( 1 )
596 ELSE IF( ( alphai( i ) / safmax ).GT.
597 $ ( anrmto / anrm ) .OR.
598 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
600 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
601 beta( i ) = beta( i )*work( 1 )
602 alphar( i ) = alphar( i )*work( 1 )
603 alphai( i ) = alphai( i )*work( 1 )
611 IF( alphai( i ).NE.zero )
THEN
612 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
613 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
614 work( 1 ) = abs( b( i, i ) / beta( i ) )
615 beta( i ) = beta( i )*work( 1 )
616 alphar( i ) = alphar( i )*work( 1 )
617 alphai( i ) = alphai( i )*work( 1 )
626 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
627 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
629 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
634 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
635 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
647 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
648 IF( alphai( i ).EQ.zero )
THEN
652 IF( cursl .AND. .NOT.lastsl )
659 cursl = cursl .OR. lastsl
664 IF( cursl .AND. .NOT.lst2sl )