223 SUBROUTINE sggev3( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR,
224 $ ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK,
232 CHARACTER JOBVL, JOBVR
233 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
236 REAL A( LDA, * ), ALPHAI( * ), ( * ),
237 $ ( LDB, * ), BETA( * ), VL( LDVL, * ),
238 $ vr( ldvr, * ), work( * )
245 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
248 LOGICAL , ILBSCL, ILV, ILVL, ILVR, LQUERY
250 INTEGER ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
251 $ in, iright, irows, itau, iwrk, jc, jr, lwkopt
252 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
266 EXTERNAL lsame,
slamch, slange
269 INTRINSIC abs,
max, sqrt
275 IF( lsame( jobvl,
'N' ) )
THEN
278 ELSE IF( lsame( jobvl,
'V' ) )
THEN
286 IF( lsame( jobvr,
'N' ) )
THEN
289 ELSE IF( lsame( jobvr,
'V' ) )
THEN
301 lquery = ( lwork.EQ.-1 )
302 IF( ijobvl.LE.0 )
THEN
304 ELSE IF( ijobvr.LE.0 )
THEN
306 ELSE IF( n.LT.0 )
THEN
308 ELSE IF( lda.LT.
max( 1, n ) )
THEN
310 ELSE IF( ldb.LT.
max( 1, n ) )
THEN
312 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
314 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
316 ELSE IF( lwork.LT.
max( 1, 8*n ) .AND. .NOT.lquery )
THEN
323 CALL sgeqrf( n, n, b, ldb, work, work, -1, ierr )
324 lwkopt =
max( 1, 8*n, 3*n+int( work( 1 ) ) )
325 CALL sormqr(
'L',
'T', n, n, n, b, ldb
327 lwkopt =
max( lwkopt, 3*n+int( work( 1 ) ) )
328 CALL sgghd3( jobvl, jobvr, n, 1, n, a, lda, b, ldb, vl, ldvl,
329 $ vr, ldvr, work, -1, ierr )
330 lwkopt =
max( lwkopt, 3*n+int( work( 1 ) ) )
332 CALL sorgqr( n, n, n, vl, ldvl, work, work, -1, ierr )
333 lwkopt =
max( lwkopt, 3*n+int( work( 1 ) ) )
334 CALL slaqz0(
'S', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
335 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
336 $ work, -1, 0, ierr )
337 lwkopt =
max( lwkopt, 2*n+int( work( 1 ) ) )
339 CALL slaqz0(
'E', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
340 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
341 $ work, -1, 0, ierr )
342 lwkopt =
max( lwkopt, 2*n+int( work( 1 ) ) )
344 work( 1 ) = real( lwkopt )
349 CALL xerbla(
'SGGEV3 ', -info )
351 ELSE IF( lquery )
THEN
364 bignum = one / smlnum
365 CALL slabad( smlnum, bignum )
366 smlnum = sqrt( smlnum ) / eps
367 bignum = one / smlnum
371 anrm = slange(
'M', n, n, a, lda, work )
373 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
376 ELSEIF( anrm.GT.bignum )
THEN
381 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
385 bnrm = slange(
'M', n, n, b, ldb, work )
387 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
390 ELSE IF( bnrm.GT.bignum )
THEN
395 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
402 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
403 $ work( iright ), work( iwrk ), ierr )
407 irows = ihi + 1 - ilo
415 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
416 $ work( iwrk ), lwork+1-iwrk, ierr )
420 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
421 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
422 $ lwork+1-iwrk, ierr )
427 CALL slaset( 'full
', N, N, ZERO, ONE, VL, LDVL )
428.GT.
IF( IROWS1 ) THEN
429 CALL SLACPY( 'l
', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
430 $ VL( ILO+1, ILO ), LDVL )
432 CALL SORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
433 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
439 $ CALL SLASET( 'full
', N, N, ZERO, ONE, VR, LDVR )
447 CALL SGGHD3( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
448 $ LDVL, VR, LDVR, WORK( IWRK ), LWORK+1-IWRK, IERR )
450 CALL SGGHD3( 'n
', 'n
', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
451 $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR,
452 $ WORK( IWRK ), LWORK+1-IWRK, IERR )
464 CALL SLAQZ0( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
465 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
466 $ WORK( IWRK ), LWORK+1-IWRK, 0, IERR )
468.GT..AND..LE.
IF( IERR0 IERRN ) THEN
470.GT..AND..LE.
ELSE IF( IERRN IERR2*N ) THEN
490 CALL STGEVC( CHTEMP, 'b
', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
491 $ VR, LDVR, N, IN, WORK( IWRK ), IERR )
500 CALL SGGBAK( 'p
', 'l
', N, ILO, IHI, WORK( ILEFT ),
501 $ WORK( IRIGHT ), N, VL, LDVL, IERR )
503.LT.
IF( ALPHAI( JC )ZERO )
506.EQ.
IF( ALPHAI( JC )ZERO ) THEN
508 TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
512 TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
513 $ ABS( VL( JR, JC+1 ) ) )
519.EQ.
IF( ALPHAI( JC )ZERO ) THEN
521 VL( JR, JC ) = VL( JR, JC )*TEMP
525 VL( JR, JC ) = VL( JR, JC )*TEMP
526 VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
532 CALL SGGBAK( 'p
', 'r
', N, ILO, IHI, WORK( ILEFT ),
533 $ WORK( IRIGHT ), N, VR, LDVR, IERR )
535.LT.
IF( ALPHAI( JC )ZERO )
538.EQ.
IF( ALPHAI( JC )ZERO ) THEN
540 TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
544 TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
545 $ ABS( VR( JR, JC+1 ) ) )
551.EQ.
IF( ALPHAI( JC )ZERO ) THEN
553 VR( JR, JC ) = VR( JR, JC )*TEMP
557 VR( JR, JC ) = VR( JR, JC )*TEMP
558 VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
573 CALL SLASCL( 'g
', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
574 CALL SLASCL( 'g
', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
578 CALL SLASCL( 'g
', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
581 WORK( 1 ) = REAL( LWKOPT )