zchkbb.f
来自「famous linear algebra library (LAPACK) p」· F 代码 · 共 591 行 · 第 1/2 页
F
591 行
* Important constants
*
BADMM = .FALSE.
BADNN = .FALSE.
MMAX = 1
NMAX = 1
MNMAX = 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 ) ) )
10 CONTINUE
*
BADNNB = .FALSE.
KMAX = 0
DO 20 J = 1, NWDTHS
KMAX = MAX( KMAX, KK( J ) )
IF( KK( J ).LT.0 )
$ BADNNB = .TRUE.
20 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( NWDTHS.LT.0 ) THEN
INFO = -4
ELSE IF( BADNNB ) THEN
INFO = -5
ELSE IF( NTYPES.LT.0 ) THEN
INFO = -6
ELSE IF( NRHS.LT.0 ) THEN
INFO = -8
ELSE IF( LDA.LT.NMAX ) THEN
INFO = -13
ELSE IF( LDAB.LT.2*KMAX+1 ) THEN
INFO = -15
ELSE IF( LDQ.LT.NMAX ) THEN
INFO = -19
ELSE IF( LDP.LT.NMAX ) THEN
INFO = -21
ELSE IF( LDC.LT.NMAX ) THEN
INFO = -23
ELSE IF( ( MAX( LDA, NMAX )+1 )*NMAX.GT.LWORK ) THEN
INFO = -26
END IF
*
IF( INFO.NE.0 ) THEN
CALL XERBLA( 'ZCHKBB', -INFO )
RETURN
END IF
*
* Quick return if possible
*
IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 .OR. NWDTHS.EQ.0 )
$ RETURN
*
* More Important constants
*
UNFL = DLAMCH( 'Safe minimum' )
OVFL = ONE / UNFL
ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
ULPINV = ONE / ULP
RTUNFL = SQRT( UNFL )
RTOVFL = SQRT( OVFL )
*
* Loop over sizes, widths, types
*
NERRS = 0
NMATS = 0
*
DO 160 JSIZE = 1, NSIZES
M = MVAL( JSIZE )
N = NVAL( JSIZE )
MNMIN = MIN( M, N )
AMNINV = ONE / DBLE( MAX( 1, M, N ) )
*
DO 150 JWIDTH = 1, NWDTHS
K = KK( JWIDTH )
IF( K.GE.M .AND. K.GE.N )
$ GO TO 150
KL = MAX( 0, MIN( M-1, K ) )
KU = MAX( 0, MIN( N-1, K ) )
*
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
NMATS = NMATS + 1
NTEST = 0
*
DO 30 J = 1, 4
IOLDSD( J ) = ISEED( J )
30 CONTINUE
*
* 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/ singular values)
* =5 random log (none)
* =6 random nonhermitian, w/ singular values
* =7 (none)
* =8 (none)
* =9 random nonhermitian
*
IF( MTYPES.GT.MAXTYP )
$ GO TO 90
*
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 ZLASET( 'Full', LDA, N, CZERO, CZERO, A, LDA )
CALL ZLASET( 'Full', LDAB, N, CZERO, CZERO, AB, LDAB )
IINFO = 0
COND = ULPINV
*
* Special Matrices -- Identity & Jordan block
*
* Zero
*
IF( ITYPE.EQ.1 ) THEN
IINFO = 0
*
ELSE IF( ITYPE.EQ.2 ) THEN
*
* Identity
*
DO 80 JCOL = 1, N
A( JCOL, JCOL ) = ANORM
80 CONTINUE
*
ELSE IF( ITYPE.EQ.4 ) THEN
*
* Diagonal Matrix, singular values specified
*
CALL ZLATMS( M, N, 'S', ISEED, 'N', RWORK, IMODE,
$ COND, ANORM, 0, 0, 'N', A, LDA, WORK,
$ IINFO )
*
ELSE IF( ITYPE.EQ.6 ) THEN
*
* Nonhermitian, singular values specified
*
CALL ZLATMS( M, N, 'S', ISEED, 'N', RWORK, IMODE,
$ COND, ANORM, KL, KU, 'N', A, LDA, WORK,
$ IINFO )
*
ELSE IF( ITYPE.EQ.9 ) THEN
*
* Nonhermitian, random entries
*
CALL ZLATMR( M, N, 'S', ISEED, 'N', WORK, 6, ONE,
$ CONE, 'T', 'N', WORK( N+1 ), 1, ONE,
$ WORK( 2*N+1 ), 1, ONE, 'N', IDUMMA, KL,
$ KU, ZERO, ANORM, 'N', A, LDA, IDUMMA,
$ IINFO )
*
ELSE
*
IINFO = 1
END IF
*
* Generate Right-Hand Side
*
CALL ZLATMR( M, NRHS, 'S', ISEED, 'N', WORK, 6, ONE,
$ CONE, 'T', 'N', WORK( M+1 ), 1, ONE,
$ WORK( 2*M+1 ), 1, ONE, 'N', IDUMMA, M, NRHS,
$ ZERO, ONE, 'NO', C, LDC, IDUMMA, IINFO )
*
IF( IINFO.NE.0 ) THEN
WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N,
$ JTYPE, IOLDSD
INFO = ABS( IINFO )
RETURN
END IF
*
90 CONTINUE
*
* Copy A to band storage.
*
DO 110 J = 1, N
DO 100 I = MAX( 1, J-KU ), MIN( M, J+KL )
AB( KU+1+I-J, J ) = A( I, J )
100 CONTINUE
110 CONTINUE
*
* Copy C
*
CALL ZLACPY( 'Full', M, NRHS, C, LDC, CC, LDC )
*
* Call ZGBBRD to compute B, Q and P, and to update C.
*
CALL ZGBBRD( 'B', M, N, NRHS, KL, KU, AB, LDAB, BD, BE,
$ Q, LDQ, P, LDP, CC, LDC, WORK, RWORK,
$ IINFO )
*
IF( IINFO.NE.0 ) THEN
WRITE( NOUNIT, FMT = 9999 )'ZGBBRD', IINFO, N, JTYPE,
$ IOLDSD
INFO = ABS( IINFO )
IF( IINFO.LT.0 ) THEN
RETURN
ELSE
RESULT( 1 ) = ULPINV
GO TO 120
END IF
END IF
*
* Test 1: Check the decomposition A := Q * B * P'
* 2: Check the orthogonality of Q
* 3: Check the orthogonality of P
* 4: Check the computation of Q' * C
*
CALL ZBDT01( M, N, -1, A, LDA, Q, LDQ, BD, BE, P, LDP,
$ WORK, RWORK, RESULT( 1 ) )
CALL ZUNT01( 'Columns', M, M, Q, LDQ, WORK, LWORK, RWORK,
$ RESULT( 2 ) )
CALL ZUNT01( 'Rows', N, N, P, LDP, WORK, LWORK, RWORK,
$ RESULT( 3 ) )
CALL ZBDT02( M, NRHS, C, LDC, CC, LDC, Q, LDQ, WORK,
$ RWORK, RESULT( 4 ) )
*
* End of Loop -- Check for RESULT(j) > THRESH
*
NTEST = 4
120 CONTINUE
NTESTT = NTESTT + NTEST
*
* Print out tests which fail.
*
DO 130 JR = 1, NTEST
IF( RESULT( JR ).GE.THRESH ) THEN
IF( NERRS.EQ.0 )
$ CALL DLAHD2( NOUNIT, 'ZBB' )
NERRS = NERRS + 1
WRITE( NOUNIT, FMT = 9998 )M, N, K, IOLDSD, JTYPE,
$ JR, RESULT( JR )
END IF
130 CONTINUE
*
140 CONTINUE
150 CONTINUE
160 CONTINUE
*
* Summary
*
CALL DLASUM( 'ZBB', NOUNIT, NERRS, NTESTT )
RETURN
*
9999 FORMAT( ' ZCHKBB: ', A, ' returned INFO=', I5, '.', / 9X, 'M=',
$ I5, ' N=', I5, ' K=', I5, ', JTYPE=', I5, ', ISEED=(',
$ 3( I5, ',' ), I5, ')' )
9998 FORMAT( ' M =', I4, ' N=', I4, ', K=', I3, ', seed=',
$ 4( I4, ',' ), ' type ', I2, ', test(', I2, ')=', G10.3 )
*
* End of ZCHKBB
*
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?