359 SUBROUTINE sggesx( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A,
361 $ B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
362 $ VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,
363 $ LIWORK, BWORK, INFO )
370 CHARACTER JOBVSL, JOBVSR, SENSE, SORT
371 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
377 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
378 $ B( LDB, * ), BETA( * ), RCONDE( 2 ),
379 $ rcondv( 2 ), vsl( ldvsl, * ), vsr( ldvsr, * ),
391 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
394 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
395 $ lquery, lst2sl, wantsb, wantse, wantsn, wantst,
397 INTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
398 $ ileft, ilo, ip, iright, irows, itau, iwrk,
399 $ liwmin, lwrk, maxwrk, minwrk
400 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
401 $ pr, safmax, safmin, smlnum
407 EXTERNAL SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ,
414 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
415 EXTERNAL LSAME, ILAENV, SLAMCH, SLANGE,
419 INTRINSIC abs, max, sqrt
425 IF( lsame( jobvsl,
'N' ) )
THEN
428 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
436 IF( lsame( jobvsr,
'N' ) )
THEN
439 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
447 wantst = lsame( sort,
'S' )
448 wantsn = lsame( sense,
'N' )
449 wantse = lsame( sense,
'E' )
450 wantsv = lsame( sense,
'V' )
451 wantsb = lsame( sense,
'B' )
452 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
455 ELSE IF( wantse )
THEN
457 ELSE IF( wantsv )
THEN
459 ELSE IF( wantsb )
THEN
466 IF( ijobvl.LE.0 )
THEN
468 ELSE IF( ijobvr.LE.0 )
THEN
470 ELSE IF( ( .NOT.wantst ) .AND.
471 $ ( .NOT.lsame( sort,
'N' ) ) )
THEN
473 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsv .OR. wantsb ) .OR.
474 $ ( .NOT.wantst .AND. .NOT.wantsn ) )
THEN
476 ELSE IF( n.LT.0 )
THEN
478 ELSE IF( lda.LT.max( 1, n ) )
THEN
480 ELSE IF( ldb.LT.max( 1, n ) )
THEN
482 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
484 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
497 minwrk = max( 8*n, 6*n + 16 )
498 maxwrk = minwrk - n +
499 $ n*ilaenv( 1,
'SGEQRF',
' ', n, 1, n, 0 )
500 maxwrk = max( maxwrk, minwrk - n +
501 $ n*ilaenv( 1,
'SORMQR',
' ', n, 1, n, -1 ) )
503 maxwrk = max( maxwrk, minwrk - n +
504 $ n*ilaenv( 1,
'SORGQR',
' ', n, 1, n, -1 ) )
508 $ lwrk = max( lwrk, n*n/2 )
514 work( 1 ) = sroundup_lwork(lwrk)
515 IF( wantsn .OR. n.EQ.0 )
THEN
522 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
524 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
530 CALL xerbla(
'SGGESX', -info )
532 ELSE IF (lquery)
THEN
546 safmin = slamch(
'S' )
547 safmax = one / safmin
548 smlnum = sqrt( safmin ) / eps
549 bignum = one / smlnum
553 anrm = slange(
'M', n, n, a, lda, work )
555 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
558 ELSE IF( anrm.GT.bignum )
THEN
563 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
567 bnrm = slange(
'M', n, n, b, ldb, work )
569 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
572 ELSE IF( bnrm.GT.bignum )
THEN
577 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
585 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
586 $ work( iright ), work( iwrk ), ierr )
591 irows = ihi + 1 - ilo
595 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
596 $ work( iwrk ), lwork+1-iwrk, ierr )
601 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
602 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
603 $ lwork+1-iwrk, ierr )
609 CALL slaset(
'Full', n, n, zero, one, vsl, ldvsl )
610 IF( irows.GT.1 )
THEN
611 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
612 $ vsl( ilo+1, ilo ), ldvsl )
614 CALL sorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
615 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
621 $
CALL slaset(
'Full', n, n, zero, one, vsr, ldvsr )
626 CALL sgghrd( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
627 $ ldvsl, vsr, ldvsr, ierr )
635 CALL shgeqz(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
636 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
637 $ work( iwrk ), lwork+1-iwrk, ierr )
639 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
641 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
659 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
661 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
665 $
CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n,
671 bwork( i ) = selctg( alphar( i ), alphai( i ),
678 CALL stgsen( ijob, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
679 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
680 $ sdim, pl, pr, dif, work( iwrk ), lwork-iwrk+1,
681 $ iwork, liwork, ierr )
684 $ maxwrk = max( maxwrk, 2*sdim*( n-sdim ) )
685 IF( ierr.EQ.-22 )
THEN
691 IF( ijob.EQ.1 .OR. ijob.EQ.4 )
THEN
695 IF( ijob.EQ.2 .OR. ijob.EQ.4 )
THEN
696 rcondv( 1 ) = dif( 1 )
697 rcondv( 2 ) = dif( 2 )
709 $
CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
710 $ work( iright ), n, vsl, ldvsl, ierr )
713 $
CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
714 $ work( iright ), n, vsr, ldvsr, ierr )
722 IF( alphai( i ).NE.zero )
THEN
723 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
724 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
726 work( 1 ) = abs( a( i, i ) / alphar( i ) )
727 beta( i ) = beta( i )*work( 1 )
728 alphar( i ) = alphar( i )*work( 1 )
729 alphai( i ) = alphai( i )*work( 1 )
730 ELSE IF( ( alphai( i ) / safmax ).GT.( anrmto / anrm )
731 $ .OR. ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
733 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
734 beta( i ) = beta( i )*work( 1 )
735 alphar( i ) = alphar( i )*work( 1 )
736 alphai( i ) = alphai( i )*work( 1 )
744 IF( alphai( i ).NE.zero )
THEN
745 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
746 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
747 work( 1 ) = abs( b( i, i ) / beta( i ) )
748 beta( i ) = beta( i )*work( 1 )
749 alphar( i ) = alphar( i )*work( 1 )
750 alphai( i ) = alphai( i )*work( 1 )
759 CALL slascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
760 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
762 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
767 CALL slascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
768 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
780 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
781 IF( alphai( i ).EQ.zero )
THEN
785 IF( cursl .AND. .NOT.lastsl )
792 cursl = cursl .OR. lastsl
797 IF( cursl .AND. .NOT.lst2sl )
814 work( 1 ) = sroundup_lwork(maxwrk)