slarrd.f.html

来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 738 行 · 第 1/4 页

HTML
738
字号
         WORK( N+5 ) = GL
         WORK( N+6 ) = GU
         IWORK( 1 ) = -1
         IWORK( 2 ) = -1
         IWORK( 3 ) = N + 1
         IWORK( 4 ) = N + 1
         IWORK( 5 ) = IL - 1
         IWORK( 6 ) = IU
<span class="comment">*</span><span class="comment">
</span>         CALL <a name="SLAEBZ.361"></a><a href="slaebz.f.html#SLAEBZ.1">SLAEBZ</a>( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN,
     $         D, E, E2, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,
     $                IWORK, W, IBLOCK, IINFO )
         IF( IINFO .NE. 0 ) THEN
            INFO = IINFO
            RETURN
         END IF
<span class="comment">*</span><span class="comment">        On exit, output intervals may not be ordered by ascending negcount
</span>         IF( IWORK( 6 ).EQ.IU ) THEN
            WL = WORK( N+1 )
            WLU = WORK( N+3 )
            NWL = IWORK( 1 )
            WU = WORK( N+4 )
            WUL = WORK( N+2 )
            NWU = IWORK( 4 )
         ELSE
            WL = WORK( N+2 )
            WLU = WORK( N+4 )
            NWL = IWORK( 2 )
            WU = WORK( N+3 )
            WUL = WORK( N+1 )
            NWU = IWORK( 3 )
         END IF
<span class="comment">*</span><span class="comment">        On exit, the interval [WL, WLU] contains a value with negcount NWL,
</span><span class="comment">*</span><span class="comment">        and [WUL, WU] contains a value with negcount NWU.
</span>         IF( NWL.LT.0 .OR. NWL.GE.N .OR. NWU.LT.1 .OR. NWU.GT.N ) THEN
            INFO = 4
            RETURN
         END IF

      ELSEIF( IRANGE.EQ.VALRNG ) THEN
         WL = VL
         WU = VU

      ELSEIF( IRANGE.EQ.ALLRNG ) THEN
         WL = GL
         WU = GU
      ENDIF



<span class="comment">*</span><span class="comment">     Find Eigenvalues -- Loop Over blocks and recompute NWL and NWU.
</span><span class="comment">*</span><span class="comment">     NWL accumulates the number of eigenvalues .le. WL,
</span><span class="comment">*</span><span class="comment">     NWU accumulates the number of eigenvalues .le. WU
</span>      M = 0
      IEND = 0
      INFO = 0
      NWL = 0
      NWU = 0
<span class="comment">*</span><span class="comment">
</span>      DO 70 JBLK = 1, NSPLIT
         IOFF = IEND
         IBEGIN = IOFF + 1
         IEND = ISPLIT( JBLK )
         IN = IEND - IOFF
<span class="comment">*</span><span class="comment">
</span>         IF( IN.EQ.1 ) THEN
<span class="comment">*</span><span class="comment">           1x1 block
</span>            IF( WL.GE.D( IBEGIN )-PIVMIN )
     $         NWL = NWL + 1
            IF( WU.GE.D( IBEGIN )-PIVMIN )
     $         NWU = NWU + 1
            IF( IRANGE.EQ.ALLRNG .OR.
     $           ( WL.LT.D( IBEGIN )-PIVMIN
     $             .AND. WU.GE. D( IBEGIN )-PIVMIN ) ) THEN
               M = M + 1
               W( M ) = D( IBEGIN )
               WERR(M) = ZERO
<span class="comment">*</span><span class="comment">              The gap for a single block doesn't matter for the later
</span><span class="comment">*</span><span class="comment">              algorithm and is assigned an arbitrary large value
</span>               IBLOCK( M ) = JBLK
               INDEXW( M ) = 1
            END IF

