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( * ), ALPHAR( * ),
237 $ B( LDB, * ), BETA( * ), VL( LDVL, * ),
238 $ vr( ldvr, * ), work( * )
245 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
248 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
250 INTEGER , 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
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, work, a, lda, work,
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
363 smlnum = slamch(
'S' )
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 ELSE IF( 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
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 IF( irows.GT.1 )
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
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 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
470 ELSE IF( ierr.GT.n .AND. ierr.LE.2*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 )