279 SUBROUTINE sgges3( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B,
280 $ LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
281 $ VSR, LDVSR, WORK, LWORK, BWORK, INFO )
288 CHARACTER JOBVSL, JOBVSR, SORT
289 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
293 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
294 $ b( ldb, * ), beta( * ), vsl( ldvsl, * ),
295 $ vsr( ldvsr, * ), work( * )
306 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
309 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
310 $ LQUERY, LST2SL, WANTST
311 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
312 $ ILO, IP, IRIGHT, IROWS, ITAU, IWRK, LWKOPT
313 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
314 $ PVSR, SAFMAX, SAFMIN, SMLNUM
326 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
327 EXTERNAL lsame, slamch, slange, sroundup_lwork
330 INTRINSIC abs, max, sqrt
336 IF( lsame( jobvsl,
'N' ) )
THEN
339 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
347 IF( lsame( jobvsr,
'N' ) )
THEN
350 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
358 wantst = lsame( sort,
'S' )
363 lquery = ( lwork.EQ.-1 )
364 IF( ijobvl.LE.0 )
THEN
366 ELSE IF( ijobvr.LE.0 )
THEN
368 ELSE IF( ( .NOT.wantst ) .AND. ( .NOT.lsame( sort,
'N' ) ) )
THEN
370 ELSE IF( n.LT.0 )
THEN
372 ELSE IF( lda.LT.max( 1, n ) )
THEN
374 ELSE IF( ldb.LT.max( 1, n ) )
THEN
376 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
378 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
380 ELSE IF( lwork.LT.6*n+16 .AND. .NOT.lquery )
THEN
387 CALL sgeqrf( n, n, b, ldb, work, work, -1, ierr )
388 lwkopt = max( 6*n+16, 3*n+int( work( 1 ) ) )
389 CALL sormqr(
'L',
'T', n, n, n, b, ldb, work, a, lda, work,
391 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
393 CALL sorgqr( n, n, n, vsl, ldvsl, work, work, -1, ierr )
394 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
396 CALL sgghd3( jobvsl, jobvsr, n, 1, n, a, lda, b, ldb, vsl,
397 $ ldvsl, vsr, ldvsr, work, -1, ierr )
398 lwkopt = max( lwkopt, 3*n+int( work( 1 ) ) )
399 CALL slaqz0(
'S', jobvsl, jobvsr, n, 1, n, a, lda, b, ldb,
400 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
401 $ work, -1, 0, ierr )
402 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
404 CALL stgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
405 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
406 $ sdim, pvsl, pvsr, dif, work, -1, idum, 1,
408 lwkopt = max( lwkopt, 2*n+int( work( 1 ) ) )
410 work( 1 ) = sroundup_lwork(lwkopt)
414 CALL xerbla(
'SGGES3 ', -info )
416 ELSE IF( lquery )
THEN
430 safmin = slamch(
'S' )
431 safmax = one / safmin
432 smlnum = sqrt( safmin ) / eps
433 bignum = one / smlnum
437 anrm = slange(
'M', n, n, a, lda, work )
439 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
442 ELSE IF( anrm.GT.bignum )
THEN
447 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
451 bnrm = slange(
'M', n, n, b, ldb, work )
453 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
456 ELSE IF( bnrm.GT.bignum )
THEN
461 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
468 CALL sggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
469 $ work( iright ), work( iwrk ), ierr )
473 irows = ihi + 1 - ilo
477 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
478 $ work( iwrk ), lwork+1-iwrk, ierr )
482 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
483 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
484 $ lwork+1-iwrk, ierr )
489 CALL slaset(
'Full', n, n, zero, one, vsl, ldvsl )
490 IF( irows.GT.1 )
THEN
491 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
492 $ vsl( ilo+1, ilo ), ldvsl )
494 CALL sorgqr( irows, irows, irows, vsl( ilo, ilo ), ldvsl,
495 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
501 $
CALL slaset(
'Full', n, n, zero, one, vsr, ldvsr )
505 CALL sgghd3( jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb, vsl,
506 $ ldvsl, vsr, ldvsr, work( iwrk ), lwork+1-iwrk, ierr )
511 CALL slaqz0(
'S', jobvsl, jobvsr, n, ilo, ihi, a, lda, b, ldb,
512 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
513 $ work( iwrk ), lwork+1-iwrk, 0, ierr )
515 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
517 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
533 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
535 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
539 $
CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
544 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
547 CALL stgsen( 0, ilvsl, ilvsr, bwork, n, a, lda, b, ldb, alphar,
548 $ alphai, beta, vsl, ldvsl, vsr, ldvsr, sdim, pvsl,
549 $ pvsr, dif, work( iwrk ), lwork-iwrk+1, idum, 1,
559 $
CALL sggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
560 $ work( iright ), n, vsl, ldvsl, ierr )
563 $
CALL sggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
564 $ work( iright ), n, vsr, ldvsr, ierr )
572 IF( alphai( i ).NE.zero )
THEN
573 IF( ( alphar( i )/safmax ).GT.( anrmto/anrm ) .OR.
574 $ ( safmin/alphar( i ) ).GT.( anrm/anrmto ) )
THEN
575 work( 1 ) = abs( a( i, i )/alphar( i ) )
576 beta( i ) = beta( i )*work( 1 )
577 alphar( i ) = alphar( i )*work( 1 )
578 alphai( i ) = alphai( i )*work( 1 )
579 ELSE IF( ( alphai( i )/safmax ).GT.( anrmto/anrm ) .OR.
580 $ ( safmin/alphai( i ) ).GT.( anrm/anrmto ) )
THEN
581 work( 1 ) = abs( a( i, i+1 )/alphai( i ) )
582 beta( i ) = beta( i )*work( 1 )
583 alphar( i ) = alphar( i )*work( 1 )
584 alphai( i ) = alphai( i )*work( 1 )
592 IF( alphai( i ).NE.zero )
THEN
593 IF( ( beta( i )/safmax ).GT.( bnrmto/bnrm ) .OR.
594 $ ( safmin/beta( i ) ).GT.( bnrm/bnrmto ) )
THEN
595 work( 1 ) = abs(b( i, i )/beta( i ))
596 beta( i ) = beta( i )*work( 1 )
597 alphar( i ) = alphar( i )*work( 1 )
598 alphai( i ) = alphai( i )*work( 1 )
607 CALL slascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
608 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
609 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
613 CALL slascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
614 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
626 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
627 IF( alphai( i ).EQ.zero )
THEN
631 IF( cursl .AND. .NOT.lastsl )
638 cursl = cursl .OR. lastsl
643 IF( cursl .AND. .NOT.lst2sl )
660 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 sgges3(jobvsl, jobvsr, sort, selctg, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, work, lwork, bwork, info)
SGGES3 computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...
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 stgsen(ijob, wantq, wantz, select, n, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, m, pl, pr, dif, work, lwork, iwork, liwork, info)
STGSEN
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