304 SUBROUTINE sgegv( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,
305 $ BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )
312 CHARACTER JOBVL, JOBVR
313 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
316 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
317 $ b( ldb, * ), beta( * ), vl( ldvl, * ),
318 $ vr( ldvr, * ), work( * )
325 parameter( zero = 0.0e0, one = 1.0e0 )
328 LOGICAL ILIMIT, ILV, ILVL, ILVR, LQUERY
330 INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
331 $ in, iright, irows, itau, iwork, jc, jr, lopt,
332 $ lwkmin, lwkopt, nb, nb1, nb2, nb3
333 REAL ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,
334 $ bnrm1, bnrm2, eps, onepls, safmax, safmin,
335 $ salfai, salfar, sbeta, scale, temp
348 EXTERNAL ilaenv, lsame, slamch, slange
351 INTRINSIC abs, int, max
357 IF( lsame( jobvl,
'N' ) )
THEN
360 ELSE IF( lsame( jobvl,
'V' ) )
THEN
368 IF( lsame( jobvr,
'N' ) )
THEN
371 ELSE IF( lsame( jobvr,
'V' ) )
THEN
382 lwkmin = max( 8*n, 1 )
385 lquery = ( lwork.EQ.-1 )
387 IF( ijobvl.LE.0 )
THEN
389 ELSE IF( ijobvr.LE.0 )
THEN
391 ELSE IF( n.LT.0 )
THEN
393 ELSE IF( lda.LT.max( 1, n ) )
THEN
395 ELSE IF( ldb.LT.max( 1, n ) )
THEN
397 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
399 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
401 ELSE IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
406 nb1 = ilaenv( 1,
'SGEQRF',
' ', n, n, -1, -1 )
407 nb2 = ilaenv( 1,
'SORMQR',
' ', n, n, n, -1 )
408 nb3 = ilaenv( 1,
'SORGQR',
' ', n, n, n, -1 )
409 nb = max( nb1, nb2, nb3 )
410 lopt = 2*n + max( 6*n, n*(nb+1) )
415 CALL xerbla(
'SGEGV ', -info )
417 ELSE IF( lquery )
THEN
428 eps = slamch(
'E' )*slamch(
'B' )
429 safmin = slamch(
'S' )
430 safmin = safmin + safmin
431 safmax = one / safmin
432 onepls = one + ( 4*eps )
436 anrm = slange(
'M', n, n, a, lda, work )
439 IF( anrm.LT.one )
THEN
440 IF( safmax*anrm.LT.one )
THEN
446 IF( anrm.GT.zero )
THEN
447 CALL slascl(
'G', -1, -1, anrm, one, n, n, a, lda, iinfo )
448 IF( iinfo.NE.0 )
THEN
456 bnrm = slange(
'M', n, n, b, ldb, work )
459 IF( bnrm.LT.one )
THEN
460 IF( safmax*bnrm.LT.one )
THEN
466 IF( bnrm.GT.zero )
THEN
467 CALL slascl(
'G', -1, -1, bnrm, one, n, n, b, ldb, iinfo )
468 IF( iinfo.NE.0 )
THEN
481 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
482 $ work( iright ), work( iwork ), iinfo )
483 IF( iinfo.NE.0 )
THEN
492 irows = ihi + 1 - ilo
500 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
501 $ work( iwork ), lwork+1-iwork, iinfo )
503 $ lwkopt = max( lwkopt, int( work( iwork ) )+iwork-1 )
504 IF( iinfo.NE.0 )
THEN
509 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
510 $ work( itau ), a( ilo, ilo ), lda, work( iwork ),
511 $ lwork+1-iwork, iinfo )
513 $ lwkopt = max( lwkopt, int( work( iwork ) )+iwork-1 )
514 IF( iinfo.NE.0 )
THEN
520 CALL slaset(
'Full', n, n, zero, one, vl, ldvl )
521 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
522 $ vl( ilo+1, ilo ), ldvl )
523 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
524 $ work( itau ), work( iwork ), lwork+1-iwork,
527 $ lwkopt = max( lwkopt, int( work( iwork ) )+iwork-1 )
528 IF( iinfo.NE.0 )
THEN
535 $
CALL slaset(
'Full', n, n, zero, one, vr, ldvr )
543 CALL sgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
544 $ ldvl, vr, ldvr, iinfo )
546 CALL sgghrd(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
547 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, iinfo )
549 IF( iinfo.NE.0 )
THEN
564 CALL shgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
565 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
566 $ work( iwork ), lwork+1-iwork, iinfo )
568 $ lwkopt = max( lwkopt, int( work( iwork ) )+iwork-1 )
569 IF( iinfo.NE.0 )
THEN
570 IF( iinfo.GT.0 .AND. iinfo.LE.n )
THEN
572 ELSE IF( iinfo.GT.n .AND. iinfo.LE.2*n )
THEN
594 CALL stgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl, ldvl,
595 $ vr, ldvr, n, in, work( iwork ), iinfo )
596 IF( iinfo.NE.0 )
THEN
604 CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
605 $ work( iright ), n, vl, ldvl, iinfo )
606 IF( iinfo.NE.0 )
THEN
611 IF( alphai( jc ).LT.zero )
614 IF( alphai( jc ).EQ.zero )
THEN
616 temp = max( temp, abs( vl( jr, jc ) ) )
620 temp = max( temp, abs( vl( jr, jc ) )+
621 $ abs( vl( jr, jc+1 ) ) )
627 IF( alphai( jc ).EQ.zero )
THEN
629 vl( jr, jc ) = vl( jr, jc )*temp
633 vl( jr, jc ) = vl( jr, jc )*temp
634 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
640 CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
641 $ work( iright ), n, vr, ldvr, iinfo )
642 IF( iinfo.NE.0 )
THEN
647 IF( alphai( jc ).LT.zero )
650 IF( alphai( jc ).EQ.zero )
THEN
652 temp = max( temp, abs( vr( jr, jc ) ) )
656 temp = max( temp, abs( vr( jr, jc ) )+
657 $ abs( vr( jr, jc+1 ) ) )
663 IF( alphai( jc ).EQ.zero )
THEN
665 vr( jr, jc ) = vr( jr, jc )*temp
669 vr( jr, jc ) = vr( jr, jc )*temp
670 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
689 absar = abs( alphar( jc ) )
690 absai = abs( alphai( jc ) )
691 absb = abs( beta( jc ) )
692 salfar = anrm*alphar( jc )
693 salfai = anrm*alphai( jc )
694 sbeta = bnrm*beta( jc )
700 IF( abs( salfai ).LT.safmin .AND. absai.GE.
701 $ max( safmin, eps*absar, eps*absb ) )
THEN
703 scale = ( onepls*safmin / anrm1 ) /
704 $ max( onepls*safmin, anrm2*absai )
706 ELSE IF( salfai.EQ.zero )
THEN
711 IF( alphai( jc ).LT.zero .AND. jc.GT.1 )
THEN
712 alphai( jc-1 ) = zero
713 ELSE IF( alphai( jc ).GT.zero .AND. jc.LT.n )
THEN
714 alphai( jc+1 ) = zero
720 IF( abs( salfar ).LT.safmin .AND. absar.GE.
721 $ max( safmin, eps*absai, eps*absb ) )
THEN
723 scale = max( scale, ( onepls*safmin / anrm1 ) /
724 $ max( onepls*safmin, anrm2*absar ) )
729 IF( abs( sbeta ).LT.safmin .AND. absb.GE.
730 $ max( safmin, eps*absar, eps*absai ) )
THEN
732 scale = max( scale, ( onepls*safmin / bnrm1 ) /
733 $ max( onepls*safmin, bnrm2*absb ) )
739 temp = ( scale*safmin )*max( abs( salfar ), abs( salfai ),
742 $ scale = scale / temp
750 salfar = ( scale*alphar( jc ) )*anrm
751 salfai = ( scale*alphai( jc ) )*anrm
752 sbeta = ( scale*beta( jc ) )*bnrm
754 alphar( jc ) = salfar
755 alphai( jc ) = salfai
subroutine xerbla(srname, info)
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
subroutine sggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
SGGBAK
subroutine sggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
SGGBAL
subroutine sgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
SGGHRD
subroutine shgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
SHGEQZ
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
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 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 stgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
STGEVC
subroutine sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR
subroutine sgegv(jobvl, jobvr, n, a, lda, b, ldb, alphar, alphai, beta, vl, ldvl, vr, ldvr, work, lwork, info)
SGEGV computes the eigenvalues and, optionally, the left and/or right eigenvectors of a real matrix p...