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

📄 dgelsd.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
         CALL XERBLA( 'DGELSD', -INFO )         RETURN      ELSE IF( LQUERY ) THEN         GO TO 10      END IF**     Quick return if possible.*      IF( M.EQ.0 .OR. N.EQ.0 ) THEN         RANK = 0         RETURN      END IF**     Get machine parameters.*      EPS = DLAMCH( 'P' )      SFMIN = DLAMCH( 'S' )      SMLNUM = SFMIN / EPS      BIGNUM = ONE / SMLNUM      CALL DLABAD( SMLNUM, BIGNUM )**     Scale A if max entry outside range [SMLNUM,BIGNUM].*      ANRM = DLANGE( 'M', M, N, A, LDA, WORK )      IASCL = 0      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN**        Scale matrix norm up to SMLNUM.*         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )         IASCL = 1      ELSE IF( ANRM.GT.BIGNUM ) THEN**        Scale matrix norm down to BIGNUM.*         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )         IASCL = 2      ELSE IF( ANRM.EQ.ZERO ) THEN**        Matrix all zero. Return zero solution.*         CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )         CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )         RANK = 0         GO TO 10      END IF**     Scale B if max entry outside range [SMLNUM,BIGNUM].*      BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )      IBSCL = 0      IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN**        Scale matrix norm up to SMLNUM.*         CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )         IBSCL = 1      ELSE IF( BNRM.GT.BIGNUM ) THEN**        Scale matrix norm down to BIGNUM.*         CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )         IBSCL = 2      END IF**     If M < N make sure certain entries of B are zero.*      IF( M.LT.N )     $   CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )**     Overdetermined case.*      IF( M.GE.N ) THEN**        Path 1 - overdetermined or exactly determined.*         MM = M         IF( M.GE.MNTHR ) THEN**           Path 1a - overdetermined, with many more rows than columns.*            MM = N            ITAU = 1            NWORK = ITAU + N**           Compute A=Q*R.*           (Workspace: need 2*N, prefer N+N*NB)*            CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                   LWORK-NWORK+1, INFO )**           Multiply B by transpose(Q).*           (Workspace: need N+NRHS, prefer N+NRHS*NB)*            CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,     $                   LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )**           Zero out below R.*            IF( N.GT.1 ) THEN               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )            END IF         END IF*         IE = 1         ITAUQ = IE + N         ITAUP = ITAUQ + N         NWORK = ITAUP + N**        Bidiagonalize R in A.*        (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)*         CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,     $                INFO )**        Multiply B by transpose of left bidiagonalizing vectors of R.*        (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)*         CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )**        Solve the bidiagonal least squares problem.*         CALL DLALSD( 'U', SMLSIZ, N, NRHS, S, WORK( IE ), B, LDB,     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )         IF( INFO.NE.0 ) THEN            GO TO 10         END IF**        Multiply B by right bidiagonalizing vectors of R.*         CALL DORMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )*      ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+     $         MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN**        Path 2a - underdetermined, with many more columns than rows*        and sufficient workspace for an efficient algorithm.*         LDWORK = M         IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),     $       M*LDA+M+M*NRHS ) )LDWORK = LDA         ITAU = 1         NWORK = M + 1**        Compute A=L*Q.*        (Workspace: need 2*M, prefer M+M*NB)*         CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),     $                LWORK-NWORK+1, INFO )         IL = NWORK**        Copy L to WORK(IL), zeroing out above its diagonal.*         CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )         CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),     $                LDWORK )         IE = IL + LDWORK*M         ITAUQ = IE + M         ITAUP = ITAUQ + M         NWORK = ITAUP + M**        Bidiagonalize L in WORK(IL).*        (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)*         CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),     $                WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),     $                LWORK-NWORK+1, INFO )**        Multiply B by transpose of left bidiagonalizing vectors of L.*        (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)*         CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,     $                WORK( ITAUQ ), B, LDB, WORK( NWORK ),     $                LWORK-NWORK+1, INFO )**        Solve the bidiagonal least squares problem.*         CALL DLALSD( 'U', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )         IF( INFO.NE.0 ) THEN            GO TO 10         END IF**        Multiply B by right bidiagonalizing vectors of L.*         CALL DORMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,     $                WORK( ITAUP ), B, LDB, WORK( NWORK ),     $                LWORK-NWORK+1, INFO )**        Zero out below first M rows of B.*         CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )         NWORK = ITAU + M**        Multiply transpose(Q) by B.*        (Workspace: need M+NRHS, prefer M+NRHS*NB)*         CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,     $                LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )*      ELSE**        Path 2 - remaining underdetermined cases.*         IE = 1         ITAUQ = IE + M         ITAUP = ITAUQ + M         NWORK = ITAUP + M**        Bidiagonalize A.*        (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)*         CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),     $                WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,     $                INFO )**        Multiply B by transpose of left bidiagonalizing vectors.*        (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)*         CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )**        Solve the bidiagonal least squares problem.*         CALL DLALSD( 'L', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,     $                RCOND, RANK, WORK( NWORK ), IWORK, INFO )         IF( INFO.NE.0 ) THEN            GO TO 10         END IF**        Multiply B by right bidiagonalizing vectors of A.*         CALL DORMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),     $                B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )*      END IF**     Undo scaling.*      IF( IASCL.EQ.1 ) THEN         CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )         CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,     $                INFO )      ELSE IF( IASCL.EQ.2 ) THEN         CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )         CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,     $                INFO )      END IF      IF( IBSCL.EQ.1 ) THEN         CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )      ELSE IF( IBSCL.EQ.2 ) THEN         CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )      END IF*   10 CONTINUE      WORK( 1 ) = MAXWRK      RETURN**     End of DGELSD*      END

⌨️ 快捷键说明

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