diff --git a/SRC/chbevx.f b/SRC/chbevx.f index 439d85a70..8ff2aa2fe 100644 --- a/SRC/chbevx.f +++ b/SRC/chbevx.f @@ -296,7 +296,7 @@ SUBROUTINE CHBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDWRK, ISCALE, ITMP1, $ J, JJ, NSPLIT REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -415,8 +415,11 @@ SUBROUTINE CHBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -517,14 +520,8 @@ SUBROUTINE CHBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/chbevx_2stage.f b/SRC/chbevx_2stage.f index c05adc455..9398baf1f 100644 --- a/SRC/chbevx_2stage.f +++ b/SRC/chbevx_2stage.f @@ -357,7 +357,7 @@ SUBROUTINE CHBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ, $ LQUERY CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDWRK, ISCALE, ITMP1, $ LLWORK, LWMIN, LHTRD, LWTRD, IB, INDHOUS, $ J, JJ, NSPLIT @@ -501,8 +501,11 @@ SUBROUTINE CHBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -608,14 +611,8 @@ SUBROUTINE CHBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/cheevr.f b/SRC/cheevr.f index bab9353f8..c8d8179d4 100644 --- a/SRC/cheevr.f +++ b/SRC/cheevr.f @@ -398,7 +398,7 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ, TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP, + INTEGER I, IEEEOK, IINFO, INDIBL, INDIFL, INDISP, $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK, $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ, $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN, @@ -549,8 +549,11 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -700,14 +703,8 @@ SUBROUTINE CHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/cheevr_2stage.f b/SRC/cheevr_2stage.f index 5bd16f449..f2ac021c7 100644 --- a/SRC/cheevr_2stage.f +++ b/SRC/cheevr_2stage.f @@ -433,7 +433,7 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ, TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP, + INTEGER I, IEEEOK, IINFO, INDIBL, INDIFL, INDISP, $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK, $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ, $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN, @@ -590,8 +590,11 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -744,14 +747,8 @@ SUBROUTINE CHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/cheevx.f b/SRC/cheevx.f index 54324830e..15d24ce64 100644 --- a/SRC/cheevx.f +++ b/SRC/cheevx.f @@ -287,7 +287,7 @@ SUBROUTINE CHEEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, LWKMIN, LWKOPT, NB, $ NSPLIT @@ -419,8 +419,11 @@ SUBROUTINE CHEEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -525,14 +528,8 @@ SUBROUTINE CHEEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/cheevx_2stage.f b/SRC/cheevx_2stage.f index 5b93c5aab..cde12aa1d 100644 --- a/SRC/cheevx_2stage.f +++ b/SRC/cheevx_2stage.f @@ -334,7 +334,7 @@ SUBROUTINE CHEEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, $ NSPLIT, LWMIN, LHTRD, LWTRD, KD, IB, INDHOUS @@ -470,8 +470,11 @@ SUBROUTINE CHEEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -580,14 +583,8 @@ SUBROUTINE CHEEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/chpevx.f b/SRC/chpevx.f index 7bf5510b3..428084bf3 100644 --- a/SRC/chpevx.f +++ b/SRC/chpevx.f @@ -266,7 +266,7 @@ SUBROUTINE CHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, + INTEGER I, IINFO, INDD, INDE, INDEE, $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE, $ ITMP1, J, JJ, NSPLIT REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -373,8 +373,11 @@ SUBROUTINE CHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL CSSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 ) @@ -469,14 +472,8 @@ SUBROUTINE CHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 20 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/cstein.f b/SRC/cstein.f index 1040fe888..974b79040 100644 --- a/SRC/cstein.f +++ b/SRC/cstein.f @@ -95,6 +95,8 @@ *> the first submatrix from the top, =2 if W(i) belongs to *> the second submatrix, etc. ( The output array IBLOCK *> from SSTEBZ is expected here. ) +*> A negative entry, with which SSTEBZ flags an eigenvalue that +*> did not converge, is treated as its absolute value. *> \endverbatim *> *> \param[in] ISPLIT @@ -244,11 +246,12 @@ SUBROUTINE CSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, INFO = -9 ELSE DO 20 J = 2, M - IF( IBLOCK( J ).LT.IBLOCK( J-1 ) ) THEN + IF( ABS( IBLOCK( J ) ).LT.ABS( IBLOCK( J-1 ) ) ) THEN INFO = -6 GO TO 30 END IF - IF( IBLOCK( J ).EQ.IBLOCK( J-1 ) .AND. W( J ).LT.W( J-1 ) ) + IF( ABS( IBLOCK( J ) ).EQ.ABS( IBLOCK( J-1 ) ) .AND. + $ W( J ).LT.W( J-1 ) ) $ THEN INFO = -5 GO TO 30 @@ -292,7 +295,7 @@ SUBROUTINE CSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, * Compute eigenvectors of matrix blocks. * J1 = 1 - DO 180 NBLK = 1, IBLOCK( M ) + DO 180 NBLK = 1, ABS( IBLOCK( M ) ) * * Find starting and ending indices of block nblk. * @@ -324,7 +327,7 @@ SUBROUTINE CSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, 60 CONTINUE JBLK = 0 DO 170 J = J1, M - IF( IBLOCK( J ).NE.NBLK ) THEN + IF( ABS( IBLOCK( J ) ).NE.NBLK ) THEN J1 = J GO TO 180 END IF diff --git a/SRC/dsbevx.f b/SRC/dsbevx.f index 6b29432e0..20ea91e78 100644 --- a/SRC/dsbevx.f +++ b/SRC/dsbevx.f @@ -290,7 +290,7 @@ SUBROUTINE DSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDWRK, ISCALE, ITMP1, J, JJ, $ NSPLIT DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -406,8 +406,11 @@ SUBROUTINE DSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -507,14 +510,8 @@ SUBROUTINE DSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/dsbevx_2stage.f b/SRC/dsbevx_2stage.f index 233a7121e..b54675f35 100644 --- a/SRC/dsbevx_2stage.f +++ b/SRC/dsbevx_2stage.f @@ -349,7 +349,7 @@ SUBROUTINE DSBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ, $ LQUERY CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDWRK, ISCALE, ITMP1, J, JJ, $ LLWORK, LWMIN, LHTRD, LWTRD, IB, INDHOUS, $ NSPLIT @@ -490,8 +490,11 @@ SUBROUTINE DSBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -596,14 +599,8 @@ SUBROUTINE DSBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/dspevx.f b/SRC/dspevx.f index 6eaff9b17..11c71990f 100644 --- a/SRC/dspevx.f +++ b/SRC/dspevx.f @@ -257,7 +257,7 @@ SUBROUTINE DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, + INTEGER I, IINFO, INDD, INDE, INDEE, $ INDISP, INDIWO, INDTAU, INDWRK, ISCALE, ITMP1, $ J, JJ, NSPLIT DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -364,8 +364,11 @@ SUBROUTINE DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 ) @@ -458,14 +461,8 @@ SUBROUTINE DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 20 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/dstein.f b/SRC/dstein.f index 02de3a0b3..bb7eb0eb3 100644 --- a/SRC/dstein.f +++ b/SRC/dstein.f @@ -88,6 +88,8 @@ *> the first submatrix from the top, =2 if W(i) belongs to *> the second submatrix, etc. ( The output array IBLOCK *> from DSTEBZ is expected here. ) +*> A negative entry, with which DSTEBZ flags an eigenvalue that +*> did not converge, is treated as its absolute value. *> \endverbatim *> *> \param[in] ISPLIT @@ -233,11 +235,12 @@ SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, INFO = -9 ELSE DO 20 J = 2, M - IF( IBLOCK( J ).LT.IBLOCK( J-1 ) ) THEN + IF( ABS( IBLOCK( J ) ).LT.ABS( IBLOCK( J-1 ) ) ) THEN INFO = -6 GO TO 30 END IF - IF( IBLOCK( J ).EQ.IBLOCK( J-1 ) .AND. W( J ).LT.W( J-1 ) ) + IF( ABS( IBLOCK( J ) ).EQ.ABS( IBLOCK( J-1 ) ) .AND. + $ W( J ).LT.W( J-1 ) ) $ THEN INFO = -5 GO TO 30 @@ -281,7 +284,7 @@ SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, * Compute eigenvectors of matrix blocks. * J1 = 1 - DO 160 NBLK = 1, IBLOCK( M ) + DO 160 NBLK = 1, ABS( IBLOCK( M ) ) * * Find starting and ending indices of block nblk. * @@ -313,7 +316,7 @@ SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, 60 CONTINUE JBLK = 0 DO 150 J = J1, M - IF( IBLOCK( J ).NE.NBLK ) THEN + IF( ABS( IBLOCK( J ) ).NE.NBLK ) THEN J1 = J GO TO 160 END IF diff --git a/SRC/dstevr.f b/SRC/dstevr.f index d75afcb37..87548af61 100644 --- a/SRC/dstevr.f +++ b/SRC/dstevr.f @@ -326,7 +326,7 @@ SUBROUTINE DSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, LOGICAL ALLEIG, INDEIG, TEST, LQUERY, VALEIG, WANTZ, $ TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IMAX, INDIBL, INDIFL, INDISP, + INTEGER I, IEEEOK, INDIBL, INDIFL, INDISP, $ INDIWO, ISCALE, ITMP1, J, JJ, LIWMIN, LWMIN, $ NSPLIT DOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM, @@ -450,8 +450,11 @@ SUBROUTINE DSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / TNRM ELSE IF( TNRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / TNRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL DSCAL( N, SIGMA, D, 1 ) @@ -537,14 +540,8 @@ SUBROUTINE DSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 10 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/dstevx.f b/SRC/dstevx.f index e18c03265..e9ddbd806 100644 --- a/SRC/dstevx.f +++ b/SRC/dstevx.f @@ -251,7 +251,7 @@ SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDISP, INDIWO, INDWRK, + INTEGER I, IINFO, INDISP, INDIWO, INDWRK, $ ISCALE, ITMP1, J, JJ, NSPLIT DOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM, $ TMP1, TNRM, VLL, VUU @@ -352,8 +352,11 @@ SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / TNRM ELSE IF( TNRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / TNRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL DSCAL( N, SIGMA, D, 1 ) @@ -427,14 +430,8 @@ SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 20 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/dsyevr.f b/SRC/dsyevr.f index 92166fa1b..caa54cda3 100644 --- a/SRC/dsyevr.f +++ b/SRC/dsyevr.f @@ -371,7 +371,7 @@ SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, VALEIG, WANTZ, $ TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDD, INDDD, INDE, + INTEGER I, IEEEOK, IINFO, INDD, INDDD, INDE, $ INDEE, INDIBL, INDIFL, INDISP, INDIWO, INDTAU, $ INDWK, INDWKN, ISCALE, J, JJ, LIWMIN, $ LLWORK, LLWRKN, LWKOPT, LWMIN, NB, NSPLIT @@ -511,8 +511,11 @@ SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -655,14 +658,8 @@ SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * * Jump here if DSTEMR/DSTEIN succeeded. 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. Note: We do not sort the IFAIL portion of IWORK. diff --git a/SRC/dsyevr_2stage.f b/SRC/dsyevr_2stage.f index 180800e26..f09a137b3 100644 --- a/SRC/dsyevr_2stage.f +++ b/SRC/dsyevr_2stage.f @@ -405,7 +405,7 @@ SUBROUTINE DSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, VALEIG, WANTZ, $ TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDD, INDDD, INDE, + INTEGER I, IEEEOK, IINFO, INDD, INDDD, INDE, $ INDEE, INDIBL, INDIFL, INDISP, INDIWO, INDTAU, $ INDWK, INDWKN, ISCALE, J, JJ, LIWMIN, $ LLWORK, LLWRKN, LWMIN, NSPLIT, @@ -556,8 +556,11 @@ SUBROUTINE DSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -705,14 +708,8 @@ SUBROUTINE DSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * * Jump here if DSTEMR/DSTEIN succeeded. 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. Note: We do not sort the IFAIL portion of IWORK. diff --git a/SRC/dsyevx.f b/SRC/dsyevx.f index 84dfe289d..ac3bf7d28 100644 --- a/SRC/dsyevx.f +++ b/SRC/dsyevx.f @@ -278,7 +278,7 @@ SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, LLWRKN, LWKMIN, $ LWKOPT, NB, NSPLIT @@ -407,8 +407,11 @@ SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -514,14 +517,8 @@ SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/dsyevx_2stage.f b/SRC/dsyevx_2stage.f index 4b5519be9..cdbb7e2c1 100644 --- a/SRC/dsyevx_2stage.f +++ b/SRC/dsyevx_2stage.f @@ -325,7 +325,7 @@ SUBROUTINE DSYEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, LLWRKN, $ NSPLIT, LWMIN, LHTRD, LWTRD, KD, IB, INDHOUS @@ -459,8 +459,11 @@ SUBROUTINE DSYEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -569,14 +572,8 @@ SUBROUTINE DSYEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/ssbevx.f b/SRC/ssbevx.f index 313616e7d..c7080f906 100644 --- a/SRC/ssbevx.f +++ b/SRC/ssbevx.f @@ -290,7 +290,7 @@ SUBROUTINE SSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDWRK, ISCALE, ITMP1, J, JJ, $ NSPLIT REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -406,8 +406,11 @@ SUBROUTINE SSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -507,14 +510,8 @@ SUBROUTINE SSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/ssbevx_2stage.f b/SRC/ssbevx_2stage.f index 228839cb5..d70644ca2 100644 --- a/SRC/ssbevx_2stage.f +++ b/SRC/ssbevx_2stage.f @@ -349,7 +349,7 @@ SUBROUTINE SSBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ, $ LQUERY CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDWRK, ISCALE, ITMP1, J, JJ, $ LLWORK, LWMIN, LHTRD, LWTRD, IB, INDHOUS, $ NSPLIT @@ -491,8 +491,11 @@ SUBROUTINE SSBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -597,14 +600,8 @@ SUBROUTINE SSBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/sspevx.f b/SRC/sspevx.f index 375a6a223..ca602d8c7 100644 --- a/SRC/sspevx.f +++ b/SRC/sspevx.f @@ -257,7 +257,7 @@ SUBROUTINE SSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, + INTEGER I, IINFO, INDD, INDE, INDEE, $ INDISP, INDIWO, INDTAU, INDWRK, ISCALE, ITMP1, $ J, JJ, NSPLIT REAL ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -364,8 +364,11 @@ SUBROUTINE SSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL SSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 ) @@ -458,14 +461,8 @@ SUBROUTINE SSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 20 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/sstein.f b/SRC/sstein.f index 471d31220..72d550730 100644 --- a/SRC/sstein.f +++ b/SRC/sstein.f @@ -88,6 +88,8 @@ *> the first submatrix from the top, =2 if W(i) belongs to *> the second submatrix, etc. ( The output array IBLOCK *> from SSTEBZ is expected here. ) +*> A negative entry, with which SSTEBZ flags an eigenvalue that +*> did not converge, is treated as its absolute value. *> \endverbatim *> *> \param[in] ISPLIT @@ -233,11 +235,12 @@ SUBROUTINE SSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, INFO = -9 ELSE DO 20 J = 2, M - IF( IBLOCK( J ).LT.IBLOCK( J-1 ) ) THEN + IF( ABS( IBLOCK( J ) ).LT.ABS( IBLOCK( J-1 ) ) ) THEN INFO = -6 GO TO 30 END IF - IF( IBLOCK( J ).EQ.IBLOCK( J-1 ) .AND. W( J ).LT.W( J-1 ) ) + IF( ABS( IBLOCK( J ) ).EQ.ABS( IBLOCK( J-1 ) ) .AND. + $ W( J ).LT.W( J-1 ) ) $ THEN INFO = -5 GO TO 30 @@ -281,7 +284,7 @@ SUBROUTINE SSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, * Compute eigenvectors of matrix blocks. * J1 = 1 - DO 160 NBLK = 1, IBLOCK( M ) + DO 160 NBLK = 1, ABS( IBLOCK( M ) ) * * Find starting and ending indices of block nblk. * @@ -313,7 +316,7 @@ SUBROUTINE SSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, 60 CONTINUE JBLK = 0 DO 150 J = J1, M - IF( IBLOCK( J ).NE.NBLK ) THEN + IF( ABS( IBLOCK( J ) ).NE.NBLK ) THEN J1 = J GO TO 160 END IF diff --git a/SRC/sstevr.f b/SRC/sstevr.f index 0b72c2f0e..51dac1c90 100644 --- a/SRC/sstevr.f +++ b/SRC/sstevr.f @@ -328,7 +328,7 @@ SUBROUTINE SSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, LOGICAL ALLEIG, INDEIG, TEST, LQUERY, VALEIG, WANTZ, $ TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IMAX, INDIBL, INDIFL, INDISP, + INTEGER I, IEEEOK, INDIBL, INDIFL, INDISP, $ INDIWO, ISCALE, J, JJ, LIWMIN, LWMIN, NSPLIT REAL BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM, $ TMP1, TNRM, VLL, VUU @@ -452,8 +452,11 @@ SUBROUTINE SSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / TNRM ELSE IF( TNRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / TNRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL SSCAL( N, SIGMA, D, 1 ) @@ -539,14 +542,8 @@ SUBROUTINE SSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 10 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/sstevx.f b/SRC/sstevx.f index f84e740ef..51c563109 100644 --- a/SRC/sstevx.f +++ b/SRC/sstevx.f @@ -251,7 +251,7 @@ SUBROUTINE SSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDISP, INDIWO, INDWRK, + INTEGER I, IINFO, INDISP, INDIWO, INDWRK, $ ISCALE, ITMP1, J, JJ, NSPLIT REAL BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM, $ TMP1, TNRM, VLL, VUU @@ -352,8 +352,11 @@ SUBROUTINE SSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / TNRM ELSE IF( TNRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / TNRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL SSCAL( N, SIGMA, D, 1 ) @@ -427,14 +430,8 @@ SUBROUTINE SSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 20 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/ssyevr.f b/SRC/ssyevr.f index 6a848bb1c..cbe3e71ae 100644 --- a/SRC/ssyevr.f +++ b/SRC/ssyevr.f @@ -373,7 +373,7 @@ SUBROUTINE SSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ, TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDD, INDDD, INDE, + INTEGER I, IEEEOK, IINFO, INDD, INDDD, INDE, $ INDEE, INDIBL, INDIFL, INDISP, INDIWO, INDTAU, $ INDWK, INDWKN, ISCALE, J, JJ, LIWMIN, $ LLWORK, LLWRKN, LWKOPT, LWMIN, NB, NSPLIT @@ -516,8 +516,11 @@ SUBROUTINE SSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -665,14 +668,8 @@ SUBROUTINE SSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * * Jump here if SSTEMR/SSTEIN succeeded. 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. Note: We do not sort the IFAIL portion of IWORK. diff --git a/SRC/ssyevr_2stage.f b/SRC/ssyevr_2stage.f index 63f002388..47d82f308 100644 --- a/SRC/ssyevr_2stage.f +++ b/SRC/ssyevr_2stage.f @@ -405,7 +405,7 @@ SUBROUTINE SSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, VALEIG, WANTZ, $ TRYRAC, TEST CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDD, INDDD, INDE, + INTEGER I, IEEEOK, IINFO, INDD, INDDD, INDE, $ INDEE, INDIBL, INDIFL, INDISP, INDIWO, INDTAU, $ INDWK, INDWKN, ISCALE, J, JJ, LIWMIN, $ LLWORK, LLWRKN, LWMIN, NSPLIT, @@ -557,8 +557,11 @@ SUBROUTINE SSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -711,14 +714,8 @@ SUBROUTINE SSYEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * * Jump here if SSTEMR/SSTEIN succeeded. 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. Note: We do not sort the IFAIL portion of IWORK. diff --git a/SRC/ssyevx.f b/SRC/ssyevx.f index 9528c66fc..857e61da0 100644 --- a/SRC/ssyevx.f +++ b/SRC/ssyevx.f @@ -278,7 +278,7 @@ SUBROUTINE SSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, LLWRKN, LWKMIN, $ LWKOPT, NB, NSPLIT @@ -408,8 +408,11 @@ SUBROUTINE SSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -515,14 +518,8 @@ SUBROUTINE SSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/ssyevx_2stage.f b/SRC/ssyevx_2stage.f index 8a1fc2798..a0338bac8 100644 --- a/SRC/ssyevx_2stage.f +++ b/SRC/ssyevx_2stage.f @@ -325,7 +325,7 @@ SUBROUTINE SSYEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, LLWRKN, $ NSPLIT, LWMIN, LHTRD, LWTRD, KD, IB, INDHOUS @@ -460,8 +460,11 @@ SUBROUTINE SSYEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -570,14 +573,8 @@ SUBROUTINE SSYEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL SSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL SSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zhbevx.f b/SRC/zhbevx.f index 22487eb27..938789384 100644 --- a/SRC/zhbevx.f +++ b/SRC/zhbevx.f @@ -296,7 +296,7 @@ SUBROUTINE ZHBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDWRK, ISCALE, ITMP1, $ J, JJ, NSPLIT DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -415,8 +415,11 @@ SUBROUTINE ZHBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -517,14 +520,8 @@ SUBROUTINE ZHBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zhbevx_2stage.f b/SRC/zhbevx_2stage.f index a22b589f5..bfc6e542a 100644 --- a/SRC/zhbevx_2stage.f +++ b/SRC/zhbevx_2stage.f @@ -357,7 +357,7 @@ SUBROUTINE ZHBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ, $ LQUERY CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDWRK, ISCALE, ITMP1, $ LLWORK, LWMIN, LHTRD, LWTRD, IB, INDHOUS, $ J, JJ, NSPLIT @@ -500,8 +500,11 @@ SUBROUTINE ZHBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -607,14 +610,8 @@ SUBROUTINE ZHBEVX_2STAGE( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zheevr.f b/SRC/zheevr.f index 038738ec8..cf77d1c2b 100644 --- a/SRC/zheevr.f +++ b/SRC/zheevr.f @@ -398,7 +398,7 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ, TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP, + INTEGER I, IEEEOK, IINFO, INDIBL, INDIFL, INDISP, $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK, $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ, $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN, @@ -548,8 +548,11 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -699,14 +702,8 @@ SUBROUTINE ZHEEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zheevr_2stage.f b/SRC/zheevr_2stage.f index 0ba5a2953..4553203a7 100644 --- a/SRC/zheevr_2stage.f +++ b/SRC/zheevr_2stage.f @@ -433,7 +433,7 @@ SUBROUTINE ZHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ, TRYRAC CHARACTER ORDER - INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP, + INTEGER I, IEEEOK, IINFO, INDIBL, INDIFL, INDISP, $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK, $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ, $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN, @@ -590,8 +590,11 @@ SUBROUTINE ZHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -744,14 +747,8 @@ SUBROUTINE ZHEEVR_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * If matrix was scaled, then rescale eigenvalues appropriately. * 30 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zheevx.f b/SRC/zheevx.f index f7f58932f..29699b8fb 100644 --- a/SRC/zheevx.f +++ b/SRC/zheevx.f @@ -287,7 +287,7 @@ SUBROUTINE ZHEEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, LWKMIN, LWKOPT, NB, $ NSPLIT @@ -418,8 +418,11 @@ SUBROUTINE ZHEEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -524,14 +527,8 @@ SUBROUTINE ZHEEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zheevx_2stage.f b/SRC/zheevx_2stage.f index 1b0a22d27..a9a7e5929 100644 --- a/SRC/zheevx_2stage.f +++ b/SRC/zheevx_2stage.f @@ -334,7 +334,7 @@ SUBROUTINE ZHEEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, $ WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE, $ ITMP1, J, JJ, LLWORK, $ NSPLIT, LWMIN, LHTRD, LWTRD, KD, IB, INDHOUS @@ -469,8 +469,11 @@ SUBROUTINE ZHEEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN IF( LOWER ) THEN @@ -579,14 +582,8 @@ SUBROUTINE ZHEEVX_2STAGE( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, * If matrix was scaled, then rescale eigenvalues appropriately. * 40 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zhpevx.f b/SRC/zhpevx.f index 3a60e8fd6..a3a5bcfe9 100644 --- a/SRC/zhpevx.f +++ b/SRC/zhpevx.f @@ -266,7 +266,7 @@ SUBROUTINE ZHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * .. Local Scalars .. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ CHARACTER ORDER - INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, + INTEGER I, IINFO, INDD, INDE, INDEE, $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE, $ ITMP1, J, JJ, NSPLIT DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, @@ -373,8 +373,11 @@ SUBROUTINE ZHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN - ISCALE = 1 +* An infinite norm gives SIGMA = 0; leave such a matrix +* unscaled so that VL and VU remain a valid interval. SIGMA = RMAX / ANRM + IF( SIGMA.GT.ZERO ) + $ ISCALE = 1 END IF IF( ISCALE.EQ.1 ) THEN CALL ZDSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 ) @@ -469,14 +472,8 @@ SUBROUTINE ZHPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, * If matrix was scaled, then rescale eigenvalues appropriately. * 20 CONTINUE - IF( ISCALE.EQ.1 ) THEN - IF( INFO.EQ.0 ) THEN - IMAX = M - ELSE - IMAX = INFO - 1 - END IF - CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) - END IF + IF( ISCALE.EQ.1 ) + $ CALL DSCAL( M, ONE / SIGMA, W, 1 ) * * If eigenvalues are not in order, then sort them, along with * eigenvectors. diff --git a/SRC/zstein.f b/SRC/zstein.f index ca408fe70..a00c088c1 100644 --- a/SRC/zstein.f +++ b/SRC/zstein.f @@ -95,6 +95,8 @@ *> the first submatrix from the top, =2 if W(i) belongs to *> the second submatrix, etc. ( The output array IBLOCK *> from DSTEBZ is expected here. ) +*> A negative entry, with which DSTEBZ flags an eigenvalue that +*> did not converge, is treated as its absolute value. *> \endverbatim *> *> \param[in] ISPLIT @@ -244,11 +246,12 @@ SUBROUTINE ZSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, INFO = -9 ELSE DO 20 J = 2, M - IF( IBLOCK( J ).LT.IBLOCK( J-1 ) ) THEN + IF( ABS( IBLOCK( J ) ).LT.ABS( IBLOCK( J-1 ) ) ) THEN INFO = -6 GO TO 30 END IF - IF( IBLOCK( J ).EQ.IBLOCK( J-1 ) .AND. W( J ).LT.W( J-1 ) ) + IF( ABS( IBLOCK( J ) ).EQ.ABS( IBLOCK( J-1 ) ) .AND. + $ W( J ).LT.W( J-1 ) ) $ THEN INFO = -5 GO TO 30 @@ -292,7 +295,7 @@ SUBROUTINE ZSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, * Compute eigenvectors of matrix blocks. * J1 = 1 - DO 180 NBLK = 1, IBLOCK( M ) + DO 180 NBLK = 1, ABS( IBLOCK( M ) ) * * Find starting and ending indices of block nblk. * @@ -324,7 +327,7 @@ SUBROUTINE ZSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, 60 CONTINUE JBLK = 0 DO 170 J = J1, M - IF( IBLOCK( J ).NE.NBLK ) THEN + IF( ABS( IBLOCK( J ) ).NE.NBLK ) THEN J1 = J GO TO 180 END IF diff --git a/TESTING/EIG/derrst.f b/TESTING/EIG/derrst.f index 94018743f..3662873a9 100644 --- a/TESTING/EIG/derrst.f +++ b/TESTING/EIG/derrst.f @@ -86,6 +86,7 @@ SUBROUTINE DERRST( PATH, NUNIT ) $ E( NMAX ), Q( NMAX, NMAX ), R( NMAX ), $ TAU( NMAX ), W( LW ), X( NMAX ), $ Z( NMAX, NMAX ) + DOUBLE PRECISION RINF, RZERO * .. * .. External Functions .. LOGICAL LSAMEN @@ -439,6 +440,49 @@ SUBROUTINE DERRST( PATH, NUNIT ) CALL CHKXER( 'DSTEIN', INFOT, NOUT, LERR, OK ) NT = NT + 4 * +* A matrix that holds an infinity must come back from the +* drivers that scale it, instead of reaching XERBLA with a +* scale factor of zero. +* + RZERO = 0.0D0 + RINF = 1.0D0 / RZERO + DO 50 J = 1, NMAX + D( J ) = DBLE( J ) + E( J ) = 1.0D0 / DBLE( J+1 ) + DO 40 I = 1, NMAX + A( I, J ) = RZERO + 40 CONTINUE + A( J, J ) = D( J ) + 50 CONTINUE + D( 1 ) = RINF + A( 1, 1 ) = RINF + E( NMAX ) = RZERO + A( 1, 2 ) = E( 1 ) + A( 2, 3 ) = E( 2 ) + SRNAMT = 'DSTEVX' + INFOT = 0 + LERR = .FALSE. + CALL DSTEVX( 'V', 'V', NMAX, D, E, RZERO, 1.0D0, 1, NMAX, + $ RZERO, M, X, Z, NMAX, W, IW, I3, INFO ) + IF( LERR ) THEN + WRITE( NOUT, FMT = 9997 )'DSTEVX' + OK = .FALSE. + END IF + D( 1 ) = RINF + E( 1 ) = 1.0D0 / DBLE( 2 ) + E( 2 ) = 1.0D0 / DBLE( 3 ) + E( NMAX ) = RZERO + SRNAMT = 'DSYEVX' + INFOT = 0 + LERR = .FALSE. + CALL DSYEVX( 'V', 'V', 'U', NMAX, A, NMAX, RZERO, 1.0D0, 1, + $ NMAX, RZERO, M, X, Z, NMAX, W, LW, IW, I3, INFO ) + IF( LERR ) THEN + WRITE( NOUT, FMT = 9997 )'DSYEVX' + OK = .FALSE. + END IF + NT = NT + 2 +* * DSTEQR * SRNAMT = 'DSTEQR' @@ -1427,6 +1471,8 @@ SUBROUTINE DERRST( PATH, NUNIT ) $ ' (', I3, ' tests done)' ) 9998 FORMAT( ' *** ', A3, ' routines failed the tests of the error ', $ 'exits ***' ) + 9997 FORMAT( ' *** ', A6, ' called XERBLA for a matrix with an ', + $ 'infinity ***' ) * RETURN * diff --git a/TESTING/EIG/serrst.f b/TESTING/EIG/serrst.f index 471fa3599..642a0648c 100644 --- a/TESTING/EIG/serrst.f +++ b/TESTING/EIG/serrst.f @@ -86,6 +86,7 @@ SUBROUTINE SERRST( PATH, NUNIT ) $ E( NMAX ), Q( NMAX, NMAX ), R( NMAX ), $ TAU( NMAX ), W( LW ), X( NMAX ), $ Z( NMAX, NMAX ) + REAL RINF, RZERO * .. * .. External Functions .. LOGICAL LSAMEN @@ -439,6 +440,49 @@ SUBROUTINE SERRST( PATH, NUNIT ) CALL CHKXER( 'SSTEIN', INFOT, NOUT, LERR, OK ) NT = NT + 4 * +* A matrix that holds an infinity must come back from the +* drivers that scale it, instead of reaching XERBLA with a +* scale factor of zero. +* + RZERO = 0.0E0 + RINF = 1.0E0 / RZERO + DO 50 J = 1, NMAX + D( J ) = REAL( J ) + E( J ) = 1.0E0 / REAL( J+1 ) + DO 40 I = 1, NMAX + A( I, J ) = RZERO + 40 CONTINUE + A( J, J ) = D( J ) + 50 CONTINUE + D( 1 ) = RINF + A( 1, 1 ) = RINF + E( NMAX ) = RZERO + A( 1, 2 ) = E( 1 ) + A( 2, 3 ) = E( 2 ) + SRNAMT = 'SSTEVX' + INFOT = 0 + LERR = .FALSE. + CALL SSTEVX( 'V', 'V', NMAX, D, E, RZERO, 1.0E0, 1, NMAX, + $ RZERO, M, X, Z, NMAX, W, IW, I3, INFO ) + IF( LERR ) THEN + WRITE( NOUT, FMT = 9997 )'SSTEVX' + OK = .FALSE. + END IF + D( 1 ) = RINF + E( 1 ) = 1.0E0 / REAL( 2 ) + E( 2 ) = 1.0E0 / REAL( 3 ) + E( NMAX ) = RZERO + SRNAMT = 'SSYEVX' + INFOT = 0 + LERR = .FALSE. + CALL SSYEVX( 'V', 'V', 'U', NMAX, A, NMAX, RZERO, 1.0E0, 1, + $ NMAX, RZERO, M, X, Z, NMAX, W, LW, IW, I3, INFO ) + IF( LERR ) THEN + WRITE( NOUT, FMT = 9997 )'SSYEVX' + OK = .FALSE. + END IF + NT = NT + 2 +* * SSTEQR * SRNAMT = 'SSTEQR' @@ -1425,6 +1469,8 @@ SUBROUTINE SERRST( PATH, NUNIT ) $ ' (', I3, ' tests done)' ) 9998 FORMAT( ' *** ', A3, ' routines failed the tests of the error ', $ 'exits ***' ) + 9997 FORMAT( ' *** ', A6, ' called XERBLA for a matrix with an ', + $ 'infinity ***' ) * RETURN *