279 SUBROUTINE sgges( 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 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
295 $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),
296 $ vsr( ldvsr, * ), work( * )
307 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+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 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
316 $ PVSR, SAFMAX, SAFMIN, SMLNUM
330 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
331 EXTERNAL lsame, ilaenv, slamch, slange,
335 INTRINSIC abs, max, sqrt
341 IF( lsame( jobvsl,
'N' ) )
THEN
344 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
352 IF( lsame( jobvsr,
'N' ) )
THEN
355 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
363 wantst = lsame( sort,
'S' )
368 lquery = ( lwork.EQ.-1 )
369 IF( ijobvl.LE.0 )
THEN
371 ELSE IF( ijobvr.LE.0 )
THEN
373 ELSE IF( ( .NOT.wantst ) .AND.
374 $ ( .NOT.lsame( sort,
'N' ) ) )
THEN
376 ELSE IF( n.LT.0 )
THEN
378 ELSE IF( lda.LT.max( 1, n ) )
THEN
380 ELSE IF( ldb.LT.max( 1, n ) )
THEN
382 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
384 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
397 minwrk = max( 8*n, 6*n + 16 )
398 maxwrk = minwrk - n +
399 $ n*ilaenv( 1,
'SGEQRF',
' ', n, 1, n, 0 )
400 maxwrk = max( maxwrk, minwrk - n +
401 $ n*ilaenv( 1,
'SORMQR',
' ', n, 1, n, -1 ) )
403 maxwrk = max( maxwrk, minwrk - n +
404 $ n*ilaenv( 1,
'SORGQR',
' ', n, 1, n,
411 work( 1 ) = sroundup_lwork(maxwrk)
413 IF( lwork.LT.minwrk .AND. .NOT.lquery )
418 CALL xerbla(
'SGGES ', -info )
420 ELSE IF( lquery )
THEN
434 safmin = slamch(
'S' )
435 safmax = one / safmin
436 smlnum = sqrt( safmin ) / eps
437 bignum = one / smlnum
441 anrm = slange(
'M', n, n, a, lda, work )
443 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
446 ELSE IF( anrm.GT.bignum )
THEN
451 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
455 bnrm = slange(
'M', n, n, b, ldb, work )
457 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
460 ELSE IF( bnrm.GT.bignum )
THEN
465 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
473 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
474 $ work( iright ), work( iwrk ), ierr )
479 irows = ihi + 1 - ilo
483 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
484 $ work( iwrk ), lwork+1-iwrk, ierr )
489 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
490 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
491 $ lwork+1-iwrk, ierr )
497 CALL slaset(
'Full', n, n, zero, one, vsl, ldvsl )
498 IF( irows.GT.1 )
THEN
499 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
500 $ vsl( ilo+1, ilo ), ldvsl )
502 CALL sorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
503 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
509 $
CALL slaset(
'Full', n, n, zero, one, vsr, ldvsr )
514 CALL sgghrd( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
515 $ ldvsl, vsr, ldvsr, ierr )
521 CALL shgeqz(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
522 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
523 $ work( iwrk ), lwork+1-iwrk, ierr )
525 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
527 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
544 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
546 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
550 $
CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n,
556 bwork( i ) = selctg( alphar( i ), alphai( i ),
560 CALL stgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
562 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
563 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
574 $
CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
575 $ work( iright ), n, vsl, ldvsl, ierr )
578 $
CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
579 $ work( iright ), n, vsr, ldvsr, ierr )
587 IF( alphai( i ).NE.zero )
THEN
588 IF( ( alphar( i )/safmax ).GT.( anrmto/anrm ) .OR.
589 $ ( safmin/alphar( i ) ).GT.( anrm/anrmto ) )
THEN
590 work( 1 ) = abs( a( i, i )/alphar( i ) )
591 beta( i ) = beta( i )*work( 1 )
592 alphar( i ) = alphar( i )*work( 1 )
593 alphai( i ) = alphai( i )*work( 1 )
594 ELSE IF( ( alphai( i )/safmax ).GT.( anrmto/anrm ) .OR.
595 $ ( safmin/alphai( i ) ).GT.( anrm/anrmto ) )
THEN
596 work( 1 ) = abs( a( i, i+1 )/alphai( i ) )
597 beta( i ) = beta( i )*work( 1 )
598 alphar( i ) = alphar( i )*work( 1 )
599 alphai( i ) = alphai( i )*work( 1 )
607 IF( alphai( i ).NE.zero )
THEN
608 IF( ( beta( i )/safmax ).GT.( bnrmto/bnrm ) .OR.
609 $ ( safmin/beta( i ) ).GT.( bnrm/bnrmto ) )
THEN
610 work( 1 ) = abs(b( i, i )/beta( i ))
611 beta( i ) = beta( i )*work( 1 )
612 alphar( i ) = alphar( i )*work( 1 )
613 alphai( i ) = alphai( i )*work( 1 )
622 CALL slascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
623 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
625 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
630 CALL slascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
631 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
643 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
644 IF( alphai( i ).EQ.zero )
THEN
648 IF( cursl .AND. .NOT.lastsl )
655 cursl = cursl .OR. lastsl
660 IF( cursl .AND. .NOT.lst2sl )
677 work( 1 ) = sroundup_lwork(maxwrk)