📄 dgelsd.f
字号:
SUBROUTINE DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, $ WORK, LWORK, IWORK, INFO )** -- LAPACK driver routine (version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* October 31, 1999** .. Scalar Arguments .. INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK DOUBLE PRECISION RCOND* ..* .. Array Arguments .. INTEGER IWORK( * ) DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )* ..** Purpose* =======** DGELSD computes the minimum-norm solution to a real linear least* squares problem:* minimize 2-norm(| b - A*x |)* using the singular value decomposition (SVD) of A. A is an M-by-N* matrix which may be rank-deficient.** Several right hand side vectors b and solution vectors x can be* handled in a single call; they are stored as the columns of the* M-by-NRHS right hand side matrix B and the N-by-NRHS solution* matrix X.** The problem is solved in three steps:* (1) Reduce the coefficient matrix A to bidiagonal form with* Householder transformations, reducing the original problem* into a "bidiagonal least squares problem" (BLS)* (2) Solve the BLS using a divide and conquer approach.* (3) Apply back all the Householder tranformations to solve* the original least squares problem.** The effective rank of A is determined by treating as zero those* singular values which are less than RCOND times the largest singular* value.** The divide and conquer algorithm makes very mild assumptions about* floating point arithmetic. It will work on machines with a guard* digit in add/subtract, or on those binary machines without guard* digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or* Cray-2. It could conceivably fail on hexadecimal or decimal machines* without guard digits, but we know of none.** Arguments* =========** M (input) INTEGER* The number of rows of A. M >= 0.** N (input) INTEGER* The number of columns of A. N >= 0.** NRHS (input) INTEGER* The number of right hand sides, i.e., the number of columns* of the matrices B and X. NRHS >= 0.** A (input) DOUBLE PRECISION array, dimension (LDA,N)* On entry, the M-by-N matrix A.* On exit, A has been destroyed.** LDA (input) INTEGER* The leading dimension of the array A. LDA >= max(1,M).** B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)* On entry, the M-by-NRHS right hand side matrix B.* On exit, B is overwritten by the N-by-NRHS solution* matrix X. If m >= n and RANK = n, the residual* sum-of-squares for the solution in the i-th column is given* by the sum of squares of elements n+1:m in that column.** LDB (input) INTEGER* The leading dimension of the array B. LDB >= max(1,max(M,N)).** S (output) DOUBLE PRECISION array, dimension (min(M,N))* The singular values of A in decreasing order.* The condition number of A in the 2-norm = S(1)/S(min(m,n)).** RCOND (input) DOUBLE PRECISION* RCOND is used to determine the effective rank of A.* Singular values S(i) <= RCOND*S(1) are treated as zero.* If RCOND < 0, machine precision is used instead.** RANK (output) INTEGER* The effective rank of A, i.e., the number of singular values* which are greater than RCOND*S(1).** WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK must be at least 1.* The exact minimum amount of workspace needed depends on M,* N and NRHS. As long as LWORK is at least* 12*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2,* if M is greater than or equal to N or* 12*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS + (SMLSIZ+1)**2,* if M is less than N, the code will execute correctly.* SMLSIZ is returned by ILAENV and is equal to the maximum* size of the subproblems at the bottom of the computation* tree (usually about 25), and* NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )* For good performance, LWORK should generally be larger.** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** IWORK (workspace) INTEGER array, dimension (LIWORK)* LIWORK >= 3 * MINMN * NLVL + 11 * MINMN,* where MINMN = MIN( M,N ).** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value.* > 0: the algorithm for computing the SVD failed to converge;* if INFO = i, i off-diagonal elements of an intermediate* bidiagonal form did not converge to zero.** Further Details* ===============** Based on contributions by* Ming Gu and Ren-Cang Li, Computer Science Division, University of* California at Berkeley, USA* Osni Marques, LBNL/NERSC, USA** =====================================================================** .. Parameters .. DOUBLE PRECISION ZERO, ONE, TWO PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )* ..* .. Local Scalars .. LOGICAL LQUERY INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ, $ LDWORK, MAXMN, MAXWRK, MINMN, MINWRK, MM, $ MNTHR, NLVL, NWORK, SMLSIZ, WLALSD DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM* ..* .. External Subroutines .. EXTERNAL DGEBRD, DGELQF, DGEQRF, DLABAD, DLACPY, DLALSD, $ DLASCL, DLASET, DORMBR, DORMLQ, DORMQR, XERBLA* ..* .. External Functions .. INTEGER ILAENV DOUBLE PRECISION DLAMCH, DLANGE EXTERNAL ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions .. INTRINSIC DBLE, INT, LOG, MAX, MIN* ..* .. Executable Statements ..** Test the input arguments.* INFO = 0 MINMN = MIN( M, N ) MAXMN = MAX( M, N ) MNTHR = ILAENV( 6, 'DGELSD', ' ', M, N, NRHS, -1 ) LQUERY = ( LWORK.EQ.-1 ) IF( M.LT.0 ) THEN INFO = -1 ELSE IF( N.LT.0 ) THEN INFO = -2 ELSE IF( NRHS.LT.0 ) THEN INFO = -3 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN INFO = -5 ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN INFO = -7 END IF* SMLSIZ = ILAENV( 9, 'DGELSD', ' ', 0, 0, 0, 0 )** Compute workspace.* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)* MINWRK = 1 MINMN = MAX( 1, MINMN ) NLVL = MAX( INT( LOG( DBLE( MINMN ) / DBLE( SMLSIZ+1 ) ) / $ LOG( TWO ) )+ 1, 0 )* IF( INFO.EQ.0 ) THEN MAXWRK = 0 MM = M IF( M.GE.N .AND. M.GE.MNTHR ) THEN** Path 1a - overdetermined, with many more rows than columns.* MM = N MAXWRK = MAX( MAXWRK, N+N*ILAENV( 1, 'DGEQRF', ' ', M, N, $ -1, -1 ) ) MAXWRK = MAX( MAXWRK, N+NRHS* $ ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N, -1 ) ) END IF IF( M.GE.N ) THEN** Path 1 - overdetermined or exactly determined.* MAXWRK = MAX( MAXWRK, 3*N+( MM+N )* $ ILAENV( 1, 'DGEBRD', ' ', MM, N, -1, -1 ) ) MAXWRK = MAX( MAXWRK, 3*N+NRHS* $ ILAENV( 1, 'DORMBR', 'QLT', MM, NRHS, N, -1 ) ) MAXWRK = MAX( MAXWRK, 3*N+( N-1 )* $ ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, N, -1 ) ) WLALSD = 9*N+2*N*SMLSIZ+8*N*NLVL+N*NRHS+(SMLSIZ+1)**2 MAXWRK = MAX( MAXWRK, 3*N+WLALSD ) MINWRK = MAX( 3*N+MM, 3*N+NRHS, 3*N+WLALSD ) END IF IF( N.GT.M ) THEN WLALSD = 9*M+2*M*SMLSIZ+8*M*NLVL+M*NRHS+(SMLSIZ+1)**2 IF( N.GE.MNTHR ) THEN** Path 2a - underdetermined, with many more columns* than rows.* MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 ) MAXWRK = MAX( MAXWRK, M*M+4*M+2*M* $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) ) MAXWRK = MAX( MAXWRK, M*M+4*M+NRHS* $ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, M, -1 ) ) MAXWRK = MAX( MAXWRK, M*M+4*M+( M-1 )* $ ILAENV( 1, 'DORMBR', 'PLN', M, NRHS, M, -1 ) ) IF( NRHS.GT.1 ) THEN MAXWRK = MAX( MAXWRK, M*M+M+M*NRHS ) ELSE MAXWRK = MAX( MAXWRK, M*M+2*M ) END IF MAXWRK = MAX( MAXWRK, M+NRHS* $ ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M, -1 ) ) MAXWRK = MAX( MAXWRK, M*M+4*M+WLALSD ) ELSE** Path 2 - remaining underdetermined cases.* MAXWRK = 3*M + ( N+M )*ILAENV( 1, 'DGEBRD', ' ', M, N, $ -1, -1 ) MAXWRK = MAX( MAXWRK, 3*M+NRHS* $ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, N, -1 ) ) MAXWRK = MAX( MAXWRK, 3*M+M* $ ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, M, -1 ) ) MAXWRK = MAX( MAXWRK, 3*M+WLALSD ) END IF MINWRK = MAX( 3*M+NRHS, 3*M+M, 3*M+WLALSD ) END IF MINWRK = MIN( MINWRK, MAXWRK ) WORK( 1 ) = MAXWRK IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN INFO = -12 END IF END IF* IF( INFO.NE.0 ) THEN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -