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

📄 dgesdd.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 4 页
字号:
               ITAUQ = IE + N               ITAUP = ITAUQ + N               NWORK = ITAUP + N**              Bidiagonalize R in A*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*               NB = ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 )               OPS = OPS + DOPLA( 'DGEBRD', N, N, 0, 0, NB )               CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),     $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,     $                      IERR )**              Perform bidiagonal SVD, computing left singular vectors*              of bidiagonal matrix in WORK(IU) and computing right*              singular vectors of bidiagonal matrix in VT*              (Workspace: need N+N*N+BDSPAC)*               CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,     $                      VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,     $                      INFO )**              Overwrite WORK(IU) by left singular vectors of R and VT*              by right singular vectors of R*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)*               NB = ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'QLN', N, N, N, 0, NB )               CALL DORMBR( 'Q', 'L', 'N', N, N, N, A, LDA,     $                      WORK( ITAUQ ), WORK( IU ), LDWRKU,     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )               NB = ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'PRT', N, N, N, 0, NB )               CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,     $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Multiply Q in U by left singular vectors of R in*              WORK(IU), storing result in A*              (Workspace: need N*N)*               OPS = OPS + DOPBL3( 'DGEMM ', M, N, N )               CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU, WORK( IU ),     $                     LDWRKU, ZERO, A, LDA )**              Copy left singular vectors of A from A to U*               CALL DLACPY( 'F', M, N, A, LDA, U, LDU )*            END IF*         ELSE**           M .LT. MNTHR**           Path 5 (M at least N, but not much larger)*           Reduce to bidiagonal form without QR decomposition*            IE = 1            ITAUQ = IE + N            ITAUP = ITAUQ + N            NWORK = ITAUP + N**           Bidiagonalize A*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)*            NB = MAX( 1, ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 ) )            OPS = OPS + DOPLA( 'DGEBRD', M, N, 0, 0, NB )            CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),     $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,     $                   IERR )            IF( WNTQN ) THEN**              Perform bidiagonal SVD, only computing singular values*              (Workspace: need N+BDSPAC)*               CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,     $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )            ELSE IF( WNTQO ) THEN               IU = NWORK               IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN**                 WORK( IU ) is M by N*                  LDWRKU = M                  NWORK = IU + LDWRKU*N                  CALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IU ),     $                         LDWRKU )               ELSE**                 WORK( IU ) is N by N*                  LDWRKU = N                  NWORK = IU + LDWRKU*N**                 WORK(IR) is LDWRKR by N*                  IR = NWORK                  LDWRKR = ( LWORK-N*N-3*N ) / N               END IF               NWORK = IU + LDWRKU*N**              Perform bidiagonal SVD, computing left singular vectors*              of bidiagonal matrix in WORK(IU) and computing right*              singular vectors of bidiagonal matrix in VT*              (Workspace: need N+N*N+BDSPAC)*               CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ),     $                      LDWRKU, VT, LDVT, DUM, IDUM, WORK( NWORK ),     $                      IWORK, INFO )**              Overwrite VT by right singular vectors of A*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*               NB = ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'PRT', N, N, N, 0, NB )               CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,     $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )*               IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN**                 Overwrite WORK(IU) by left singular vectors of A*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*                  NB = ILAENV( 1, 'DORMBR', 'QLN', M, N, N, -1 )                  OPS = OPS + DOPLA2( 'DORMBR', 'QLN', M, N, N, 0, NB )                  CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,     $                         WORK( ITAUQ ), WORK( IU ), LDWRKU,     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )**                 Copy left singular vectors of A from WORK(IU) to A*                  CALL DLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )               ELSE**                 Generate Q in A*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*                  NB = ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 )                  OPS = OPS + DOPLA2( 'DORGBR', 'Q', M, N, N, 0, NB )                  CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )**                 Multiply Q in A by left singular vectors of*                 bidiagonal matrix in WORK(IU), storing result in*                 WORK(IR) and copying to A*                 (Workspace: need 2*N*N, prefer N*N+M*N)*                  DO 20 I = 1, M, LDWRKR                     CHUNK = MIN( M-I+1, LDWRKR )                     OPS = OPS + DOPBL3( 'DGEMM ', CHUNK, N, N )                     CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),     $                           LDA, WORK( IU ), LDWRKU, ZERO,     $                           WORK( IR ), LDWRKR )                     CALL DLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,     $                            A( I, 1 ), LDA )   20             CONTINUE               END IF*            ELSE IF( WNTQS ) THEN**              Perform bidiagonal SVD, computing left singular vectors*              of bidiagonal matrix in U and computing right singular*              vectors of bidiagonal matrix in VT*              (Workspace: need N+BDSPAC)*               CALL DLASET( 'F', M, N, ZERO, ZERO, U, LDU )               CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,     $                      LDVT, DUM, IDUM, WORK( NWORK ), IWORK,     $                      INFO )**              Overwrite U by left singular vectors of A and VT*              by right singular vectors of A*              (Workspace: need 3*N, prefer 2*N+N*NB)*               NB = ILAENV( 1, 'DORMBR', 'QLN', M, N, N, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'QLN', M, N, N, 0, NB )               CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,     $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )               NB = ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'PRT', N, N, N, 0, NB )               CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,     $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )            ELSE IF( WNTQA ) THEN**              Perform bidiagonal SVD, computing left singular vectors*              of bidiagonal matrix in U and computing right singular*              vectors of bidiagonal matrix in VT*              (Workspace: need N+BDSPAC)*               CALL DLASET( 'F', M, M, ZERO, ZERO, U, LDU )               CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,     $                      LDVT, DUM, IDUM, WORK( NWORK ), IWORK,     $                      INFO )**              Set the right corner of U to identity matrix*               CALL DLASET( 'F', M-N, M-N, ZERO, ONE, U( N+1, N+1 ),     $                      LDU )**              Overwrite U by left singular vectors of A and VT*              by right singular vectors of A*              (Workspace: need N*N+2*N+M, prefer N*N+2*N+M*NB)*               NB = ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'QLN', M, M, N, 0, NB )               CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,     $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )               NB = ILAENV( 1, 'DORMBR', 'PRT', N, N, M, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'PRT', N, N, M, 0, NB )               CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,     $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )            END IF*         END IF*      ELSE**        A has more columns than rows. If A has sufficiently more*        columns than rows, first reduce using the LQ decomposition (if*        sufficient workspace available)*         IF( N.GE.MNTHR ) THEN*            IF( WNTQN ) THEN**              Path 1t (N much larger than M, JOBZ='N')*              No singular vectors to be computed*               ITAU = 1               NWORK = ITAU + M**              Compute A=L*Q*              (Workspace: need 2*M, prefer M+M*NB)*               NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )               OPS = OPS + DOPLA( 'DGELQF', M, N, 0, 0, NB )               CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Zero out above L*               CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )               IE = 1               ITAUQ = IE + M               ITAUP = ITAUQ + M               NWORK = ITAUP + M**              Bidiagonalize L in A*              (Workspace: need 4*M, prefer 3*M+2*M*NB)*               NB = ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 )               OPS = OPS + DOPLA( 'DGEBRD', M, M, 0, 0, NB )               CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),     $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,     $                      IERR )               NWORK = IE + M**              Perform bidiagonal SVD, computing singular values only*              (Workspace: need M+BDSPAC)*               CALL DBDSDC( 'U', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,     $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )*            ELSE IF( WNTQO ) THEN**              Path 2t (N much larger than M, JOBZ='O')*              M right singular vectors to be overwritten on A and*              M left singular vectors to be computed in U*               IVT = 1**              IVT is M by M*               IL = IVT + M*M               IF( LWORK.GE.M*N+M*M+3*M+BDSPAC ) THEN**                 WORK(IL) is M by N*                  LDWRKL = M                  CHUNK = N               ELSE                  LDWRKL = M                  CHUNK = ( LWORK-M*M ) / M               END IF               ITAU = IL + LDWRKL*M               NWORK = ITAU + M**              Compute A=L*Q*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*               NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )               OPS = OPS + DOPLA( 'DGELQF', M, N, 0, 0, NB )               CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Copy L to WORK(IL), zeroing about above it*               CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )               CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,     $                      WORK( IL+LDWRKL ), LDWRKL )**              Generate Q in A*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)*               NB = ILAENV( 1, 'DORGLQ', ' ', M, N, M, -1 )               OPS = OPS + DOPLA( 'DORGLQ', M, N, M, 0, NB )               CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )               IE = ITAU               ITAUQ = IE + M               ITAUP = ITAUQ + M               NWORK = ITAUP + M**              Bidiagonalize L in WORK(IL)*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)*               NB = ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 )               OPS = OPS + DOPLA( 'DGEBRD', M, M, 0, 0, NB )               CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),     $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Perform bidiagonal SVD, computing left singular vectors*              of bidiagonal matrix in U, and computing right singular*              vectors of bidiagonal matrix in WORK(IVT)*              (Workspace: need M+M*M+BDSPAC)*               CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,     $                      WORK( IVT ), M, DUM, IDUM, WORK( NWORK ),     $                      IWORK, INFO )**              Overwrite U by left singular vectors of L and WORK(IVT)*              by right singular vectors of L*              (Workspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)*               NB = ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'QLN', M, M, M, 0, NB )               CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,     $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )               NB = ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 )               OPS = OPS + DOPLA2( 'DORMBR', 'PRT', M, M, M, 0, NB )               CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,     $                      WORK( ITAUP ), WORK( IVT ), M,     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )**              Multiply right singular vectors of L in WORK(IVT) by Q*              in A, storing result in WORK(IL) and copying to A*              (Workspace: need 2*M*M, prefer M*M+M*N)*               DO 30 I = 1, N, CHUNK                  BLK = MIN( N-I+1, CHUNK )                  OPS = OPS + DOPBL3( 'DGEMM ', M, BLK, M )                  CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ), M,     $                        A( 1, I ), LDA, ZERO, WORK( IL ), LDWRKL )                  CALL DLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,     $                         A( 1, I ), LDA )   30          CONTINUE*

⌨️ 快捷键说明

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