📄 slasd2.f
字号:
* DSIGMA, IDXC, IDXC, and the first column of U2* are used as storage space.* DO 60 I = 2, N DSIGMA( I ) = D( IDXQ( I ) ) U2( I, 1 ) = Z( IDXQ( I ) ) IDXC( I ) = COLTYP( IDXQ( I ) ) 60 CONTINUE* CALL SLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )* DO 70 I = 2, N IDXI = 1 + IDX( I ) D( I ) = DSIGMA( IDXI ) Z( I ) = U2( IDXI, 1 ) COLTYP( I ) = IDXC( IDXI ) 70 CONTINUE** Calculate the allowable deflation tolerance* OPS = OPS + REAL( 2 ) EPS = SLAMCH( 'Epsilon' ) TOL = MAX( ABS( ALPHA ), ABS( BETA ) ) TOL = EIGHT*EPS*MAX( ABS( D( N ) ), TOL )** There are 2 kinds of deflation -- first a value in the z-vector* is small, second two (or more) singular values are very close* together (their difference is small).** If the value in the z-vector is small, we simply permute the* array so that the corresponding singular value is moved to the* end.** If two values in the D-vector are close, we perform a two-sided* rotation designed to make one of the corresponding z-vector* entries zero, and then permute the array so that the deflated* singular value is moved to the end.** If there are multiple singular values then the problem deflates.* Here the number of equal singular values are found. As each equal* singular value is found, an elementary reflector is computed to* rotate the corresponding singular subspace so that the* corresponding components of Z are zero in this new basis.* K = 1 K2 = N + 1 DO 80 J = 2, N IF( ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.* K2 = K2 - 1 IDXP( K2 ) = J COLTYP( J ) = 4 IF( J.EQ.N ) $ GO TO 120 ELSE JPREV = J GO TO 90 END IF 80 CONTINUE 90 CONTINUE J = JPREV 100 CONTINUE J = J + 1 IF( J.GT.N ) $ GO TO 110 IF( ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.* K2 = K2 - 1 IDXP( K2 ) = J COLTYP( J ) = 4 ELSE** Check if singular values are close enough to allow deflation.* OPS = OPS + REAL( 1 ) IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN** Deflation is possible.* S = Z( JPREV ) C = Z( J )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.* OPS = OPS + REAL( 7 ) TAU = SLAPY2( C, S ) C = C / TAU S = -S / TAU Z( J ) = TAU Z( JPREV ) = ZERO** Apply back the Givens rotation to the left and right* singular vector matrices.* IDXJP = IDXQ( IDX( JPREV )+1 ) IDXJ = IDXQ( IDX( J )+1 ) IF( IDXJP.LE.NLP1 ) THEN IDXJP = IDXJP - 1 END IF IF( IDXJ.LE.NLP1 ) THEN IDXJ = IDXJ - 1 END IF OPS = OPS + REAL( 12 ) CALL SROT( N, U( 1, IDXJP ), 1, U( 1, IDXJ ), 1, C, S ) CALL SROT( M, VT( IDXJP, 1 ), LDVT, VT( IDXJ, 1 ), LDVT, C, $ S ) IF( COLTYP( J ).NE.COLTYP( JPREV ) ) THEN COLTYP( J ) = 3 END IF COLTYP( JPREV ) = 4 K2 = K2 - 1 IDXP( K2 ) = JPREV JPREV = J ELSE K = K + 1 U2( K, 1 ) = Z( JPREV ) DSIGMA( K ) = D( JPREV ) IDXP( K ) = JPREV JPREV = J END IF END IF GO TO 100 110 CONTINUE** Record the last singular value.* K = K + 1 U2( K, 1 ) = Z( JPREV ) DSIGMA( K ) = D( JPREV ) IDXP( K ) = JPREV* 120 CONTINUE** Count up the total number of the various types of columns, then* form a permutation which positions the four column types into* four groups of uniform structure (although one or more of these* groups may be empty).* DO 130 J = 1, 4 CTOT( J ) = 0 130 CONTINUE DO 140 J = 2, N CT = COLTYP( J ) CTOT( CT ) = CTOT( CT ) + 1 140 CONTINUE** PSM(*) = Position in SubMatrix (of types 1 through 4)* PSM( 1 ) = 2 PSM( 2 ) = 2 + CTOT( 1 ) PSM( 3 ) = PSM( 2 ) + CTOT( 2 ) PSM( 4 ) = PSM( 3 ) + CTOT( 3 )** Fill out the IDXC array so that the permutation which it induces* will place all type-1 columns first, all type-2 columns next,* then all type-3's, and finally all type-4's, starting from the* second column. This applies similarly to the rows of VT.* DO 150 J = 2, N JP = IDXP( J ) CT = COLTYP( JP ) IDXC( PSM( CT ) ) = J PSM( CT ) = PSM( CT ) + 1 150 CONTINUE** Sort the singular values and corresponding singular vectors into* DSIGMA, U2, and VT2 respectively. The singular values/vectors* which were not deflated go into the first K slots of DSIGMA, U2,* and VT2 respectively, while those which were deflated go into the* last N - K slots, except that the first column/row will be treated* separately.* DO 160 J = 2, N JP = IDXP( J ) DSIGMA( J ) = D( JP ) IDXJ = IDXQ( IDX( IDXP( IDXC( J ) ) )+1 ) IF( IDXJ.LE.NLP1 ) THEN IDXJ = IDXJ - 1 END IF CALL SCOPY( N, U( 1, IDXJ ), 1, U2( 1, J ), 1 ) CALL SCOPY( M, VT( IDXJ, 1 ), LDVT, VT2( J, 1 ), LDVT2 ) 160 CONTINUE** Determine DSIGMA(1), DSIGMA(2) and Z(1)* OPS = OPS + REAL( 1 ) DSIGMA( 1 ) = ZERO HLFTOL = TOL / TWO IF( ABS( DSIGMA( 2 ) ).LE.HLFTOL ) $ DSIGMA( 2 ) = HLFTOL IF( M.GT.N ) THEN OPS = OPS + REAL( 5 ) Z( 1 ) = SLAPY2( Z1, Z( M ) ) IF( Z( 1 ).LE.TOL ) THEN C = ONE S = ZERO Z( 1 ) = TOL ELSE OPS = OPS + REAL( 2 ) C = Z1 / Z( 1 ) S = Z( M ) / Z( 1 ) END IF ELSE IF( ABS( Z1 ).LE.TOL ) THEN Z( 1 ) = TOL ELSE Z( 1 ) = Z1 END IF END IF** Move the rest of the updating row to Z.* CALL SCOPY( K-1, U2( 2, 1 ), 1, Z( 2 ), 1 )** Determine the first column of U2, the first row of VT2 and the* last row of VT.* CALL SLASET( 'A', N, 1, ZERO, ZERO, U2, LDU2 ) U2( NLP1, 1 ) = ONE IF( M.GT.N ) THEN OPS = OPS + REAL( NLP1*2 ) DO 170 I = 1, NLP1 VT( M, I ) = -S*VT( NLP1, I ) VT2( 1, I ) = C*VT( NLP1, I ) 170 CONTINUE OPS = OPS + REAL( (M-NLP2+1)*2 ) DO 180 I = NLP2, M VT2( 1, I ) = S*VT( M, I ) VT( M, I ) = C*VT( M, I ) 180 CONTINUE ELSE CALL SCOPY( M, VT( NLP1, 1 ), LDVT, VT2( 1, 1 ), LDVT2 ) END IF IF( M.GT.N ) THEN CALL SCOPY( M, VT( M, 1 ), LDVT, VT2( M, 1 ), LDVT2 ) END IF** The deflated singular values and their corresponding vectors go* into the back of D, U, and V respectively.* IF( N.GT.K ) THEN CALL SCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 ) CALL SLACPY( 'A', N, N-K, U2( 1, K+1 ), LDU2, U( 1, K+1 ), $ LDU ) CALL SLACPY( 'A', N-K, M, VT2( K+1, 1 ), LDVT2, VT( K+1, 1 ), $ LDVT ) END IF** Copy CTOT into COLTYP for referencing in SLASD3.* DO 190 J = 1, 4 COLTYP( J ) = CTOT( J ) 190 CONTINUE* RETURN** End of SLASD2* END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -