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 sggbal(JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, WORK, INFO)
SGGBAL
subroutine sormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMQR
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 stgevc(SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
STGEVC
subroutine slabad(SMALL, LARGE)
SLABAD
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 sgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGEQRF
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
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 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 sggbak(JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V, LDV, INFO)
SGGBAK
subroutine sorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
SORGQR