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
313 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
314 $ PVSR, SAFMAX, SAFMIN, SMLNUM
328 EXTERNAL lsame, slamch, slange
331 INTRINSIC abs,
max, sqrt
337 IF( lsame( jobvsl,
'N' ) )
THEN
340 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
348 IF( lsame( jobvsr,
'N' ) )
THEN
351 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
359 wantst = lsame( sort, 's
' )
364.EQ.
LQUERY = ( LWORK-1 )
365.LE.
IF( IJOBVL0 ) THEN
367.LE.
ELSE IF( IJOBVR0 ) THEN
369.NOT..AND..NOT.
ELSE IF( ( WANTST ) ( LSAME( SORT, 'n
' ) ) ) THEN
371.LT.
ELSE IF( N0 ) THEN
373.LT.
ELSE IF( LDAMAX( 1, N ) ) THEN
375.LT.
ELSE IF( LDBMAX( 1, N ) ) THEN
377.LT..OR..AND..LT.
ELSE IF( LDVSL1 ( ILVSL LDVSLN ) ) THEN
379.LT..OR..AND..LT.
ELSE IF( LDVSR1 ( ILVSR LDVSRN ) ) THEN
381.LT..AND..NOT.
ELSE IF( LWORK6*N+16 LQUERY ) THEN
388 CALL SGEQRF( N, N, B, LDB, WORK, WORK, -1, IERR )
389 LWKOPT = MAX( 6*N+16, 3*N+INT( WORK( 1 ) ) )
390 CALL SORMQR( 'l
', 't
', N, N, N, B, LDB, WORK, A, LDA, WORK,
392 LWKOPT = MAX( LWKOPT, 3*N+INT( WORK( 1 ) ) )
394 CALL SORGQR( N, N, N, VSL, LDVSL, WORK, WORK, -1, IERR )
395 LWKOPT = MAX( LWKOPT, 3*N+INT( WORK( 1 ) ) )
397 CALL SGGHD3( JOBVSL, JOBVSR, N, 1, N, A, LDA, B, LDB, VSL,
398 $ LDVSL, VSR, LDVSR, WORK, -1, IERR )
399 LWKOPT = MAX( LWKOPT, 3*N+INT( WORK( 1 ) ) )
400 CALL SLAQZ0( 's
', JOBVSL, JOBVSR, N, 1, N, A, LDA, B, LDB,
401 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
402 $ WORK, -1, 0, IERR )
403 LWKOPT = MAX( LWKOPT, 2*N+INT( WORK( 1 ) ) )
405 CALL STGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
406 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
407 $ SDIM, PVSL, PVSR, DIF, WORK, -1, IDUM, 1,
409 LWKOPT = MAX( LWKOPT, 2*N+INT( WORK( 1 ) ) )
415 CALL XERBLA( 'sgges3 ', -INFO )
417 ELSE IF( LQUERY ) THEN
431 SAFMIN = SLAMCH( 's
' )
432 SAFMAX = ONE / SAFMIN
433 CALL SLABAD( SAFMIN, SAFMAX )
434 SMLNUM = SQRT( SAFMIN ) / EPS
435 BIGNUM = ONE / SMLNUM
439 ANRM = SLANGE( 'm
', N, N, A, LDA, WORK )
441.GT..AND..LT.
IF( ANRMZERO ANRMSMLNUM ) THEN
444.GT.
ELSE IF( ANRMBIGNUM ) THEN
449 $ CALL SLASCL( 'g
', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
453 BNRM = SLANGE( 'm
', N, N, B, LDB, WORK )
455.GT..AND..LT.
IF( BNRMZERO BNRMSMLNUM ) THEN
458.GT.
ELSE IF( BNRMBIGNUM ) THEN
463 $ CALL SLASCL( 'g', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
470 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
471 $ work( iright ), work( iwrk ), ierr )
475 irows = ihi + 1 - ilo
479 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
480 $ work( iwrk ), lwork+1-iwrk, ierr )
484 CALL sormqr( 'l
', 't
', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
485 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
486 $ LWORK+1-IWRK, IERR )
491 CALL SLASET( 'full
', N, N, ZERO, ONE, VSL, LDVSL )
492.GT.
IF( IROWS1 ) THEN
493 CALL SLACPY( 'l
', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
494 $ VSL( ILO+1, ILO ), LDVSL )
496 CALL SORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
497 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
503 $ CALL SLASET( 'full
', N, N, ZERO, ONE, VSR, LDVSR )
507 CALL SGGHD3( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
508 $ LDVSL, VSR, LDVSR, WORK( IWRK ), LWORK+1-IWRK, IERR )
513 CALL SLAQZ0( 's
', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
514 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
515 $ WORK( IWRK ), LWORK+1-IWRK, 0, IERR )
517.GT..AND..LE.
IF( IERR0 IERRN ) THEN
519.GT..AND..LE.
ELSE IF( IERRN IERR2*N ) THEN
535 CALL SLASCL( 'g', 0, 0, anrmto, anrm, n, 1, alphar, n,
537 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
541 $
CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
546 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
549 CALL stgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb, alphar,
550 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
551 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
561 $
CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
562 $ work( iright ), n, vsl, ldvsl, ierr )
565 $
CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
566 $ work( iright ), n, vsr, ldvsr, ierr )
574 IF( alphai( i ).NE.zero )
THEN
575 IF( ( alphar( i )/safmax ).GT.( anrmto/anrm ) .OR.
576 $ ( safmin/alphar( i ) ).GT.( anrm/anrmto ) )
THEN
577 work( 1 ) = abs( a( i, i )/alphar( i ) )
578 beta( i ) = beta( i )*work( 1 )
579 alphar( i ) = alphar( i )*work( 1 )
580 alphai( i ) = alphai( i )*work( 1 )
581 ELSE IF( ( alphai( i )/safmax ).GT.( anrmto/anrm ) .OR.
582 $ ( safmin/alphai( i ) ).GT.( anrm/anrmto ) )
THEN
583 work( 1 ) = abs( a( i, i+1 )/alphai( i ) )
584 beta( i ) = beta( i )*work( 1 )
585 alphar( i ) = alphar( i )*work( 1 )
586 alphai( i ) = alphai( i )*work( 1 )
594 IF( alphai( i ).NE.zero )
THEN
595 IF( ( beta( i )/safmax ).GT.( bnrmto/bnrm ) .OR.
596 $ ( safmin/beta( i ) ).GT.( bnrm/bnrmto ) )
THEN
597 work( 1 ) = abs(b( i, i )/beta( i ))
598 beta( i ) = beta( i )*work( 1 )
599 alphar( i ) = alphar( i )*work( 1 )
600 alphai( i ) = alphai( i )*work( 1 )
609 CALL slascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
610 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
611 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
615 CALL slascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
616 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
628 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
629 IF( alphai( i ).EQ.zero )
THEN
633 IF( cursl .AND. .NOT.lastsl )
640 cursl = cursl .OR. lastsl
645 IF( cursl .AND. .NOT.lst2sl )