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

📄 dgesdd.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 4 页
字号:
                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,     $                    N, M, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+2*M*     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )                  WRKBL = MAX( WRKBL, BDSPAC+3*M )                  MAXWRK = WRKBL + M*M                  MINWRK = BDSPAC + M*M + 3*M               ELSE IF( WNTQA ) THEN**                 Path 4t (N much larger than M, JOBZ='A')*                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,     $                    N, M, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+2*M*     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )                  WRKBL = MAX( WRKBL, BDSPAC+3*M )                  MAXWRK = WRKBL + M*M                  MINWRK = BDSPAC + M*M + 3*M               END IF            ELSE**              Path 5t (N greater than M, but not much larger)*               WRKBL = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N, -1,     $                 -1 )               IF( WNTQN ) THEN                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )                  MINWRK = 3*M + MAX( N, BDSPAC )               ELSE IF( WNTQO ) THEN                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'PRT', M, N, M, -1 ) )                  WRKBL = MAX( WRKBL, BDSPAC+3*M )                  MAXWRK = WRKBL + M*N                  MINWRK = 3*M + MAX( N, M*M+BDSPAC )               ELSE IF( WNTQS ) THEN                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'PRT', M, N, M, -1 ) )                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )                  MINWRK = 3*M + MAX( N, BDSPAC )               ELSE IF( WNTQA ) THEN                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )                  WRKBL = MAX( WRKBL, 3*M+M*     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, M, -1 ) )                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )                  MINWRK = 3*M + MAX( N, BDSPAC )               END IF            END IF         END IF         WORK( 1 ) = MAXWRK      END IF*      IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN         INFO = -12      END IF      IF( INFO.NE.0 ) THEN         CALL XERBLA( 'DGESDD', -INFO )         RETURN      ELSE IF( LQUERY ) THEN         RETURN      END IF**     Quick return if possible*      IF( M.EQ.0 .OR. N.EQ.0 ) THEN         IF( LWORK.GE.1 )     $      WORK( 1 ) = ONE         RETURN      END IF**     Get machine constants*      EPS = DLAMCH( 'P' )      SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS      BIGNUM = ONE / SMLNUM**     Scale A if max element outside range [SMLNUM,BIGNUM]*      ANRM = DLANGE( 'M', M, N, A, LDA, DUM )      ISCL = 0      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN         ISCL = 1         OPS = OPS + DBLE( M*N )         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )      ELSE IF( ANRM.GT.BIGNUM ) THEN         ISCL = 1         OPS = OPS + DBLE( M*N )         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )      END IF*      IF( M.GE.N ) THEN**        A has at least as many rows as columns. If A has sufficiently*        more rows than columns, first reduce using the QR*        decomposition (if sufficient workspace available)*         IF( M.GE.MNTHR ) THEN*            IF( WNTQN ) THEN**              Path 1 (M much larger than N, JOBZ='N')*              No singular vectors to be computed*               ITAU = 1               NWORK = ITAU + N**              Compute A=Q*R*              (Workspace: need 2*N, prefer N+N*NB)*               NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )               OPS = OPS + DOPLA( 'DGEQRF', M, N, 0, 0, NB )               CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Zero out below R*               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )               IE = 1               ITAUQ = IE + N               ITAUP = ITAUQ + N               NWORK = ITAUP + N**              Bidiagonalize R in A*              (Workspace: need 4*N, prefer 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 )               NWORK = IE + N**              Perform bidiagonal SVD, computing singular values only*              (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**              Path 2 (M much larger than N, JOBZ = 'O')*              N left singular vectors to be overwritten on A and*              N right singular vectors to be computed in VT*               IR = 1**              WORK(IR) is LDWRKR by N*               IF( LWORK.GE.LDA*N+N*N+3*N+BDSPAC ) THEN                  LDWRKR = LDA               ELSE                  LDWRKR = ( LWORK-N*N-3*N-BDSPAC ) / N               END IF               ITAU = IR + LDWRKR*N               NWORK = ITAU + N**              Compute A=Q*R*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*               NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )               OPS = OPS + DOPLA( 'DGEQRF', M, N, 0, 0, NB )               CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Copy R to WORK(IR), zeroing out below it*               CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),     $                      LDWRKR )**              Generate Q in A*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*               NB = ILAENV( 1, 'DORGQR', ' ', M, N, N, -1 )               OPS = OPS + DOPLA( 'DORGQR', M, N, N, 0, NB )               CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )               IE = ITAU               ITAUQ = IE + N               ITAUP = ITAUQ + N               NWORK = ITAUP + N**              Bidiagonalize R in VT, copying result to WORK(IR)*              (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, WORK( IR ), LDWRKR, S, WORK( IE ),     $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              WORK(IU) is N by N*               IU = NWORK               NWORK = IU + N*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 ), 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 2*N*N+3*N, prefer 2*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, WORK( IR ), LDWRKR,     $                      WORK( ITAUQ ), WORK( IU ), N, 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, WORK( IR ), LDWRKR,     $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Multiply Q in A by left singular vectors of R in*              WORK(IU), storing result in WORK(IR) and copying to A*              (Workspace: need 2*N*N, prefer N*N+M*N)*               DO 10 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 ), N, ZERO, WORK( IR ),     $                        LDWRKR )                  CALL DLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,     $                         A( I, 1 ), LDA )   10          CONTINUE*            ELSE IF( WNTQS ) THEN**              Path 3 (M much larger than N, JOBZ='S')*              N left singular vectors to be computed in U and*              N right singular vectors to be computed in VT*               IR = 1**              WORK(IR) is N by N*               LDWRKR = N               ITAU = IR + LDWRKR*N               NWORK = ITAU + N**              Compute A=Q*R*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*               NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )               OPS = OPS + DOPLA( 'DGEQRF', M, N, 0, 0, NB )               CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Copy R to WORK(IR), zeroing out below it*               CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),     $                      LDWRKR )**              Generate Q in A*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*               NB = ILAENV( 1, 'DORGQR', ' ', M, N, N, -1 )               OPS = OPS + DOPLA( 'DORGQR', M, N, N, 0, NB )               CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )               IE = ITAU               ITAUQ = IE + N               ITAUP = ITAUQ + N               NWORK = ITAUP + N**              Bidiagonalize R in WORK(IR)*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)*               NB = MAX( 1, ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )               OPS = OPS + DOPLA( 'DGEBRD', N, N, 0, 0, NB )               CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),     $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Perform bidiagonal SVD, computing left singular vectors*              of bidiagoal matrix in U and computing right singular*              vectors of bidiagonal matrix in VT*              (Workspace: need N+BDSPAC)*               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 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, WORK( IR ), LDWRKR,     $                      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, WORK( IR ), LDWRKR,     $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )**              Multiply Q in A by left singular vectors of R in*              WORK(IR), storing result in U*              (Workspace: need N*N)*               CALL DLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )               OPS = OPS + DOPBL3( 'DGEMM ', M, N, N )               CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA, WORK( IR ),     $                     LDWRKR, ZERO, U, LDU )*            ELSE IF( WNTQA ) THEN**              Path 4 (M much larger than N, JOBZ='A')*              M left singular vectors to be computed in U and*              N right singular vectors to be computed in VT*               IU = 1**              WORK(IU) is N by N*               LDWRKU = N               ITAU = IU + LDWRKU*N               NWORK = ITAU + N**              Compute A=Q*R, copying result to U*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)*               NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )               OPS = OPS + DOPLA( 'DGEQRF', M, N, 0, 0, NB )               CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                      LWORK-NWORK+1, IERR )               CALL DLACPY( 'L', M, N, A, LDA, U, LDU )**              Generate Q in U*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)               NB = ILAENV( 1, 'DORGQR', ' ', M, M, N, -1 )               OPS = OPS + DOPLA( 'DORGQR', M, M, N, 0, NB )               CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )**              Produce R in A, zeroing out other entries*               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )               IE = ITAU

⌨️ 快捷键说明

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