279 SUBROUTINE sgges3( 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 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
294 $ b( ldb, * ), beta( * ), vsl( ldvsl, * ),
295 $ vsr( ldvsr, * ), work( * )
306 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+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 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
315 $ PVSR, SAFMAX, SAFMIN, SMLNUM
328 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
329 EXTERNAL lsame, slamch, slange,
333 INTRINSIC abs, max, sqrt
339 IF( lsame( jobvsl,
'N' ) )
THEN
342 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
350 IF( lsame( jobvsr,
'N' ) )
THEN
353 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
361 wantst = lsame( sort,
'S' )
366 lquery = ( lwork.EQ.-1 )
373 IF( ijobvl.LE.0 )
THEN
375 ELSE IF( ijobvr.LE.0 )
THEN
377 ELSE IF( ( .NOT.wantst ) .AND.
378 $ ( .NOT.lsame( sort,
'N' ) ) )
THEN
380 ELSE IF( n.LT.0 )
THEN
382 ELSE IF( lda.LT.max( 1, n ) )
THEN
384 ELSE IF( ldb.LT.max( 1, n ) )
THEN
386 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
388 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
390 ELSE IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
397 CALL sgeqrf( n, n, b, ldb, work, work, -1, ierr )
398 lwkopt = max( lwkmin, 3*n+int( work( 1 ) ) )
399 CALL sormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
401 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
403 CALL sorgqr( n, n, n, vsl, ldvsl, work, work, -1, ierr )
404 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
406 CALL sgghd3( jobvsl, jobvsr, n, 1, n, a, lda, b, ldb, vsl,
407 $ ldvsl, vsr, ldvsr, work, -1, ierr )
408 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
409 CALL slaqz0(
'S', jobvsl, jobvsr, n, 1, n, a, lda, b, ldb,
410 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
411 $ work, -1, 0, ierr )
412 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
414 CALL stgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
415 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
416 $ sdim, pvsl, pvsr, dif, work, -1, idum, 1,
418 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
423 work( 1 ) = sroundup_lwork( lwkopt )
428 CALL xerbla(
'SGGES3 ', -info )
430 ELSE IF( lquery )
THEN
445 safmin = slamch(
'S' )
446 safmax = one / safmin
447 smlnum = sqrt( safmin ) / eps
448 bignum = one / smlnum
452 anrm = slange(
'M', n, n, a, lda, work )
454 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
457 ELSE IF( anrm.GT.bignum )
THEN
462 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
466 bnrm = slange(
'M', n, n, b, ldb, work )
468 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
471 ELSE IF( bnrm.GT.bignum )
THEN
476 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
483 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
484 $ work( iright ), work( iwrk ), ierr )
488 irows = ihi + 1 - ilo
492 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
493 $ work( iwrk ), lwork+1-iwrk, ierr )
497 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
498 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
499 $ lwork+1-iwrk, ierr )
504 CALL slaset(
'Full', n, n, zero, one, vsl, ldvsl )
505 IF( irows.GT.1 )
THEN
506 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
507 $ vsl( ilo+1, ilo ), ldvsl )
509 CALL sorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
510 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
516 $
CALL slaset(
'Full', n, n, zero, one, vsr, ldvsr )
520 CALL sgghd3( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
521 $ ldvsl, vsr, ldvsr, work( iwrk ), lwork+1-iwrk, ierr )
526 CALL slaqz0(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
527 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
528 $ work( iwrk ), lwork+1-iwrk, 0, ierr )
530 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
532 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
548 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
550 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
554 $
CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n,
560 bwork( i ) = selctg( alphar( i ), alphai( i ),
564 CALL stgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
566 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
567 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
577 $
CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
578 $ work( iright ), n, vsl, ldvsl, ierr )
581 $
CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
582 $ work( iright ), n, vsr, ldvsr, ierr )
590 IF( alphai( i ).NE.zero )
THEN
591 IF( ( alphar( i )/safmax ).GT.( anrmto/anrm ) .OR.
592 $ ( safmin/alphar( i ) ).GT.( anrm/anrmto ) )
THEN
593 work( 1 ) = abs( a( i, i )/alphar( i ) )
594 beta( i ) = beta( i )*work( 1 )
595 alphar( i ) = alphar( i )*work( 1 )
596 alphai( i ) = alphai( i )*work( 1 )
597 ELSE IF( ( alphai( i )/safmax ).GT.( anrmto/anrm ) .OR.
598 $ ( safmin/alphai( i ) ).GT.( anrm/anrmto ) )
THEN
599 work( 1 ) = abs( a( i, i+1 )/alphai( i ) )
600 beta( i ) = beta( i )*work( 1 )
601 alphar( i ) = alphar( i )*work( 1 )
602 alphai( i ) = alphai( i )*work( 1 )
610 IF( alphai( i ).NE.zero )
THEN
611 IF( ( beta( i )/safmax ).GT.( bnrmto/bnrm ) .OR.
612 $ ( safmin/beta( i ) ).GT.( bnrm/bnrmto ) )
THEN
613 work( 1 ) = abs(b( i, i )/beta( i ))
614 beta( i ) = beta( i )*work( 1 )
615 alphar( i ) = alphar( i )*work( 1 )
616 alphai( i ) = alphai( i )*work( 1 )
625 CALL slascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
626 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
628 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
633 CALL slascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
634 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
646 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
647 IF( alphai( i ).EQ.zero )
THEN
651 IF( cursl .AND. .NOT.lastsl )
658 cursl = cursl .OR. lastsl
663 IF( cursl .AND. .NOT.lst2sl )
680 work( 1 ) = sroundup_lwork( lwkopt )