ddrvbd.f
来自「famous linear algebra library (LAPACK) p」· F 代码 · 共 663 行 · 第 1/2 页
F
663 行
SUBROUTINE DDRVBD( NSIZES, MM, NN, NTYPES, DOTYPE, ISEED, THRESH,
$ A, LDA, U, LDU, VT, LDVT, ASAV, USAV, VTSAV, S,
$ SSAV, E, WORK, LWORK, IWORK, NOUT, INFO )
*
* -- LAPACK test routine (version 3.1) --
* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
* November 2006
*
* .. Scalar Arguments ..
INTEGER INFO, LDA, LDU, LDVT, LWORK, NOUT, NSIZES,
$ NTYPES
DOUBLE PRECISION THRESH
* ..
* .. Array Arguments ..
LOGICAL DOTYPE( * )
INTEGER ISEED( 4 ), IWORK( * ), MM( * ), NN( * )
DOUBLE PRECISION A( LDA, * ), ASAV( LDA, * ), E( * ), S( * ),
$ SSAV( * ), U( LDU, * ), USAV( LDU, * ),
$ VT( LDVT, * ), VTSAV( LDVT, * ), WORK( * )
* ..
*
* Purpose
* =======
*
* DDRVBD checks the singular value decomposition (SVD) drivers
* DGESVD and SGESDD.
* Both DGESVD and SGESDD factor A = U diag(S) VT, where U and VT are
* orthogonal and diag(S) is diagonal with the entries of the array S
* on its diagonal. The entries of S are the singular values,
* nonnegative and stored in decreasing order. U and VT can be
* optionally not computed, overwritten on A, or computed partially.
*
* A is M by N. Let MNMIN = min( M, N ). S has dimension MNMIN.
* U can be M by M or M by MNMIN. VT can be N by N or MNMIN by N.
*
* When DDRVBD is called, a number of matrix "sizes" (M's and N's)
* and a number of matrix "types" are specified. For each size (M,N)
* and each type of matrix, and for the minimal workspace as well as
* workspace adequate to permit blocking, an M x N matrix "A" will be
* generated and used to test the SVD routines. For each matrix, A will
* be factored as A = U diag(S) VT and the following 12 tests computed:
*
* Test for DGESVD:
*
* (1) | A - U diag(S) VT | / ( |A| max(M,N) ulp )
*
* (2) | I - U'U | / ( M ulp )
*
* (3) | I - VT VT' | / ( N ulp )
*
* (4) S contains MNMIN nonnegative values in decreasing order.
* (Return 0 if true, 1/ULP if false.)
*
* (5) | U - Upartial | / ( M ulp ) where Upartial is a partially
* computed U.
*
* (6) | VT - VTpartial | / ( N ulp ) where VTpartial is a partially
* computed VT.
*
* (7) | S - Spartial | / ( MNMIN ulp |S| ) where Spartial is the
* vector of singular values from the partial SVD
*
* Test for DGESDD:
*
* (8) | A - U diag(S) VT | / ( |A| max(M,N) ulp )
*
* (9) | I - U'U | / ( M ulp )
*
* (10) | I - VT VT' | / ( N ulp )
*
* (11) S contains MNMIN nonnegative values in decreasing order.
* (Return 0 if true, 1/ULP if false.)
*
* (12) | U - Upartial | / ( M ulp ) where Upartial is a partially
* computed U.
*
* (13) | VT - VTpartial | / ( N ulp ) where VTpartial is a partially
* computed VT.
*
* (14) | S - Spartial | / ( MNMIN ulp |S| ) where Spartial is the
* vector of singular values from the partial SVD
*
* The "sizes" are specified by the arrays MM(1:NSIZES) and
* NN(1:NSIZES); the value of each element pair (MM(j),NN(j))
* specifies one size. The "types" are specified by a logical array
* DOTYPE( 1:NTYPES ); if DOTYPE(j) is .TRUE., then matrix type "j"
* will be generated.
* Currently, the list of possible types is:
*
* (1) The zero matrix.
* (2) The identity matrix.
* (3) A matrix of the form U D V, where U and V are orthogonal and
* D has evenly spaced entries 1, ..., ULP with random signs
* on the diagonal.
* (4) Same as (3), but multiplied by the underflow-threshold / ULP.
* (5) Same as (3), but multiplied by the overflow-threshold * ULP.
*
* Arguments
* ==========
*
* NSIZES (input) INTEGER
* The number of matrix sizes (M,N) contained in the vectors
* MM and NN.
*
* MM (input) INTEGER array, dimension (NSIZES)
* The values of the matrix row dimension M.
*
* NN (input) INTEGER array, dimension (NSIZES)
* The values of the matrix column dimension N.
*
* NTYPES (input) INTEGER
* The number of elements in DOTYPE. If it is zero, DDRVBD
* does nothing. It must be at least zero. If it is MAXTYP+1
* and NSIZES is 1, then an additional type, MAXTYP+1 is
* defined, which is to use whatever matrices are in A and B.
* This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
* DOTYPE(MAXTYP+1) is .TRUE. .
*
* DOTYPE (input) LOGICAL array, dimension (NTYPES)
* If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix
* of type j will be generated. If NTYPES is smaller than the
* maximum number of types defined (PARAMETER MAXTYP), then
* types NTYPES+1 through MAXTYP will not be generated. If
* NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through
* DOTYPE(NTYPES) will be ignored.
*
* ISEED (input/output) INTEGER array, dimension (4)
* On entry, the seed of the random number generator. The array
* elements should be between 0 and 4095; if not they will be
* reduced mod 4096. Also, ISEED(4) must be odd.
* On exit, ISEED is changed and can be used in the next call to
* DDRVBD to continue the same random number sequence.
*
* THRESH (input) DOUBLE PRECISION
* The threshold value for the test ratios. A result is
* included in the output file if RESULT >= THRESH. The test
* ratios are scaled to be O(1), so THRESH should be a small
* multiple of 1, e.g., 10 or 100. To have every test ratio
* printed, use THRESH = 0.
*
* A (workspace) DOUBLE PRECISION array, dimension (LDA,NMAX)
* where NMAX is the maximum value of N in NN.
*
* LDA (input) INTEGER
* The leading dimension of the array A. LDA >= max(1,MMAX),
* where MMAX is the maximum value of M in MM.
*
* U (workspace) DOUBLE PRECISION array, dimension (LDU,MMAX)
*
* LDU (input) INTEGER
* The leading dimension of the array U. LDU >= max(1,MMAX).
*
* VT (workspace) DOUBLE PRECISION array, dimension (LDVT,NMAX)
*
* LDVT (input) INTEGER
* The leading dimension of the array VT. LDVT >= max(1,NMAX).
*
* ASAV (workspace) DOUBLE PRECISION array, dimension (LDA,NMAX)
*
* USAV (workspace) DOUBLE PRECISION array, dimension (LDU,MMAX)
*
* VTSAV (workspace) DOUBLE PRECISION array, dimension (LDVT,NMAX)
*
* S (workspace) DOUBLE PRECISION array, dimension
* (max(min(MM,NN)))
*
* SSAV (workspace) DOUBLE PRECISION array, dimension
* (max(min(MM,NN)))
*
* E (workspace) DOUBLE PRECISION array, dimension
* (max(min(MM,NN)))
*
* WORK (workspace) DOUBLE PRECISION array, dimension (LWORK)
*
* LWORK (input) INTEGER
* The number of entries in WORK. This must be at least
* max(3*MN+MX,5*MN-4)+2*MN**2 for all pairs
* pairs (MN,MX)=( min(MM(j),NN(j), max(MM(j),NN(j)) )
*
* IWORK (workspace) INTEGER array, dimension at least 8*min(M,N)
*
* NOUT (input) INTEGER
* The FORTRAN unit number for printing out error messages
* (e.g., if a routine returns IINFO not equal to 0.)
*
* INFO (output) INTEGER
* If 0, then everything ran OK.
* -1: NSIZES < 0
* -2: Some MM(j) < 0
* -3: Some NN(j) < 0
* -4: NTYPES < 0
* -7: THRESH < 0
* -10: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ).
* -12: LDU < 1 or LDU < MMAX.
* -14: LDVT < 1 or LDVT < NMAX, where NMAX is max( NN(j) ).
* -21: LWORK too small.
* If DLATMS, or DGESVD returns an error code, the
* absolute value of it is returned.
*
* =====================================================================
*
* .. Parameters ..
DOUBLE PRECISION ZERO, ONE
PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
INTEGER MAXTYP
PARAMETER ( MAXTYP = 5 )
* ..
* .. Local Scalars ..
LOGICAL BADMM, BADNN
CHARACTER JOBQ, JOBU, JOBVT
CHARACTER*3 PATH
INTEGER I, IINFO, IJQ, IJU, IJVT, IWS, IWTMP, J, JSIZE,
$ JTYPE, LSWORK, M, MINWRK, MMAX, MNMAX, MNMIN,
$ MTYPES, N, NFAIL, NMAX, NTEST
DOUBLE PRECISION ANORM, DIF, DIV, OVFL, ULP, ULPINV, UNFL
* ..
* .. Local Arrays ..
CHARACTER CJOB( 4 )
INTEGER IOLDSD( 4 )
DOUBLE PRECISION RESULT( 14 )
* ..
* .. External Functions ..
DOUBLE PRECISION DLAMCH
EXTERNAL DLAMCH
* ..
* .. External Subroutines ..
EXTERNAL ALASVM, DBDT01, DGESDD, DGESVD, DLABAD, DLACPY,
$ DLASET, DLATMS, DORT01, DORT03, XERBLA
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, DBLE, MAX, MIN
* ..
* .. Scalars in Common ..
LOGICAL LERR, OK
CHARACTER*6 SRNAMT
INTEGER INFOT, NUNIT
* ..
* .. Common blocks ..
COMMON / INFOC / INFOT, NUNIT, OK, LERR
COMMON / SRNAMC / SRNAMT
* ..
* .. Data statements ..
DATA CJOB / 'N', 'O', 'S', 'A' /
* ..
* .. Executable Statements ..
*
* Check for errors
*
INFO = 0
BADMM = .FALSE.
BADNN = .FALSE.
MMAX = 1
NMAX = 1
MNMAX = 1
MINWRK = 1
DO 10 J = 1, NSIZES
MMAX = MAX( MMAX, MM( J ) )
IF( MM( J ).LT.0 )
$ BADMM = .TRUE.
NMAX = MAX( NMAX, NN( J ) )
IF( NN( J ).LT.0 )
$ BADNN = .TRUE.
MNMAX = MAX( MNMAX, MIN( MM( J ), NN( J ) ) )
MINWRK = MAX( MINWRK, MAX( 3*MIN( MM( J ),
$ NN( J ) )+MAX( MM( J ), NN( J ) ), 5*MIN( MM( J ),
$ NN( J )-4 ) )+2*MIN( MM( J ), NN( J ) )**2 )
10 CONTINUE
*
* Check for errors
*
IF( NSIZES.LT.0 ) THEN
INFO = -1
ELSE IF( BADMM ) THEN
INFO = -2
ELSE IF( BADNN ) THEN
INFO = -3
ELSE IF( NTYPES.LT.0 ) THEN
INFO = -4
ELSE IF( LDA.LT.MAX( 1, MMAX ) ) THEN
INFO = -10
ELSE IF( LDU.LT.MAX( 1, MMAX ) ) THEN
INFO = -12
ELSE IF( LDVT.LT.MAX( 1, NMAX ) ) THEN
INFO = -14
ELSE IF( MINWRK.GT.LWORK ) THEN
INFO = -21
END IF
*
IF( INFO.NE.0 ) THEN
CALL XERBLA( 'DDRVBD', -INFO )
RETURN
END IF
*
* Initialize constants
*
PATH( 1: 1 ) = 'Double precision'
PATH( 2: 3 ) = 'BD'
NFAIL = 0
NTEST = 0
UNFL = DLAMCH( 'Safe minimum' )
OVFL = ONE / UNFL
CALL DLABAD( UNFL, OVFL )
ULP = DLAMCH( 'Precision' )
ULPINV = ONE / ULP
INFOT = 0
*
* Loop over sizes, types
*
DO 150 JSIZE = 1, NSIZES
M = MM( JSIZE )
N = NN( JSIZE )
MNMIN = MIN( M, N )
*
IF( NSIZES.NE.1 ) THEN
MTYPES = MIN( MAXTYP, NTYPES )
ELSE
MTYPES = MIN( MAXTYP+1, NTYPES )
END IF
*
DO 140 JTYPE = 1, MTYPES
IF( .NOT.DOTYPE( JTYPE ) )
$ GO TO 140
*
DO 20 J = 1, 4
IOLDSD( J ) = ISEED( J )
20 CONTINUE
*
* Compute "A"
*
IF( MTYPES.GT.MAXTYP )
$ GO TO 30
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?