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

📄 zbdsqr.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
         IF( NRU.GT.0 )     $      CALL ZDROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )         IF( NCC.GT.0 )     $      CALL ZDROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,     $                  SINL )         M = M - 2         GO TO 60      END IF**     If working on new submatrix, choose shift direction*     (from larger end diagonal element towards smaller)*      IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN         IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN**           Chase bulge from top (big end) to bottom (small end)*            IDIR = 1         ELSE**           Chase bulge from bottom (big end) to top (small end)*            IDIR = 2         END IF      END IF**     Apply convergence tests*      IF( IDIR.EQ.1 ) THEN**        Run convergence test in forward direction*        First apply standard test to bottom of matrix*         OPS = OPS + 1         IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.     $       ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN            E( M-1 ) = ZERO            GO TO 60         END IF*         IF( TOL.GE.ZERO ) THEN**           If relative accuracy desired,*           apply convergence criterion forward*            MU = ABS( D( LL ) )            SMINL = MU            DO 100 LLL = LL, M - 1               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN                  E( LLL ) = ZERO                  GO TO 60               END IF               SMINLO = SMINL               OPS = OPS + 4               MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )               SMINL = MIN( SMINL, MU )  100       CONTINUE         END IF*      ELSE**        Run convergence test in backward direction*        First apply standard test to top of matrix*         OPS = OPS + 1         IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.     $       ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN            E( LL ) = ZERO            GO TO 60         END IF*         IF( TOL.GE.ZERO ) THEN**           If relative accuracy desired,*           apply convergence criterion backward*            MU = ABS( D( M ) )            SMINL = MU            DO 110 LLL = M - 1, LL, -1               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN                  E( LLL ) = ZERO                  GO TO 60               END IF               SMINLO = SMINL               OPS = OPS + 4               MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )               SMINL = MIN( SMINL, MU )  110       CONTINUE         END IF      END IF      OLDLL = LL      OLDM = M**     Compute shift.  First, test if shifting would ruin relative*     accuracy, and if so set the shift to zero.*      OPS = OPS + 4      IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.     $    MAX( EPS, HNDRTH*TOL ) ) THEN**        Use a zero shift to avoid loss of relative accuracy*         SHIFT = ZERO      ELSE**        Compute the shift from 2-by-2 block at end of matrix*         OPS = OPS + 20         IF( IDIR.EQ.1 ) THEN            SLL = ABS( D( LL ) )            CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )         ELSE            SLL = ABS( D( M ) )            CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )         END IF**        Test if shift negligible, and if so set to zero*         IF( SLL.GT.ZERO ) THEN            IF( ( SHIFT / SLL )**2.LT.EPS )     $         SHIFT = ZERO         END IF      END IF**     Increment iteration count*      ITER = ITER + M - LL**     If SHIFT = 0, do simplified QR iteration*      IF( SHIFT.EQ.ZERO ) THEN         OPS = OPS + 2 + DBLE( M-LL )*( 20+12*( NCVT+NRU+NCC ) )         IF( IDIR.EQ.1 ) THEN**           Chase bulge from top to bottom*           Save cosines and sines for later singular vector updates*            CS = ONE            OLDCS = ONE            DO 120 I = LL, M - 1               CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )               IF( I.GT.LL )     $            E( I-1 ) = OLDSN*R               CALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )               RWORK( I-LL+1 ) = CS               RWORK( I-LL+1+NM1 ) = SN               RWORK( I-LL+1+NM12 ) = OLDCS               RWORK( I-LL+1+NM13 ) = OLDSN  120       CONTINUE            H = D( M )*CS            D( M ) = H*OLDCS            E( M-1 ) = H*OLDSN**           Update singular vectors*            IF( NCVT.GT.0 )     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),     $                     RWORK( N ), VT( LL, 1 ), LDVT )            IF( NRU.GT.0 )     $         CALL ZLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),     $                     RWORK( NM13+1 ), U( 1, LL ), LDU )            IF( NCC.GT.0 )     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),     $                     RWORK( NM13+1 ), C( LL, 1 ), LDC )**           Test convergence*            IF( ABS( E( M-1 ) ).LE.THRESH )     $         E( M-1 ) = ZERO*         ELSE**           Chase bulge from bottom to top*           Save cosines and sines for later singular vector updates*            CS = ONE            OLDCS = ONE            DO 130 I = M, LL + 1, -1               CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )               IF( I.LT.M )     $            E( I ) = OLDSN*R               CALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )               RWORK( I-LL ) = CS               RWORK( I-LL+NM1 ) = -SN               RWORK( I-LL+NM12 ) = OLDCS               RWORK( I-LL+NM13 ) = -OLDSN  130       CONTINUE            H = D( LL )*CS            D( LL ) = H*OLDCS            E( LL ) = H*OLDSN**           Update singular vectors*            IF( NCVT.GT.0 )     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),     $                     RWORK( NM13+1 ), VT( LL, 1 ), LDVT )            IF( NRU.GT.0 )     $         CALL ZLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),     $                     RWORK( N ), U( 1, LL ), LDU )            IF( NCC.GT.0 )     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),     $                     RWORK( N ), C( LL, 1 ), LDC )**           Test convergence*            IF( ABS( E( LL ) ).LE.THRESH )     $         E( LL ) = ZERO         END IF      ELSE**        Use nonzero shift*         OPS = OPS + 2 + DBLE( M-LL )*( 32+12*( NCVT+NRU+NCC ) )         IF( IDIR.EQ.1 ) THEN**           Chase bulge from top to bottom*           Save cosines and sines for later singular vector updates*            F = ( ABS( D( LL ) )-SHIFT )*     $          ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )            G = E( LL )            DO 140 I = LL, M - 1               CALL DLARTG( F, G, COSR, SINR, R )               IF( I.GT.LL )     $            E( I-1 ) = R               F = COSR*D( I ) + SINR*E( I )               E( I ) = COSR*E( I ) - SINR*D( I )               G = SINR*D( I+1 )               D( I+1 ) = COSR*D( I+1 )               CALL DLARTG( F, G, COSL, SINL, R )               D( I ) = R               F = COSL*E( I ) + SINL*D( I+1 )               D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )               IF( I.LT.M-1 ) THEN                  G = SINL*E( I+1 )                  E( I+1 ) = COSL*E( I+1 )               END IF               RWORK( I-LL+1 ) = COSR               RWORK( I-LL+1+NM1 ) = SINR               RWORK( I-LL+1+NM12 ) = COSL               RWORK( I-LL+1+NM13 ) = SINL  140       CONTINUE            E( M-1 ) = F**           Update singular vectors*            IF( NCVT.GT.0 )     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),     $                     RWORK( N ), VT( LL, 1 ), LDVT )            IF( NRU.GT.0 )     $         CALL ZLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),     $                     RWORK( NM13+1 ), U( 1, LL ), LDU )            IF( NCC.GT.0 )     $         CALL ZLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),     $                     RWORK( NM13+1 ), C( LL, 1 ), LDC )**           Test convergence*            IF( ABS( E( M-1 ) ).LE.THRESH )     $         E( M-1 ) = ZERO*         ELSE**           Chase bulge from bottom to top*           Save cosines and sines for later singular vector updates*            F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /     $          D( M ) )            G = E( M-1 )            DO 150 I = M, LL + 1, -1               CALL DLARTG( F, G, COSR, SINR, R )               IF( I.LT.M )     $            E( I ) = R               F = COSR*D( I ) + SINR*E( I-1 )               E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )               G = SINR*D( I-1 )               D( I-1 ) = COSR*D( I-1 )               CALL DLARTG( F, G, COSL, SINL, R )               D( I ) = R               F = COSL*E( I-1 ) + SINL*D( I-1 )               D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )               IF( I.GT.LL+1 ) THEN                  G = SINL*E( I-2 )                  E( I-2 ) = COSL*E( I-2 )               END IF               RWORK( I-LL ) = COSR               RWORK( I-LL+NM1 ) = -SINR               RWORK( I-LL+NM12 ) = COSL               RWORK( I-LL+NM13 ) = -SINL  150       CONTINUE            E( LL ) = F**           Test convergence*            IF( ABS( E( LL ) ).LE.THRESH )     $         E( LL ) = ZERO**           Update singular vectors if desired*            IF( NCVT.GT.0 )     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),     $                     RWORK( NM13+1 ), VT( LL, 1 ), LDVT )            IF( NRU.GT.0 )     $         CALL ZLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),     $                     RWORK( N ), U( 1, LL ), LDU )            IF( NCC.GT.0 )     $         CALL ZLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),     $                     RWORK( N ), C( LL, 1 ), LDC )         END IF      END IF**     QR iteration finished, go back and check convergence*      GO TO 60**     All singular values converged, so make them positive*  160 CONTINUE      DO 170 I = 1, N         IF( D( I ).LT.ZERO ) THEN            D( I ) = -D( I )**           Change sign of singular vectors, if desired*            OPS = OPS + NCVT            IF( NCVT.GT.0 )     $         CALL ZDSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )         END IF  170 CONTINUE**     Sort the singular values into decreasing order (insertion sort on*     singular values, but only one transposition per singular vector)*      DO 190 I = 1, N - 1**        Scan for smallest D(I)*         ISUB = 1         SMIN = D( 1 )         DO 180 J = 2, N + 1 - I            IF( D( J ).LE.SMIN ) THEN               ISUB = J               SMIN = D( J )            END IF  180    CONTINUE         IF( ISUB.NE.N+1-I ) THEN**           Swap singular values and vectors*            D( ISUB ) = D( N+1-I )            D( N+1-I ) = SMIN            IF( NCVT.GT.0 )     $         CALL ZSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),     $                     LDVT )            IF( NRU.GT.0 )     $         CALL ZSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )            IF( NCC.GT.0 )     $         CALL ZSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )         END IF  190 CONTINUE      GO TO 220**     Maximum number of iterations exceeded, failure to converge*  200 CONTINUE      INFO = 0      DO 210 I = 1, N - 1         IF( E( I ).NE.ZERO )     $      INFO = INFO + 1  210 CONTINUE  220 CONTINUE      RETURN**     End of ZBDSQR*      END

⌨️ 快捷键说明

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