sdrvgb.f
来自「famous linear algebra library (LAPACK) p」· F 代码 · 共 737 行 · 第 1/3 页
F
737 行
* Skip types 2, 3, or 4 if the matrix is too small.
*
ZEROT = IMAT.GE.2 .AND. IMAT.LE.4
IF( ZEROT .AND. N.LT.IMAT-1 )
$ GO TO 120
*
* Set up parameters with SLATB4 and generate a
* test matrix with SLATMS.
*
CALL SLATB4( PATH, IMAT, N, N, TYPE, KL, KU, ANORM,
$ MODE, CNDNUM, DIST )
RCONDC = ONE / CNDNUM
*
SRNAMT = 'SLATMS'
CALL SLATMS( N, N, DIST, ISEED, TYPE, RWORK, MODE,
$ CNDNUM, ANORM, KL, KU, 'Z', A, LDA, WORK,
$ INFO )
*
* Check the error code from SLATMS.
*
IF( INFO.NE.0 ) THEN
CALL ALAERH( PATH, 'SLATMS', INFO, 0, ' ', N, N,
$ KL, KU, -1, IMAT, NFAIL, NERRS, NOUT )
GO TO 120
END IF
*
* For types 2, 3, and 4, zero one or more columns of
* the matrix to test that INFO is returned correctly.
*
IZERO = 0
IF( ZEROT ) THEN
IF( IMAT.EQ.2 ) THEN
IZERO = 1
ELSE IF( IMAT.EQ.3 ) THEN
IZERO = N
ELSE
IZERO = N / 2 + 1
END IF
IOFF = ( IZERO-1 )*LDA
IF( IMAT.LT.4 ) THEN
I1 = MAX( 1, KU+2-IZERO )
I2 = MIN( KL+KU+1, KU+1+( N-IZERO ) )
DO 20 I = I1, I2
A( IOFF+I ) = ZERO
20 CONTINUE
ELSE
DO 40 J = IZERO, N
DO 30 I = MAX( 1, KU+2-J ),
$ MIN( KL+KU+1, KU+1+( N-J ) )
A( IOFF+I ) = ZERO
30 CONTINUE
IOFF = IOFF + LDA
40 CONTINUE
END IF
END IF
*
* Save a copy of the matrix A in ASAV.
*
CALL SLACPY( 'Full', KL+KU+1, N, A, LDA, ASAV, LDA )
*
DO 110 IEQUED = 1, 4
EQUED = EQUEDS( IEQUED )
IF( IEQUED.EQ.1 ) THEN
NFACT = 3
ELSE
NFACT = 1
END IF
*
DO 100 IFACT = 1, NFACT
FACT = FACTS( IFACT )
PREFAC = LSAME( FACT, 'F' )
NOFACT = LSAME( FACT, 'N' )
EQUIL = LSAME( FACT, 'E' )
*
IF( ZEROT ) THEN
IF( PREFAC )
$ GO TO 100
RCONDO = ZERO
RCONDI = ZERO
*
ELSE IF( .NOT.NOFACT ) THEN
*
* Compute the condition number for comparison
* with the value returned by SGESVX (FACT =
* 'N' reuses the condition number from the
* previous iteration with FACT = 'F').
*
CALL SLACPY( 'Full', KL+KU+1, N, ASAV, LDA,
$ AFB( KL+1 ), LDAFB )
IF( EQUIL .OR. IEQUED.GT.1 ) THEN
*
* Compute row and column scale factors to
* equilibrate the matrix A.
*
CALL SGBEQU( N, N, KL, KU, AFB( KL+1 ),
$ LDAFB, S, S( N+1 ), ROWCND,
$ COLCND, AMAX, INFO )
IF( INFO.EQ.0 .AND. N.GT.0 ) THEN
IF( LSAME( EQUED, 'R' ) ) THEN
ROWCND = ZERO
COLCND = ONE
ELSE IF( LSAME( EQUED, 'C' ) ) THEN
ROWCND = ONE
COLCND = ZERO
ELSE IF( LSAME( EQUED, 'B' ) ) THEN
ROWCND = ZERO
COLCND = ZERO
END IF
*
* Equilibrate the matrix.
*
CALL SLAQGB( N, N, KL, KU, AFB( KL+1 ),
$ LDAFB, S, S( N+1 ),
$ ROWCND, COLCND, AMAX,
$ EQUED )
END IF
END IF
*
* Save the condition number of the
* non-equilibrated system for use in SGET04.
*
IF( EQUIL ) THEN
ROLDO = RCONDO
ROLDI = RCONDI
END IF
*
* Compute the 1-norm and infinity-norm of A.
*
ANORMO = SLANGB( '1', N, KL, KU, AFB( KL+1 ),
$ LDAFB, RWORK )
ANORMI = SLANGB( 'I', N, KL, KU, AFB( KL+1 ),
$ LDAFB, RWORK )
*
* Factor the matrix A.
*
CALL SGBTRF( N, N, KL, KU, AFB, LDAFB, IWORK,
$ INFO )
*
* Form the inverse of A.
*
CALL SLASET( 'Full', N, N, ZERO, ONE, WORK,
$ LDB )
SRNAMT = 'SGBTRS'
CALL SGBTRS( 'No transpose', N, KL, KU, N,
$ AFB, LDAFB, IWORK, WORK, LDB,
$ INFO )
*
* Compute the 1-norm condition number of A.
*
AINVNM = SLANGE( '1', N, N, WORK, LDB,
$ RWORK )
IF( ANORMO.LE.ZERO .OR. AINVNM.LE.ZERO ) THEN
RCONDO = ONE
ELSE
RCONDO = ( ONE / ANORMO ) / AINVNM
END IF
*
* Compute the infinity-norm condition number
* of A.
*
AINVNM = SLANGE( 'I', N, N, WORK, LDB,
$ RWORK )
IF( ANORMI.LE.ZERO .OR. AINVNM.LE.ZERO ) THEN
RCONDI = ONE
ELSE
RCONDI = ( ONE / ANORMI ) / AINVNM
END IF
END IF
*
DO 90 ITRAN = 1, NTRAN
*
* Do for each value of TRANS.
*
TRANS = TRANSS( ITRAN )
IF( ITRAN.EQ.1 ) THEN
RCONDC = RCONDO
ELSE
RCONDC = RCONDI
END IF
*
* Restore the matrix A.
*
CALL SLACPY( 'Full', KL+KU+1, N, ASAV, LDA,
$ A, LDA )
*
* Form an exact solution and set the right hand
* side.
*
SRNAMT = 'SLARHS'
CALL SLARHS( PATH, XTYPE, 'Full', TRANS, N,
$ N, KL, KU, NRHS, A, LDA, XACT,
$ LDB, B, LDB, ISEED, INFO )
XTYPE = 'C'
CALL SLACPY( 'Full', N, NRHS, B, LDB, BSAV,
$ LDB )
*
IF( NOFACT .AND. ITRAN.EQ.1 ) THEN
*
* --- Test SGBSV ---
*
* Compute the LU factorization of the matrix
* and solve the system.
*
CALL SLACPY( 'Full', KL+KU+1, N, A, LDA,
$ AFB( KL+1 ), LDAFB )
CALL SLACPY( 'Full', N, NRHS, B, LDB, X,
$ LDB )
*
SRNAMT = 'SGBSV '
CALL SGBSV( N, KL, KU, NRHS, AFB, LDAFB,
$ IWORK, X, LDB, INFO )
*
* Check error code from SGBSV .
*
IF( INFO.NE.IZERO )
$ CALL ALAERH( PATH, 'SGBSV ', INFO,
$ IZERO, ' ', N, N, KL, KU,
$ NRHS, IMAT, NFAIL, NERRS,
$ NOUT )
*
* Reconstruct matrix from factors and
* compute residual.
*
CALL SGBT01( N, N, KL, KU, A, LDA, AFB,
$ LDAFB, IWORK, WORK,
$ RESULT( 1 ) )
NT = 1
IF( IZERO.EQ.0 ) THEN
*
* Compute residual of the computed
* solution.
*
CALL SLACPY( 'Full', N, NRHS, B, LDB,
$ WORK, LDB )
CALL SGBT02( 'No transpose', N, N, KL,
$ KU, NRHS, A, LDA, X, LDB,
$ WORK, LDB, RESULT( 2 ) )
*
* Check solution from generated exact
* solution.
*
CALL SGET04( N, NRHS, X, LDB, XACT,
$ LDB, RCONDC, RESULT( 3 ) )
NT = 3
END IF
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?