225 SUBROUTINE sggev3( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR,
226 $ ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK,
235 CHARACTER JOBVL, JOBVR
236 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
239 REAL A( lda, * ), ALPHAI( * ), ALPHAR( * ),
240 $ b( ldb, * ), beta( * ), vl( ldvl, * ),
241 $ vr( ldvr, * ), work( * )
248 parameter( zero = 0.0e+0, one = 1.0e+0 )
251 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
253 INTEGER ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
254 $ in, iright, irows, itau, iwrk, jc, jr, lwkopt
255 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
269 EXTERNAL lsame, slamch, slange
272 INTRINSIC abs, max, sqrt
278 IF( lsame( jobvl,
'N' ) )
THEN 281 ELSE IF( lsame( jobvl,
'V' ) )
THEN 289 IF( lsame( jobvr,
'N' ) )
THEN 292 ELSE IF( lsame( jobvr,
'V' ) )
THEN 304 lquery = ( lwork.EQ.-1 )
305 IF( ijobvl.LE.0 )
THEN 307 ELSE IF( ijobvr.LE.0 )
THEN 309 ELSE IF( n.LT.0 )
THEN 311 ELSE IF( lda.LT.max( 1, n ) )
THEN 313 ELSE IF( ldb.LT.max( 1, n ) )
THEN 315 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN 317 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN 319 ELSE IF( lwork.LT.max( 1, 8*n ) .AND. .NOT.lquery )
THEN 326 CALL sgeqrf( n, n, b, ldb, work, work, -1, ierr )
327 lwkopt = max( 1, 8*n, 3*n+int( work( 1 ) ) )
328 CALL sormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
330 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
331 CALL sgghd3( jobvl, jobvr, n, 1, n, a, lda, b, ldb, vl, ldvl,
332 $ vr, ldvr, work, -1, ierr )
333 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
335 CALL sorgqr( n, n, n, vl, ldvl, work, work, -1, ierr )
336 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
337 CALL shgeqz(
'S', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
338 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
340 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
342 CALL shgeqz(
'E', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
343 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
345 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
347 work( 1 ) =
REAL( lwkopt )
352 CALL xerbla(
'SGGEV3 ', -info )
354 ELSE IF( lquery )
THEN 366 smlnum = slamch(
'S' )
367 bignum = one / smlnum
368 CALL slabad( smlnum, bignum )
369 smlnum = sqrt( smlnum ) / eps
370 bignum = one / smlnum
374 anrm = slange(
'M', n, n, a, lda, work )
376 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 379 ELSE IF( anrm.GT.bignum )
THEN 384 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
388 bnrm = slange(
'M', n, n, b, ldb, work )
390 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN 393 ELSE IF( bnrm.GT.bignum )
THEN 398 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
405 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
406 $ work( iright ), work( iwrk ), ierr )
410 irows = ihi + 1 - ilo
418 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
419 $ work( iwrk ), lwork+1-iwrk, ierr )
423 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
424 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
425 $ lwork+1-iwrk, ierr )
430 CALL slaset(
'Full', n, n, zero, one, vl, ldvl )
431 IF( irows.GT.1 )
THEN 432 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
433 $ vl( ilo+1, ilo ), ldvl )
435 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
436 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
442 $
CALL slaset(
'Full', n, n, zero, one, vr, ldvr )
450 CALL sgghd3( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
451 $ ldvl, vr, ldvr, work( iwrk ), lwork+1-iwrk, ierr )
453 CALL sgghd3(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
454 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr,
455 $ work( iwrk ), lwork+1-iwrk, ierr )
467 CALL shgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
468 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
469 $ work( iwrk ), lwork+1-iwrk, ierr )
471 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN 473 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN 493 CALL stgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl, ldvl,
494 $ vr, ldvr, n, in, work( iwrk ), ierr )
503 CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
504 $ work( iright ), n, vl, ldvl, ierr )
506 IF( alphai( jc ).LT.zero )
509 IF( alphai( jc ).EQ.zero )
THEN 511 temp = max( temp, abs( vl( jr, jc ) ) )
515 temp = max( temp, abs( vl( jr, jc ) )+
516 $ abs( vl( jr, jc+1 ) ) )
522 IF( alphai( jc ).EQ.zero )
THEN 524 vl( jr, jc ) = vl( jr, jc )*temp
528 vl( jr, jc ) = vl( jr, jc )*temp
529 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
535 CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
536 $ work( iright ), n, vr, ldvr, ierr )
538 IF( alphai( jc ).LT.zero )
541 IF( alphai( jc ).EQ.zero )
THEN 543 temp = max( temp, abs( vr( jr, jc ) ) )
547 temp = max( temp, abs( vr( jr, jc ) )+
548 $ abs( vr( jr, jc+1 ) ) )
554 IF( alphai( jc ).EQ.zero )
THEN 556 vr( jr, jc ) = vr( jr, jc )*temp
560 vr( jr, jc ) = vr( jr, jc )*temp
561 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
576 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
577 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
581 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
584 work( 1 ) =
REAL( lwkopt )
subroutine stgevc(SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
STGEVC
subroutine sgghd3(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
SGGHD3
subroutine shgeqz(JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
SHGEQZ
subroutine sormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMQR
subroutine sgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGEQRF
subroutine sggev3(JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO)
SGGEV3 computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices ...
subroutine sggbak(JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V, LDV, INFO)
SGGBAK
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine slascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine sorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGQR
subroutine sggbal(JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, WORK, INFO)
SGGBAL
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.