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 ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
251 $ in, iright, irows, itau, iwrk, jc, jr, lwkopt
252 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
264 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
265 EXTERNAL lsame, slamch, slange, sroundup_lwork
268 INTRINSIC abs, max, sqrt
274 IF( lsame( jobvl,
'N' ) )
THEN
277 ELSE IF( lsame( jobvl,
'V' ) )
THEN
285 IF( lsame( jobvr,
'N' ) )
THEN
288 ELSE IF( lsame( jobvr,
'V' ) )
THEN
300 lquery = ( lwork.EQ.-1 )
301 IF( ijobvl.LE.0 )
THEN
303 ELSE IF( ijobvr.LE.0 )
THEN
305 ELSE IF( n.LT.0 )
THEN
307 ELSE IF( lda.LT.max( 1, n ) )
THEN
309 ELSE IF( ldb.LT.max( 1, n ) )
THEN
311 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
313 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
315 ELSE IF( lwork.LT.max( 1, 8*n ) .AND. .NOT.lquery )
THEN
322 CALL sgeqrf( n, n, b, ldb, work, work, -1, ierr )
323 lwkopt = max( 1, 8*n, 3*n+int( work( 1 ) ) )
324 CALL sormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
326 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
327 CALL sgghd3( jobvl, jobvr, n, 1, n, a, lda, b, ldb, vl, ldvl,
328 $ vr, ldvr, work, -1, ierr )
329 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
331 CALL sorgqr( n, n, n, vl, ldvl, work, work, -1, ierr )
332 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
333 CALL slaqz0(
'S', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
334 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
335 $ work, -1, 0, ierr )
336 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
338 CALL slaqz0(
'E', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
339 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
340 $ work, -1, 0, ierr )
341 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
343 work( 1 ) = sroundup_lwork( lwkopt )
348 CALL xerbla(
'SGGEV3 ', -info )
350 ELSE IF( lquery )
THEN
362 smlnum = slamch(
'S' )
363 bignum = one / smlnum
364 smlnum = sqrt( smlnum ) / eps
365 bignum = one / smlnum
369 anrm = slange(
'M', n, n, a, lda, work )
371 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
374 ELSE IF( anrm.GT.bignum )
THEN
379 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
383 bnrm = slange(
'M', n, n, b, ldb, work )
385 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
388 ELSE IF( bnrm.GT.bignum )
THEN
393 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
400 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
401 $ work( iright ), work( iwrk ), ierr )
405 irows = ihi + 1 - ilo
413 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
414 $ work( iwrk ), lwork+1-iwrk, ierr )
418 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
419 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
420 $ lwork+1-iwrk, ierr )
425 CALL slaset(
'Full', n, n, zero, one, vl, ldvl )
426 IF( irows.GT.1 )
THEN
427 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
428 $ vl( ilo+1, ilo ), ldvl )
430 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
431 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
437 $
CALL slaset(
'Full', n, n, zero, one, vr, ldvr )
445 CALL sgghd3( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
446 $ ldvl, vr, ldvr, work( iwrk ), lwork+1-iwrk, ierr )
448 CALL sgghd3(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
449 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr,
450 $ work( iwrk ), lwork+1-iwrk, ierr )
462 CALL slaqz0( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
463 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
464 $ work( iwrk ), lwork+1-iwrk, 0, ierr )
466 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
468 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
488 CALL stgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl, ldvl,
489 $ vr, ldvr, n, in, work( iwrk ), ierr )
498 CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
499 $ work( iright ), n, vl, ldvl, ierr )
501 IF( alphai( jc ).LT.zero )
504 IF( alphai( jc ).EQ.zero )
THEN
506 temp = max( temp, abs( vl( jr, jc ) ) )
510 temp = max( temp, abs( vl( jr, jc ) )+
511 $ abs( vl( jr, jc+1 ) ) )
517 IF( alphai( jc ).EQ.zero )
THEN
519 vl( jr, jc ) = vl( jr, jc )*temp
523 vl( jr, jc ) = vl( jr, jc )*temp
524 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
530 CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
531 $ work( iright ), n, vr, ldvr, ierr )
533 IF( alphai( jc ).LT.zero )
536 IF( alphai( jc ).EQ.zero )
THEN
538 temp = max( temp, abs( vr( jr, jc ) ) )
542 temp = max( temp, abs( vr( jr, jc ) )+
543 $ abs( vr( jr, jc+1 ) ) )
549 IF( alphai( jc ).EQ.zero )
THEN
551 vr( jr, jc ) = vr( jr, jc )*temp
555 vr( jr, jc ) = vr( jr, jc )*temp
556 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
571 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
572 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
576 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
579 work( 1 ) = sroundup_lwork( lwkopt )
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 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 sgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
SGGHD3
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
recursive subroutine slaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, rec, info)
SLAQZ0
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