<span class="comment">*</span><span class="comment">        Disabled 2x2 case because of a failure on the following matrix
</span><span class="comment">*</span><span class="comment">        RANGE = 'I', IL = IU = 4
</span><span class="comment">*</span><span class="comment">          Original Tridiagonal, d = [
</span><span class="comment">*</span><span class="comment">           -0.150102010615740E+00
</span><span class="comment">*</span><span class="comment">           -0.849897989384260E+00
</span><span class="comment">*</span><span class="comment">           -0.128208148052635E-15
</span><span class="comment">*</span><span class="comment">            0.128257718286320E-15
</span><span class="comment">*</span><span class="comment">          ];
</span><span class="comment">*</span><span class="comment">          e = [
</span><span class="comment">*</span><span class="comment">           -0.357171383266986E+00
</span><span class="comment">*</span><span class="comment">           -0.180411241501588E-15
</span><span class="comment">*</span><span class="comment">           -0.175152352710251E-15
</span><span class="comment">*</span><span class="comment">          ];
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">         ELSE IF( IN.EQ.2 ) THEN
</span><span class="comment">*</span><span class="comment">*           2x2 block
</span><span class="comment">*</span><span class="comment">            DISC = SQRT( (HALF*(D(IBEGIN)-D(IEND)))**2 + E(IBEGIN)**2 )
</span><span class="comment">*</span><span class="comment">            TMP1 = HALF*(D(IBEGIN)+D(IEND))
</span><span class="comment">*</span><span class="comment">            L1 = TMP1 - DISC
</span><span class="comment">*</span><span class="comment">            IF( WL.GE. L1-PIVMIN )
</span><span class="comment">*</span><span class="comment">     $         NWL = NWL + 1
</span><span class="comment">*</span><span class="comment">            IF( WU.GE. L1-PIVMIN )
</span><span class="comment">*</span><span class="comment">     $         NWU = NWU + 1
</span><span class="comment">*</span><span class="comment">            IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L1-PIVMIN .AND. WU.GE.
</span><span class="comment">*</span><span class="comment">     $          L1-PIVMIN ) ) THEN
</span><span class="comment">*</span><span class="comment">               M = M + 1
</span><span class="comment">*</span><span class="comment">               W( M ) = L1
</span><span class="comment">*</span><span class="comment">*              The uncertainty of eigenvalues of a 2x2 matrix is very small
</span><span class="comment">*</span><span class="comment">               WERR( M ) = EPS * ABS( W( M ) ) * TWO
</span><span class="comment">*</span><span class="comment">               IBLOCK( M ) = JBLK
</span><span class="comment">*</span><span class="comment">               INDEXW( M ) = 1
</span><span class="comment">*</span><span class="comment">            ENDIF
</span><span class="comment">*</span><span class="comment">            L2 = TMP1 + DISC
</span><span class="comment">*</span><span class="comment">            IF( WL.GE. L2-PIVMIN )
</span><span class="comment">*</span><span class="comment">     $         NWL = NWL + 1
</span><span class="comment">*</span><span class="comment">            IF( WU.GE. L2-PIVMIN )
</span><span class="comment">*</span><span class="comment">     $         NWU = NWU + 1
</span><span class="comment">*</span><span class="comment">            IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L2-PIVMIN .AND. WU.GE.
</span><span class="comment">*</span><span class="comment">     $          L2-PIVMIN ) ) THEN
</span><span class="comment">*</span><span class="comment">               M = M + 1
</span><span class="comment">*</span><span class="comment">               W( M ) = L2
</span><span class="comment">*</span><span class="comment">*              The uncertainty of eigenvalues of a 2x2 matrix is very small
</span><span class="comment">*</span><span class="comment">               WERR( M ) = EPS * ABS( W( M ) ) * TWO
</span><span class="comment">*</span><span class="comment">               IBLOCK( M ) = JBLK
</span><span class="comment">*</span><span class="comment">               INDEXW( M ) = 2
</span><span class="comment">*</span><span class="comment">            ENDIF
</span>         ELSE
<span class="comment">*</span><span class="comment">           General Case - block of size IN &gt;= 2
</span><span class="comment">*</span><span class="comment">           Compute local Gerschgorin interval and use it as the initial
</span><span class="comment">*</span><span class="comment">           interval for <a name="SLAEBZ.484"></a><a href="slaebz.f.html#SLAEBZ.1">SLAEBZ</a>
</span>            GU = D( IBEGIN )
            GL = D( IBEGIN )
            TMP1 = ZERO

            DO 40 J = IBEGIN, IEND
               GL =  MIN( GL, GERS( 2*J - 1))
               GU = MAX( GU, GERS(2*J) )
   40       CONTINUE
            SPDIAM = GU - GL
            GL = GL - FUDGE*SPDIAM*EPS*IN - FUDGE*PIVMIN
            GU = GU + FUDGE*SPDIAM*EPS*IN + FUDGE*PIVMIN
<span class="comment">*</span><span class="comment">
</span>            IF( IRANGE.GT.1 ) THEN
               IF( GU.LT.WL ) THEN
<span class="comment">*</span><span class="comment">                 the local block contains none of the wanted eigenvalues
</span>                  NWL = NWL + IN
                  NWU = NWU + IN
                  GO TO 70
               END IF
<span class="comment">*</span><span class="comment">              refine search interval if possible, only range (WL,WU] matters
</span>               GL = MAX( GL, WL )
               GU = MIN( GU, WU )
               IF( GL.GE.GU )
     $            GO TO 70
            END IF

<span class="comment">*</span><span class="comment">           Find negcount of initial interval boundaries GL and GU
</span>            WORK( N+1 ) = GL
            WORK( N+IN+1 ) = GU
            CALL <a name="SLAEBZ.514"></a><a href="slaebz.f.html#SLAEBZ.1">SLAEBZ</a>( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
     $                   D( IBEGIN ), E( IBEGIN ), E2( IBEGIN ),
     $                   IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,
     $                   IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
            IF( IINFO .NE. 0 ) THEN
               INFO = IINFO
               RETURN
            END IF
<span class="comment">*</span><span class="comment">
</span>            NWL = NWL + IWORK( 1 )
            NWU = NWU + IWORK( IN+1 )
            IWOFF = M - IWORK( 1 )

<span class="comment">*</span><span class="comment">           Compute Eigenvalues
</span>            ITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /
     $              LOG( TWO ) ) + 2
            CALL <a name="SLAEBZ.530"></a><a href="slaebz.f.html#SLAEBZ.1">SLAEBZ</a>( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
     $                   D( IBEGIN ), E( IBEGIN ), E2( IBEGIN ),
     $                   IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,
     $                   IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
            IF( IINFO .NE. 0 ) THEN
               INFO = IINFO
               RETURN

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?