dchkbd.f
来自「famous linear algebra library (LAPACK) p」· F 代码 · 共 969 行 · 第 1/3 页
F
969 行
* ======================================================================
*
* .. Parameters ..
DOUBLE PRECISION ZERO, ONE, TWO, HALF
PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
$ HALF = 0.5D0 )
INTEGER MAXTYP
PARAMETER ( MAXTYP = 16 )
* ..
* .. Local Scalars ..
LOGICAL BADMM, BADNN, BIDIAG
CHARACTER UPLO
CHARACTER*3 PATH
INTEGER I, IINFO, IMODE, ITYPE, J, JCOL, JSIZE, JTYPE,
$ LOG2UI, M, MINWRK, MMAX, MNMAX, MNMIN, MQ,
$ MTYPES, N, NFAIL, NMAX, NTEST
DOUBLE PRECISION AMNINV, ANORM, COND, OVFL, RTOVFL, RTUNFL,
$ TEMP1, TEMP2, ULP, ULPINV, UNFL
* ..
* .. Local Arrays ..
INTEGER IDUM( 1 ), IOLDSD( 4 ), KMAGN( MAXTYP ),
$ KMODE( MAXTYP ), KTYPE( MAXTYP )
DOUBLE PRECISION DUM( 1 ), DUMMA( 1 ), RESULT( 19 )
* ..
* .. External Functions ..
DOUBLE PRECISION DLAMCH, DLARND
EXTERNAL DLAMCH, DLARND
* ..
* .. External Subroutines ..
EXTERNAL ALASUM, DBDSDC, DBDSQR, DBDT01, DBDT02, DBDT03,
$ DCOPY, DGEBRD, DGEMM, DLABAD, DLACPY, DLAHD2,
$ DLASET, DLATMR, DLATMS, DORGBR, DORT01, XERBLA
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, EXP, INT, LOG, MAX, MIN, SQRT
* ..
* .. 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 KTYPE / 1, 2, 5*4, 5*6, 3*9, 10 /
DATA KMAGN / 2*1, 3*1, 2, 3, 3*1, 2, 3, 1, 2, 3, 0 /
DATA KMODE / 2*0, 4, 3, 1, 4, 4, 4, 3, 1, 4, 4, 0,
$ 0, 0, 0 /
* ..
* .. 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, MVAL( J ) )
IF( MVAL( J ).LT.0 )
$ BADMM = .TRUE.
NMAX = MAX( NMAX, NVAL( J ) )
IF( NVAL( J ).LT.0 )
$ BADNN = .TRUE.
MNMAX = MAX( MNMAX, MIN( MVAL( J ), NVAL( J ) ) )
MINWRK = MAX( MINWRK, 3*( MVAL( J )+NVAL( J ) ),
$ MVAL( J )*( MVAL( J )+MAX( MVAL( J ), NVAL( J ),
$ NRHS )+1 )+NVAL( J )*MIN( NVAL( J ), MVAL( J ) ) )
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( NRHS.LT.0 ) THEN
INFO = -6
ELSE IF( LDA.LT.MMAX ) THEN
INFO = -11
ELSE IF( LDX.LT.MMAX ) THEN
INFO = -17
ELSE IF( LDQ.LT.MMAX ) THEN
INFO = -21
ELSE IF( LDPT.LT.MNMAX ) THEN
INFO = -23
ELSE IF( MINWRK.GT.LWORK ) THEN
INFO = -27
END IF
*
IF( INFO.NE.0 ) THEN
CALL XERBLA( 'DCHKBD', -INFO )
RETURN
END IF
*
* Initialize constants
*
PATH( 1: 1 ) = 'Double precision'
PATH( 2: 3 ) = 'BD'
NFAIL = 0
NTEST = 0
UNFL = DLAMCH( 'Safe minimum' )
OVFL = DLAMCH( 'Overflow' )
CALL DLABAD( UNFL, OVFL )
ULP = DLAMCH( 'Precision' )
ULPINV = ONE / ULP
LOG2UI = INT( LOG( ULPINV ) / LOG( TWO ) )
RTUNFL = SQRT( UNFL )
RTOVFL = SQRT( OVFL )
INFOT = 0
*
* Loop over sizes, types
*
DO 200 JSIZE = 1, NSIZES
M = MVAL( JSIZE )
N = NVAL( JSIZE )
MNMIN = MIN( M, N )
AMNINV = ONE / MAX( M, N, 1 )
*
IF( NSIZES.NE.1 ) THEN
MTYPES = MIN( MAXTYP, NTYPES )
ELSE
MTYPES = MIN( MAXTYP+1, NTYPES )
END IF
*
DO 190 JTYPE = 1, MTYPES
IF( .NOT.DOTYPE( JTYPE ) )
$ GO TO 190
*
DO 20 J = 1, 4
IOLDSD( J ) = ISEED( J )
20 CONTINUE
*
DO 30 J = 1, 14
RESULT( J ) = -ONE
30 CONTINUE
*
UPLO = ' '
*
* Compute "A"
*
* Control parameters:
*
* KMAGN KMODE KTYPE
* =1 O(1) clustered 1 zero
* =2 large clustered 2 identity
* =3 small exponential (none)
* =4 arithmetic diagonal, (w/ eigenvalues)
* =5 random symmetric, w/ eigenvalues
* =6 nonsymmetric, w/ singular values
* =7 random diagonal
* =8 random symmetric
* =9 random nonsymmetric
* =10 random bidiagonal (log. distrib.)
*
IF( MTYPES.GT.MAXTYP )
$ GO TO 100
*
ITYPE = KTYPE( JTYPE )
IMODE = KMODE( JTYPE )
*
* Compute norm
*
GO TO ( 40, 50, 60 )KMAGN( JTYPE )
*
40 CONTINUE
ANORM = ONE
GO TO 70
*
50 CONTINUE
ANORM = ( RTOVFL*ULP )*AMNINV
GO TO 70
*
60 CONTINUE
ANORM = RTUNFL*MAX( M, N )*ULPINV
GO TO 70
*
70 CONTINUE
*
CALL DLASET( 'Full', LDA, N, ZERO, ZERO, A, LDA )
IINFO = 0
COND = ULPINV
*
BIDIAG = .FALSE.
IF( ITYPE.EQ.1 ) THEN
*
* Zero matrix
*
IINFO = 0
*
ELSE IF( ITYPE.EQ.2 ) THEN
*
* Identity
*
DO 80 JCOL = 1, MNMIN
A( JCOL, JCOL ) = ANORM
80 CONTINUE
*
ELSE IF( ITYPE.EQ.4 ) THEN
*
* Diagonal Matrix, [Eigen]values Specified
*
CALL DLATMS( MNMIN, MNMIN, 'S', ISEED, 'N', WORK, IMODE,
$ COND, ANORM, 0, 0, 'N', A, LDA,
$ WORK( MNMIN+1 ), IINFO )
*
ELSE IF( ITYPE.EQ.5 ) THEN
*
* Symmetric, eigenvalues specified
*
CALL DLATMS( MNMIN, MNMIN, 'S', ISEED, 'S', WORK, IMODE,
$ COND, ANORM, M, N, 'N', A, LDA,
$ WORK( MNMIN+1 ), IINFO )
*
ELSE IF( ITYPE.EQ.6 ) THEN
*
* Nonsymmetric, singular values specified
*
CALL DLATMS( M, N, 'S', ISEED, 'N', WORK, IMODE, COND,
$ ANORM, M, N, 'N', A, LDA, WORK( MNMIN+1 ),
$ IINFO )
*
ELSE IF( ITYPE.EQ.7 ) THEN
*
* Diagonal, random entries
*
CALL DLATMR( MNMIN, MNMIN, 'S', ISEED, 'N', WORK, 6, ONE,
$ ONE, 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
$ WORK( 2*MNMIN+1 ), 1, ONE, 'N', IWORK, 0, 0,
$ ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
*
ELSE IF( ITYPE.EQ.8 ) THEN
*
* Symmetric, random entries
*
CALL DLATMR( MNMIN, MNMIN, 'S', ISEED, 'S', WORK, 6, ONE,
$ ONE, 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
$ WORK( M+MNMIN+1 ), 1, ONE, 'N', IWORK, M, N,
$ ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
*
ELSE IF( ITYPE.EQ.9 ) THEN
*
* Nonsymmetric, random entries
*
CALL DLATMR( M, N, 'S', ISEED, 'N', WORK, 6, ONE, ONE,
$ 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
$ WORK( M+MNMIN+1 ), 1, ONE, 'N', IWORK, M, N,
$ ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
*
ELSE IF( ITYPE.EQ.10 ) THEN
*
* Bidiagonal, random entries
*
TEMP1 = -TWO*LOG( ULP )
DO 90 J = 1, MNMIN
BD( J ) = EXP( TEMP1*DLARND( 2, ISEED ) )
IF( J.LT.MNMIN )
$ BE( J ) = EXP( TEMP1*DLARND( 2, ISEED ) )
90 CONTINUE
*
IINFO = 0
BIDIAG = .TRUE.
IF( M.GE.N ) THEN
UPLO = 'U'
ELSE
UPLO = 'L'
END IF
ELSE
IINFO = 1
END IF
*
IF( IINFO.EQ.0 ) THEN
*
* Generate Right-Hand Side
*
IF( BIDIAG ) THEN
CALL DLATMR( MNMIN, NRHS, 'S', ISEED, 'N', WORK, 6,
$ ONE, ONE, 'T', 'N', WORK( MNMIN+1 ), 1,
$ ONE, WORK( 2*MNMIN+1 ), 1, ONE, 'N',
$ IWORK, MNMIN, NRHS, ZERO, ONE, 'NO', Y,
$ LDX, IWORK, IINFO )
ELSE
CALL DLATMR( M, NRHS, 'S', ISEED, 'N', WORK, 6, ONE,
$ ONE, 'T', 'N', WORK( M+1 ), 1, ONE,
$ WORK( 2*M+1 ), 1, ONE, 'N', IWORK, M,
$ NRHS, ZERO, ONE, 'NO', X, LDX, IWORK,
$ IINFO )
END IF
END IF
*
* Error Exit
*
IF( IINFO.NE.0 ) THEN
WRITE( NOUT, FMT = 9998 )'Generator', IINFO, M, N,
$ JTYPE, IOLDSD
INFO = ABS( IINFO )
RETURN
END IF
*
100 CONTINUE
*
* Call DGEBRD and DORGBR to compute B, Q, and P, do tests.
*
IF( .NOT.BIDIAG ) THEN
*
* Compute transformations to reduce A to bidiagonal form:
* B := Q' * A * P.
*
CALL DLACPY( ' ', M, N, A, LDA, Q, LDQ )
CALL DGEBRD( M, N, Q, LDQ, BD, BE, WORK, WORK( MNMIN+1 ),
$ WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
*
* Check error code from DGEBRD.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?