⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dstebz.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
*        and use it as the initial interval*         GU = D( 1 )         GL = D( 1 )         TMP1 = ZERO*         OPS = OPS + 5*( N-1 ) + 23         DO 20 J = 1, N - 1            TMP2 = SQRT( WORK( J ) )            GU = MAX( GU, D( J )+TMP1+TMP2 )            GL = MIN( GL, D( J )-TMP1-TMP2 )            TMP1 = TMP2   20    CONTINUE*         GU = MAX( GU, D( N )+TMP1 )         GL = MIN( GL, D( N )-TMP1 )         TNORM = MAX( ABS( GL ), ABS( GU ) )         GL = GL - FUDGE*TNORM*ULP*N - FUDGE*TWO*PIVMIN         GU = GU + FUDGE*TNORM*ULP*N + FUDGE*PIVMIN**        Compute Iteration parameters*         ITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /     $           LOG( TWO ) ) + 2         IF( ABSTOL.LE.ZERO ) THEN            ATOLI = ULP*TNORM         ELSE            ATOLI = ABSTOL         END IF*         WORK( N+1 ) = GL         WORK( N+2 ) = GL         WORK( N+3 ) = GU         WORK( N+4 ) = GU         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*         CALL DLAEBZ( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN, D, E,     $                WORK, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,     $                IWORK, W, IBLOCK, IINFO )*         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*         IF( NWL.LT.0 .OR. NWL.GE.N .OR. NWU.LT.1 .OR. NWU.GT.N ) THEN            INFO = 4            RETURN         END IF      ELSE**        RANGE='A' or 'V' -- Set ATOLI*         OPS = OPS + 3 + 2*( N-2 )         TNORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),     $           ABS( D( N ) )+ABS( E( N-1 ) ) )*         DO 30 J = 2, N - 1            TNORM = MAX( TNORM, ABS( D( J ) )+ABS( E( J-1 ) )+     $              ABS( E( J ) ) )   30    CONTINUE*         IF( ABSTOL.LE.ZERO ) THEN            ATOLI = ULP*TNORM         ELSE            ATOLI = ABSTOL         END IF*         IF( IRANGE.EQ.2 ) THEN            WL = VL            WU = VU         ELSE            WL = ZERO            WU = ZERO         END IF      END IF**     Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU.*     NWL accumulates the number of eigenvalues .le. WL,*     NWU accumulates the number of eigenvalues .le. WU*      M = 0      IEND = 0      INFO = 0      NWL = 0      NWU = 0*      DO 70 JB = 1, NSPLIT         IOFF = IEND         IBEGIN = IOFF + 1         IEND = ISPLIT( JB )         IN = IEND - IOFF*         IF( IN.EQ.1 ) THEN**           Special Case -- IN=1*            OPS = OPS + 4            IF( IRANGE.EQ.1 .OR. WL.GE.D( IBEGIN )-PIVMIN )     $         NWL = NWL + 1            IF( IRANGE.EQ.1 .OR. WU.GE.D( IBEGIN )-PIVMIN )     $         NWU = NWU + 1            IF( IRANGE.EQ.1 .OR. ( WL.LT.D( IBEGIN )-PIVMIN .AND. WU.GE.     $          D( IBEGIN )-PIVMIN ) ) THEN               M = M + 1               W( M ) = D( IBEGIN )               IBLOCK( M ) = JB            END IF         ELSE**           General Case -- IN > 1**           Compute Gershgorin Interval*           and use it as the initial interval*            GU = D( IBEGIN )            GL = D( IBEGIN )            TMP1 = ZERO*            OPS = OPS + 4*( IEND-IBEGIN ) + 13            DO 40 J = IBEGIN, IEND - 1               TMP2 = ABS( E( J ) )               GU = MAX( GU, D( J )+TMP1+TMP2 )               GL = MIN( GL, D( J )-TMP1-TMP2 )               TMP1 = TMP2   40       CONTINUE*            GU = MAX( GU, D( IEND )+TMP1 )            GL = MIN( GL, D( IEND )-TMP1 )            BNORM = MAX( ABS( GL ), ABS( GU ) )            GL = GL - FUDGE*BNORM*ULP*IN - FUDGE*PIVMIN            GU = GU + FUDGE*BNORM*ULP*IN + FUDGE*PIVMIN**           Compute ATOLI for the current submatrix*            IF( ABSTOL.LE.ZERO ) THEN               ATOLI = ULP*MAX( ABS( GL ), ABS( GU ) )            ELSE               ATOLI = ABSTOL            END IF*            IF( IRANGE.GT.1 ) THEN               IF( GU.LT.WL ) THEN                  NWL = NWL + IN                  NWU = NWU + IN                  GO TO 70               END IF               GL = MAX( GL, WL )               GU = MIN( GU, WU )               IF( GL.GE.GU )     $            GO TO 70            END IF**           Set Up Initial Interval*            WORK( N+1 ) = GL            WORK( N+IN+1 ) = GU            CALL DLAEBZ( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,     $                   D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),     $                   IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,     $                   IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )*            NWL = NWL + IWORK( 1 )            NWU = NWU + IWORK( IN+1 )            IWOFF = M - IWORK( 1 )**           Compute Eigenvalues*            OPS = OPS + 8            ITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /     $              LOG( TWO ) ) + 2            CALL DLAEBZ( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,     $                   D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),     $                   IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,     $                   IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )**           Copy Eigenvalues Into W and IBLOCK*           Use -JB for block number for unconverged eigenvalues.*            OPS = OPS + 2*IOUT            DO 60 J = 1, IOUT               TMP1 = HALF*( WORK( J+N )+WORK( J+IN+N ) )**              Flag non-convergence.*               IF( J.GT.IOUT-IINFO ) THEN                  NCNVRG = .TRUE.                  IB = -JB               ELSE                  IB = JB               END IF               DO 50 JE = IWORK( J ) + 1 + IWOFF,     $                 IWORK( J+IN ) + IWOFF                  W( JE ) = TMP1                  IBLOCK( JE ) = IB   50          CONTINUE   60       CONTINUE*            M = M + IM         END IF   70 CONTINUE**     If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU*     If NWL+1 < IL or NWU > IU, discard extra eigenvalues.*      IF( IRANGE.EQ.3 ) THEN         IM = 0         IDISCL = IL - 1 - NWL         IDISCU = NWU - IU*         IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN            DO 80 JE = 1, M               IF( W( JE ).LE.WLU .AND. IDISCL.GT.0 ) THEN                  IDISCL = IDISCL - 1               ELSE IF( W( JE ).GE.WUL .AND. IDISCU.GT.0 ) THEN                  IDISCU = IDISCU - 1               ELSE                  IM = IM + 1                  W( IM ) = W( JE )                  IBLOCK( IM ) = IBLOCK( JE )               END IF   80       CONTINUE            M = IM         END IF         IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN**           Code to deal with effects of bad arithmetic:*           Some low eigenvalues to be discarded are not in (WL,WLU],*           or high eigenvalues to be discarded are not in (WUL,WU]*           so just kill off the smallest IDISCL/largest IDISCU*           eigenvalues, by simply finding the smallest/largest*           eigenvalue(s).**           (If N(w) is monotone non-decreasing, this should never*               happen.)*            IF( IDISCL.GT.0 ) THEN               WKILL = WU               DO 100 JDISC = 1, IDISCL                  IW = 0                  DO 90 JE = 1, M                     IF( IBLOCK( JE ).NE.0 .AND.     $                   ( W( JE ).LT.WKILL .OR. IW.EQ.0 ) ) THEN                        IW = JE                        WKILL = W( JE )                     END IF   90             CONTINUE                  IBLOCK( IW ) = 0  100          CONTINUE            END IF            IF( IDISCU.GT.0 ) THEN*               WKILL = WL               DO 120 JDISC = 1, IDISCU                  IW = 0                  DO 110 JE = 1, M                     IF( IBLOCK( JE ).NE.0 .AND.     $                   ( W( JE ).GT.WKILL .OR. IW.EQ.0 ) ) THEN                        IW = JE                        WKILL = W( JE )                     END IF  110             CONTINUE                  IBLOCK( IW ) = 0  120          CONTINUE            END IF            IM = 0            DO 130 JE = 1, M               IF( IBLOCK( JE ).NE.0 ) THEN                  IM = IM + 1                  W( IM ) = W( JE )                  IBLOCK( IM ) = IBLOCK( JE )               END IF  130       CONTINUE            M = IM         END IF         IF( IDISCL.LT.0 .OR. IDISCU.LT.0 ) THEN            TOOFEW = .TRUE.         END IF      END IF**     If ORDER='B', do nothing -- the eigenvalues are already sorted*        by block.*     If ORDER='E', sort the eigenvalues from smallest to largest*      IF( IORDER.EQ.1 .AND. NSPLIT.GT.1 ) THEN         DO 150 JE = 1, M - 1            IE = 0            TMP1 = W( JE )            DO 140 J = JE + 1, M               IF( W( J ).LT.TMP1 ) THEN                  IE = J                  TMP1 = W( J )               END IF  140       CONTINUE*            IF( IE.NE.0 ) THEN               ITMP1 = IBLOCK( IE )               W( IE ) = W( JE )               IBLOCK( IE ) = IBLOCK( JE )               W( JE ) = TMP1               IBLOCK( JE ) = ITMP1            END IF  150    CONTINUE      END IF*      INFO = 0      IF( NCNVRG )     $   INFO = INFO + 1      IF( TOOFEW )     $   INFO = INFO + 2      RETURN**     End of DSTEBZ*      END

⌨️ 快捷键说明

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