223 SUBROUTINE dggev3( 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 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
237 $ B( LDB, * ), BETA( * ), VL( LDVL, * ),
238 $ vr( ldvr, * ), work( * )
244 DOUBLE PRECISION ZERO, ONE
245 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+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 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
264 DOUBLE PRECISION DLAMCH, DLANGE
265 EXTERNAL lsame, dlamch, dlange
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 dgeqrf( n, n, b, ldb, work, work, -1, ierr )
323 lwkopt = max(1, 8*n, 3*n+int( work( 1 ) ) )
324 CALL dormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work, -1,
326 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
328 CALL dorgqr( n, n, n, vl, ldvl, work, work, -1, ierr )
329 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
332 CALL dgghd3( jobvl, jobvr, n, 1, n, a, lda, b, ldb, vl,
333 $ ldvl, vr, ldvr, work, -1, ierr )
334 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
335 CALL dlaqz0(
'S', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
336 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
337 $ work, -1, 0, ierr )
338 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
340 CALL dgghd3(
'N',
'N', n, 1, n, a, lda, b, ldb, vl, ldvl,
341 $ vr, ldvr, work, -1, ierr )
342 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
343 CALL dlaqz0(
'E', jobvl, jobvr, n, 1, n, a, lda, b, ldb,
344 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
345 $ work, -1, 0, ierr )
346 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
353 CALL xerbla(
'DGGEV3 ', -info )
355 ELSE IF( lquery )
THEN
367 smlnum = dlamch(
'S' )
368 bignum = one / smlnum
369 smlnum = sqrt( smlnum ) / eps
370 bignum = one / smlnum
374 anrm = dlange(
'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 dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
388 bnrm = dlange(
'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 dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
405 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
406 $ work( iright ), work( iwrk ), ierr )
410 irows = ihi + 1 - ilo
418 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
419 $ work( iwrk ), lwork+1-iwrk, ierr )
423 CALL dormqr(
'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 dlaset(
'Full', n, n, zero, one, vl, ldvl )
431 IF( irows.GT.1 )
THEN
432 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
433 $ vl( ilo+1, ilo ), ldvl )
435 CALL dorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
436 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
442 $
CALL dlaset(
'Full', n, n, zero, one, vr, ldvr )
450 CALL dgghd3( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
451 $ ldvl, vr, ldvr, work( iwrk ), lwork+1-iwrk, ierr )
453 CALL dgghd3(
'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 dlaqz0( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
468 $ alphar, alphai, beta, vl, ldvl, vr, ldvr,
469 $ work( iwrk ), lwork+1-iwrk, 0, 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 dtgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl, ldvl,
494 $ vr, ldvr, n, in, work( iwrk ), ierr )
503 CALL dggbak(
'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 dggbak(
'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 dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
577 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
581 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
subroutine xerbla(srname, info)
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
DGGBAK
subroutine dggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
DGGBAL
subroutine dggev3(jobvl, jobvr, n, a, lda, b, ldb, alphar, alphai, beta, vl, ldvl, vr, ldvr, work, lwork, info)
DGGEV3 computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices (...
subroutine dgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
DGGHD3
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
recursive subroutine dlaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, rec, info)
DLAQZ0
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dtgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
DTGEVC
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR