📄 zgelss.f
字号:
CALL ZUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, WORK( ITAUQ ), $ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNMBR ) = TIMNG( UNMBR ) + ( T2-T1 )** Generate right bidiagonalizing vectors of R in A* (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) OPCNT( UNGBR ) = OPCNT( UNGBR ) + $ DOPLA2( 'ZUNGBR', 'P', N, N, N, 0, NB ) T1 = DSECND( ) CALL ZUNGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ), $ WORK( IWORK ), LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNGBR ) = TIMNG( UNGBR ) + ( T2-T1 ) IRWORK = IE + N** Perform bidiagonal QR iteration* multiply B by transpose of left singular vectors* compute right singular vectors in A* (CWorkspace: none)* (RWorkspace: need BDSPAC)* OPS = 0 T1 = DSECND( ) CALL ZBDSQR( 'U', N, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM, $ 1, B, LDB, RWORK( IRWORK ), INFO ) T2 = DSECND( ) TIMNG( BDSQR ) = TIMNG( BDSQR ) + ( T2-T1 ) OPCNT( BDSQR ) = OPCNT( BDSQR ) + OPS IF( INFO.NE.0 ) $ GO TO 70** Multiply B by reciprocals of singular values* OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 1 ) THR = MAX( RCOND*S( 1 ), SFMIN ) IF( RCOND.LT.ZERO ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 1 ) THR = MAX( EPS*S( 1 ), SFMIN ) END IF RANK = 0 DO 10 I = 1, N IF( S( I ).GT.THR ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*NRHS+3 ) CALL ZDRSCL( NRHS, S( I ), B( I, 1 ), LDB ) RANK = RANK + 1 ELSE CALL ZLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB ) END IF 10 CONTINUE** Multiply B by right singular vectors* (CWorkspace: need N, prefer N*NRHS)* (RWorkspace: none)* IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN OPCNT( GEMM ) = OPCNT( GEMM ) + $ DOPBL3( 'ZGEMM ', N, NRHS, N ) T1 = DSECND( ) CALL ZGEMM( 'C', 'N', N, NRHS, N, CONE, A, LDA, B, LDB, $ CZERO, WORK, LDB ) T2 = DSECND( ) TIMNG( GEMM ) = TIMNG( GEMM ) + ( T2-T1 ) CALL ZLACPY( 'G', N, NRHS, WORK, LDB, B, LDB ) ELSE IF( NRHS.GT.1 ) THEN CHUNK = LWORK / N DO 20 I = 1, NRHS, CHUNK BL = MIN( NRHS-I+1, CHUNK ) OPCNT( GEMM ) = OPCNT( GEMM ) + $ DOPBL3( 'ZGEMM ', N, BL, N ) T1 = DSECND( ) CALL ZGEMM( 'C', 'N', N, BL, N, CONE, A, LDA, B( 1, I ), $ LDB, CZERO, WORK, N ) T2 = DSECND( ) TIMNG( GEMM ) = TIMNG( GEMM ) + ( T2-T1 ) CALL ZLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB ) 20 CONTINUE ELSE OPCNT( GEMV ) = OPCNT( GEMV ) + $ DOPBL2( 'ZGEMV ', N, N, 0, 0 ) T1 = DSECND( ) CALL ZGEMV( 'C', N, N, CONE, A, LDA, B, 1, CZERO, WORK, 1 ) T2 = DSECND( ) TIMNG( GEMV ) = TIMNG( GEMV ) + ( T2-T1 ) CALL ZCOPY( N, WORK, 1, B, 1 ) END IF* ELSE IF( N.GE.MNTHR .AND. LWORK.GE.3*M+M*M+MAX( M, NRHS, N-2*M ) ) $ THEN** Underdetermined case, M much less than N** Path 2a - underdetermined, with many more columns than rows* and sufficient workspace for an efficient algorithm* LDWORK = M IF( LWORK.GE.3*M+M*LDA+MAX( M, NRHS, N-2*M ) ) $ LDWORK = LDA ITAU = 1 IWORK = M + 1** Compute A=L*Q* (CWorkspace: need 2*M, prefer M+M*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 ) OPCNT( GELQF ) = OPCNT( GELQF ) + $ DOPLA( 'ZGELQF', M, N, 0, 0, NB ) T1 = DSECND( ) CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ), $ LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( GELQF ) = TIMNG( GELQF ) + ( T2-T1 ) IL = IWORK** Copy L to WORK(IL), zeroing out above it* CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK ) CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, WORK( IL+LDWORK ), $ LDWORK ) IE = 1 ITAUQ = IL + LDWORK*M ITAUP = ITAUQ + M IWORK = ITAUP + M** Bidiagonalize L in WORK(IL)* (CWorkspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)* (RWorkspace: need M)* NB = ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) OPCNT( GEBRD ) = OPCNT( GEBRD ) + $ DOPLA( 'ZGEBRD', M, M, 0, 0, NB ) T1 = DSECND( ) CALL ZGEBRD( M, M, WORK( IL ), LDWORK, S, RWORK( IE ), $ WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ), $ LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( GEBRD ) = TIMNG( GEBRD ) + ( T2-T1 )** Multiply B by transpose of left bidiagonalizing vectors of L* (CWorkspace: need M*M+3*M+NRHS, prefer M*M+3*M+NRHS*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZUNMBR', 'QLC', M, NRHS, M, -1 ) OPCNT( UNMBR ) = OPCNT( UNMBR ) + $ DOPLA2( 'ZUNMBR', 'QLC', M, NRHS, M, 0, NB ) T1 = DSECND( ) CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, M, WORK( IL ), LDWORK, $ WORK( ITAUQ ), B, LDB, WORK( IWORK ), $ LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNMBR ) = TIMNG( UNMBR ) + ( T2-T1 )** Generate right bidiagonalizing vectors of R in WORK(IL)* (CWorkspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZUNGBR', 'P', M, M, M, -1 ) OPCNT( UNGBR ) = OPCNT( UNGBR ) + $ DOPLA2( 'ZUNGBR', 'P', M, M, M, 0, NB ) T1 = DSECND( ) CALL ZUNGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ), $ WORK( IWORK ), LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNGBR ) = TIMNG( UNGBR ) + ( T2-T1 ) IRWORK = IE + M** Perform bidiagonal QR iteration, computing right singular* vectors of L in WORK(IL) and multiplying B by transpose of* left singular vectors* (CWorkspace: need M*M)* (RWorkspace: need BDSPAC)* OPS = 0 T1 = DSECND( ) CALL ZBDSQR( 'U', M, M, 0, NRHS, S, RWORK( IE ), WORK( IL ), $ LDWORK, A, LDA, B, LDB, RWORK( IRWORK ), INFO ) T2 = DSECND( ) TIMNG( BDSQR ) = TIMNG( BDSQR ) + ( T2-T1 ) OPCNT( BDSQR ) = OPCNT( BDSQR ) + OPS IF( INFO.NE.0 ) $ GO TO 70** Multiply B by reciprocals of singular values* OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 1 ) THR = MAX( RCOND*S( 1 ), SFMIN ) IF( RCOND.LT.ZERO ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 1 ) THR = MAX( EPS*S( 1 ), SFMIN ) END IF RANK = 0 DO 30 I = 1, M IF( S( I ).GT.THR ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*NRHS+3 ) CALL ZDRSCL( NRHS, S( I ), B( I, 1 ), LDB ) RANK = RANK + 1 ELSE CALL ZLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB ) END IF 30 CONTINUE IWORK = IL + M*LDWORK** Multiply B by right singular vectors of L in WORK(IL)* (CWorkspace: need M*M+2*M, prefer M*M+M+M*NRHS)* (RWorkspace: none)* IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN OPCNT( GEMM ) = OPCNT( GEMM ) + $ DOPBL3( 'ZGEMM ', M, NRHS, M ) CALL ZGEMM( 'C', 'N', M, NRHS, M, CONE, WORK( IL ), LDWORK, $ B, LDB, CZERO, WORK( IWORK ), LDB ) CALL ZLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB ) ELSE IF( NRHS.GT.1 ) THEN CHUNK = ( LWORK-IWORK+1 ) / M DO 40 I = 1, NRHS, CHUNK BL = MIN( NRHS-I+1, CHUNK ) OPCNT( GEMM ) = OPCNT( GEMM ) + $ DOPBL3( 'ZGEMM ', M, BL, M ) T1 = DSECND( ) CALL ZGEMM( 'C', 'N', M, BL, M, CONE, WORK( IL ), LDWORK, $ B( 1, I ), LDB, CZERO, WORK( IWORK ), N ) T2 = DSECND( ) TIMNG( GEMM ) = TIMNG( GEMM ) + ( T2-T1 ) CALL ZLACPY( 'G', M, BL, WORK( IWORK ), N, B( 1, I ), $ LDB ) 40 CONTINUE ELSE OPCNT( GEMV ) = OPCNT( GEMV ) + $ DOPBL2( 'ZGEMV ', M, M, 0, 0 ) T1 = DSECND( ) CALL ZGEMV( 'C', M, M, CONE, WORK( IL ), LDWORK, B( 1, 1 ), $ 1, CZERO, WORK( IWORK ), 1 ) T2 = DSECND( ) TIMNG( GEMV ) = TIMNG( GEMV ) + ( T2-T1 ) CALL ZCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 ) END IF** Zero out below first M rows of B* CALL ZLASET( 'F', N-M, NRHS, CZERO, CZERO, B( M+1, 1 ), LDB ) IWORK = ITAU + M** Multiply transpose(Q) by B* (CWorkspace: need M+NRHS, prefer M+NHRS*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZUNMLQ', 'LC', N, NRHS, M, -1 ) OPCNT( UNMLQ ) = OPCNT( UNMLQ ) + $ DOPLA( 'ZUNMLQ', N, NRHS, M, 0, NB ) T1 = DSECND( ) CALL ZUNMLQ( 'L', 'C', N, NRHS, M, A, LDA, WORK( ITAU ), B, $ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNMLQ ) = TIMNG( UNMLQ ) + ( T2-T1 )* ELSE** Path 2 - remaining underdetermined cases* IE = 1 ITAUQ = 1 ITAUP = ITAUQ + M IWORK = ITAUP + M** Bidiagonalize A* (CWorkspace: need 3*M, prefer 2*M+(M+N)*NB)* (RWorkspace: need N)* NB = ILAENV( 1, 'ZGEBRD', ' ', M, N, -1, -1 ) OPCNT( GEBRD ) = OPCNT( GEBRD ) + $ DOPLA( 'ZGEBRD', M, N, 0, 0, NB ) T1 = DSECND( ) CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ), $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1, $ INFO ) T2 = DSECND( ) TIMNG( GEBRD ) = TIMNG( GEBRD ) + ( T2-T1 )** Multiply B by transpose of left bidiagonalizing vectors* (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZUNMBR', 'QLC', M, NRHS, N, -1 ) OPCNT( UNMBR ) = OPCNT( UNMBR ) + $ DOPLA2( 'ZUNMBR', 'QLC', M, NRHS, N, 0, NB ) T1 = DSECND( ) CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, WORK( ITAUQ ), $ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNMBR ) = TIMNG( UNMBR ) + ( T2-T1 )** Generate right bidiagonalizing vectors in A* (CWorkspace: need 3*M, prefer 2*M+M*NB)* (RWorkspace: none)* NB = ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) OPCNT( UNGBR ) = OPCNT( UNGBR ) + $ DOPLA2( 'ZUNGBR', 'P', M, N, M, 0, NB ) T1 = DSECND( ) CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ), $ WORK( IWORK ), LWORK-IWORK+1, INFO ) T2 = DSECND( ) TIMNG( UNGBR ) = TIMNG( UNGBR ) + ( T2-T1 ) IRWORK = IE + M** Perform bidiagonal QR iteration,* computing right singular vectors of A in A and* multiplying B by transpose of left singular vectors* (CWorkspace: none)* (RWorkspace: need BDSPAC)* OPS = 0 T1 = DSECND( ) CALL ZBDSQR( 'L', M, N, 0, NRHS, S, RWORK( IE ), A, LDA, VDUM, $ 1, B, LDB, RWORK( IRWORK ), INFO ) T2 = DSECND( ) TIMNG( BDSQR ) = TIMNG( BDSQR ) + ( T2-T1 ) OPCNT( BDSQR ) = OPCNT( BDSQR ) + OPS IF( INFO.NE.0 ) $ GO TO 70** Multiply B by reciprocals of singular values* OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 1 ) THR = MAX( RCOND*S( 1 ), SFMIN ) IF( RCOND.LT.ZERO ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 1 ) THR = MAX( EPS*S( 1 ), SFMIN ) END IF RANK = 0 DO 50 I = 1, M IF( S( I ).GT.THR ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*NRHS+3 ) CALL ZDRSCL( NRHS, S( I ), B( I, 1 ), LDB ) RANK = RANK + 1 ELSE CALL ZLASET( 'F', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB ) END IF 50 CONTINUE** Multiply B by right singular vectors of A* (CWorkspace: need N, prefer N*NRHS)* (RWorkspace: none)* IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN OPCNT( GEMM ) = OPCNT( GEMM ) + $ DOPBL3( 'ZGEMM ', N, NRHS, M ) T1 = DSECND( ) CALL ZGEMM( 'C', 'N', N, NRHS, M, CONE, A, LDA, B, LDB, $ CZERO, WORK, LDB ) T2 = DSECND( ) TIMNG( GEMM ) = TIMNG( GEMM ) + ( T2-T1 ) CALL ZLACPY( 'G', N, NRHS, WORK, LDB, B, LDB ) ELSE IF( NRHS.GT.1 ) THEN CHUNK = LWORK / N DO 60 I = 1, NRHS, CHUNK BL = MIN( NRHS-I+1, CHUNK ) OPCNT( GEMM ) = OPCNT( GEMM ) + $ DOPBL3( 'ZGEMM ', N, BL, N ) T1 = DSECND( ) CALL ZGEMM( 'C', 'N', N, BL, M, CONE, A, LDA, B( 1, I ), $ LDB, CZERO, WORK, N ) T2 = DSECND( ) TIMNG( GEMM ) = TIMNG( GEMM ) + ( T2-T1 ) CALL ZLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB ) 60 CONTINUE ELSE OPCNT( GELSS ) = OPCNT( GELSS ) + $ DOPBL2( 'ZGEMV ', M, N, 0, 0 ) T1 = DSECND( ) CALL ZGEMV( 'C', M, N, CONE, A, LDA, B, 1, CZERO, WORK, 1 ) T2 = DSECND( ) TIMNG( GEMV ) = TIMNG( GEMV ) + ( T2-T1 ) CALL ZCOPY( N, WORK, 1, B, 1 ) END IF END IF** Undo scaling* IF( IASCL.EQ.1 ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*( N*NRHS+MINMN ) ) CALL ZLASCL( '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 OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*( N*NRHS+MINMN ) ) CALL ZLASCL( '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 OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*N*NRHS ) CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO ) ELSE IF( IBSCL.EQ.2 ) THEN OPCNT( GELSS ) = OPCNT( GELSS ) + DBLE( 6*N*NRHS ) CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO ) END IF 70 CONTINUE WORK( 1 ) = MAXWRK RETURN** End of ZGELSS* END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -