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

📄 zlalsd.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
         OPS = OPS + DOPBL3( 'DGEMM ', N, NRHS, N )          CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,     $               RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )         J = IRWB - 1         DO 140 JCOL = 1, NRHS            DO 130 JROW = 1, N               J = J + 1               RWORK( J ) = DIMAG( B( JROW, JCOL ) )  130       CONTINUE  140    CONTINUE         OPS = OPS + DOPBL3( 'DGEMM ', N, NRHS, N )          CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,     $               RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )         JREAL = IRWRB - 1         JIMAG = IRWIB - 1         DO 160 JCOL = 1, NRHS            DO 150 JROW = 1, N               JREAL = JREAL + 1               JIMAG = JIMAG + 1               B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),     $                           RWORK( JIMAG ) )  150       CONTINUE  160    CONTINUE**        Unscale.*         OPS = OPS + DBLE( N + 6*N*NRHS )         CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )         CALL DLASRT( 'D', N, D, INFO )         CALL ZLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )*         RETURN      END IF**     Book-keeping and setting up some constants.*      NLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1*      SMLSZP = SMLSIZ + 1*      U = 1      VT = 1 + SMLSIZ*N      DIFL = VT + SMLSZP*N      DIFR = DIFL + NLVL*N      Z = DIFR + NLVL*N*2      C = Z + NLVL*N      S = C + N      POLES = S + N      GIVNUM = POLES + 2*NLVL*N      NRWORK = GIVNUM + 2*NLVL*N      BX = 1*      IRWRB = NRWORK      IRWIB = IRWRB + SMLSIZ*NRHS      IRWB = IRWIB + SMLSIZ*NRHS*      SIZEI = 1 + N      K = SIZEI + N      GIVPTR = K + N      PERM = GIVPTR + N      GIVCOL = PERM + NLVL*N      IWK = GIVCOL + NLVL*N*2*      ST = 1      SQRE = 0      ICMPQ1 = 1      ICMPQ2 = 0      NSUB = 0*      DO 170 I = 1, N         IF( ABS( D( I ) ).LT.EPS ) THEN            D( I ) = SIGN( EPS, D( I ) )         END IF  170 CONTINUE*      DO 240 I = 1, NM1         IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN            NSUB = NSUB + 1            IWORK( NSUB ) = ST**           Subproblem found. First determine its size and then*           apply divide and conquer on it.*            IF( I.LT.NM1 ) THEN**              A subproblem with E(I) small for I < NM1.*               NSIZE = I - ST + 1               IWORK( SIZEI+NSUB-1 ) = NSIZE            ELSE IF( ABS( E( I ) ).GE.EPS ) THEN**              A subproblem with E(NM1) not too small but I = NM1.*               NSIZE = N - ST + 1               IWORK( SIZEI+NSUB-1 ) = NSIZE            ELSE**              A subproblem with E(NM1) small. This implies an*              1-by-1 subproblem at D(N), which is not solved*              explicitly.*               NSIZE = I - ST + 1               IWORK( SIZEI+NSUB-1 ) = NSIZE               NSUB = NSUB + 1               IWORK( NSUB ) = N               IWORK( SIZEI+NSUB-1 ) = 1               CALL ZCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )            END IF            ST1 = ST - 1            IF( NSIZE.EQ.1 ) THEN**              This is a 1-by-1 subproblem and is not solved*              explicitly.*               CALL ZCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )            ELSE IF( NSIZE.LE.SMLSIZ ) THEN**              This is a small subproblem and is solved by DLASDQ.*               CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,     $                      RWORK( VT+ST1 ), N )               CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,     $                      RWORK( U+ST1 ), N )               CALL DLASDQ( 'U', 0, NSIZE, NSIZE, NSIZE, 0, D( ST ),     $                      E( ST ), RWORK( VT+ST1 ), N, RWORK( U+ST1 ),     $                      N, RWORK( NRWORK ), 1, RWORK( NRWORK ),     $                      INFO )               IF( INFO.NE.0 ) THEN                  RETURN               END IF**              In the real version, B is passed to DLASDQ and multiplied*              internally by Q'. Here B is complex and that product is*              computed below in two steps (real and imaginary parts).*               J = IRWB - 1               DO 190 JCOL = 1, NRHS                  DO 180 JROW = ST, ST + NSIZE - 1                     J = J + 1                     RWORK( J ) = DBLE( B( JROW, JCOL ) )  180             CONTINUE  190          CONTINUE               OPS = OPS + DOPBL3( 'DGEMM ', NSIZE, NRHS, NSIZE )                CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,     $                     RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,     $                     ZERO, RWORK( IRWRB ), NSIZE )               J = IRWB - 1               DO 210 JCOL = 1, NRHS                  DO 200 JROW = ST, ST + NSIZE - 1                     J = J + 1                     RWORK( J ) = DIMAG( B( JROW, JCOL ) )  200             CONTINUE  210          CONTINUE               OPS = OPS + DOPBL3( 'DGEMM ', NSIZE, NRHS, NSIZE )                CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,     $                     RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,     $                     ZERO, RWORK( IRWIB ), NSIZE )               JREAL = IRWRB - 1               JIMAG = IRWIB - 1               DO 230 JCOL = 1, NRHS                  DO 220 JROW = ST, ST + NSIZE - 1                     JREAL = JREAL + 1                     JIMAG = JIMAG + 1                     B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),     $                                 RWORK( JIMAG ) )  220             CONTINUE  230          CONTINUE*               CALL ZLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,     $                      WORK( BX+ST1 ), N )            ELSE**              A large problem. Solve it using divide and conquer.*               CALL DLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),     $                      E( ST ), RWORK( U+ST1 ), N, RWORK( VT+ST1 ),     $                      IWORK( K+ST1 ), RWORK( DIFL+ST1 ),     $                      RWORK( DIFR+ST1 ), RWORK( Z+ST1 ),     $                      RWORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),     $                      IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),     $                      RWORK( GIVNUM+ST1 ), RWORK( C+ST1 ),     $                      RWORK( S+ST1 ), RWORK( NRWORK ),     $                      IWORK( IWK ), INFO )               IF( INFO.NE.0 ) THEN                  RETURN               END IF               BXST = BX + ST1               CALL ZLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),     $                      LDB, WORK( BXST ), N, RWORK( U+ST1 ), N,     $                      RWORK( VT+ST1 ), IWORK( K+ST1 ),     $                      RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),     $                      RWORK( Z+ST1 ), RWORK( POLES+ST1 ),     $                      IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,     $                      IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),     $                      RWORK( C+ST1 ), RWORK( S+ST1 ),     $                      RWORK( NRWORK ), IWORK( IWK ), INFO )               IF( INFO.NE.0 ) THEN                  RETURN               END IF            END IF            ST = I + 1         END IF  240 CONTINUE**     Apply the singular values and treat the tiny ones as zero.*      OPS = OPS + DBLE( 1 )      TOL = RCOND*ABS( D( IDAMAX( N, D, 1 ) ) )*      DO 250 I = 1, N**        Some of the elements in D can be negative because 1-by-1*        subproblems were not solved explicitly.*         IF( ABS( D( I ) ).LE.TOL ) THEN            CALL ZLASET( 'A', 1, NRHS, CZERO, CZERO, WORK( BX+I-1 ), N )         ELSE            RANK = RANK + 1            OPS = OPS + DBLE( 6*NRHS )            CALL ZLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,     $                   WORK( BX+I-1 ), N, INFO )         END IF         D( I ) = ABS( D( I ) )  250 CONTINUE**     Now apply back the right singular vectors.*      ICMPQ2 = 1      DO 320 I = 1, NSUB         ST = IWORK( I )         ST1 = ST - 1         NSIZE = IWORK( SIZEI+I-1 )         BXST = BX + ST1         IF( NSIZE.EQ.1 ) THEN            CALL ZCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )         ELSE IF( NSIZE.LE.SMLSIZ ) THEN**           Since B and BX are complex, the following call to DGEMM*           is performed in two steps (real and imaginary parts).**           CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,*    $                  RWORK( VT+ST1 ), N, RWORK( BXST ), N, ZERO,*    $                  B( ST, 1 ), LDB )*            J = BXST - N - 1            JREAL = IRWB - 1            DO 270 JCOL = 1, NRHS               J = J + N               DO 260 JROW = 1, NSIZE                  JREAL = JREAL + 1                  RWORK( JREAL ) = DBLE( WORK( J+JROW ) )  260          CONTINUE  270       CONTINUE            OPS = OPS + DOPBL3( 'DGEMM ', NSIZE, NRHS, NSIZE )             CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,     $                  RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,     $                  RWORK( IRWRB ), NSIZE )            J = BXST - N - 1            JIMAG = IRWB - 1            DO 290 JCOL = 1, NRHS               J = J + N               DO 280 JROW = 1, NSIZE                  JIMAG = JIMAG + 1                  RWORK( JIMAG ) = DIMAG( WORK( J+JROW ) )  280          CONTINUE  290       CONTINUE            OPS = OPS + DOPBL3( 'DGEMM ', NSIZE, NRHS, NSIZE )             CALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,     $                  RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,     $                  RWORK( IRWIB ), NSIZE )            JREAL = IRWRB - 1            JIMAG = IRWIB - 1            DO 310 JCOL = 1, NRHS               DO 300 JROW = ST, ST + NSIZE - 1                  JREAL = JREAL + 1                  JIMAG = JIMAG + 1                  B( JROW, JCOL ) = DCMPLX( RWORK( JREAL ),     $                              RWORK( JIMAG ) )  300          CONTINUE  310       CONTINUE         ELSE            CALL ZLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,     $                   B( ST, 1 ), LDB, RWORK( U+ST1 ), N,     $                   RWORK( VT+ST1 ), IWORK( K+ST1 ),     $                   RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),     $                   RWORK( Z+ST1 ), RWORK( POLES+ST1 ),     $                   IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,     $                   IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),     $                   RWORK( C+ST1 ), RWORK( S+ST1 ),     $                   RWORK( NRWORK ), IWORK( IWK ), INFO )            IF( INFO.NE.0 ) THEN               RETURN            END IF         END IF  320 CONTINUE**     Unscale and sort the singular values.*      OPS = OPS + DBLE( N + 6*N*NRHS )      CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )      CALL DLASRT( 'D', N, D, INFO )      CALL ZLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )*      RETURN**     End of ZLALSD*      END

⌨️ 快捷键说明

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