Annotation of rpl/lapack/lapack/dsgesv.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DSGESV( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK,
! 2: + SWORK, ITER, INFO )
! 3: *
! 4: * -- LAPACK PROTOTYPE driver routine (version 3.2) --
! 5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 7: * February 2007
! 8: *
! 9: * ..
! 10: * .. Scalar Arguments ..
! 11: INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
! 12: * ..
! 13: * .. Array Arguments ..
! 14: INTEGER IPIV( * )
! 15: REAL SWORK( * )
! 16: DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( N, * ),
! 17: + X( LDX, * )
! 18: * ..
! 19: *
! 20: * Purpose
! 21: * =======
! 22: *
! 23: * DSGESV computes the solution to a real system of linear equations
! 24: * A * X = B,
! 25: * where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
! 26: *
! 27: * DSGESV first attempts to factorize the matrix in SINGLE PRECISION
! 28: * and use this factorization within an iterative refinement procedure
! 29: * to produce a solution with DOUBLE PRECISION normwise backward error
! 30: * quality (see below). If the approach fails the method switches to a
! 31: * DOUBLE PRECISION factorization and solve.
! 32: *
! 33: * The iterative refinement is not going to be a winning strategy if
! 34: * the ratio SINGLE PRECISION performance over DOUBLE PRECISION
! 35: * performance is too small. A reasonable strategy should take the
! 36: * number of right-hand sides and the size of the matrix into account.
! 37: * This might be done with a call to ILAENV in the future. Up to now, we
! 38: * always try iterative refinement.
! 39: *
! 40: * The iterative refinement process is stopped if
! 41: * ITER > ITERMAX
! 42: * or for all the RHS we have:
! 43: * RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX
! 44: * where
! 45: * o ITER is the number of the current iteration in the iterative
! 46: * refinement process
! 47: * o RNRM is the infinity-norm of the residual
! 48: * o XNRM is the infinity-norm of the solution
! 49: * o ANRM is the infinity-operator-norm of the matrix A
! 50: * o EPS is the machine epsilon returned by DLAMCH('Epsilon')
! 51: * The value ITERMAX and BWDMAX are fixed to 30 and 1.0D+00
! 52: * respectively.
! 53: *
! 54: * Arguments
! 55: * =========
! 56: *
! 57: * N (input) INTEGER
! 58: * The number of linear equations, i.e., the order of the
! 59: * matrix A. N >= 0.
! 60: *
! 61: * NRHS (input) INTEGER
! 62: * The number of right hand sides, i.e., the number of columns
! 63: * of the matrix B. NRHS >= 0.
! 64: *
! 65: * A (input or input/ouptut) DOUBLE PRECISION array,
! 66: * dimension (LDA,N)
! 67: * On entry, the N-by-N coefficient matrix A.
! 68: * On exit, if iterative refinement has been successfully used
! 69: * (INFO.EQ.0 and ITER.GE.0, see description below), then A is
! 70: * unchanged, if double precision factorization has been used
! 71: * (INFO.EQ.0 and ITER.LT.0, see description below), then the
! 72: * array A contains the factors L and U from the factorization
! 73: * A = P*L*U; the unit diagonal elements of L are not stored.
! 74: *
! 75: * LDA (input) INTEGER
! 76: * The leading dimension of the array A. LDA >= max(1,N).
! 77: *
! 78: * IPIV (output) INTEGER array, dimension (N)
! 79: * The pivot indices that define the permutation matrix P;
! 80: * row i of the matrix was interchanged with row IPIV(i).
! 81: * Corresponds either to the single precision factorization
! 82: * (if INFO.EQ.0 and ITER.GE.0) or the double precision
! 83: * factorization (if INFO.EQ.0 and ITER.LT.0).
! 84: *
! 85: * B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)
! 86: * The N-by-NRHS right hand side matrix B.
! 87: *
! 88: * LDB (input) INTEGER
! 89: * The leading dimension of the array B. LDB >= max(1,N).
! 90: *
! 91: * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
! 92: * If INFO = 0, the N-by-NRHS solution matrix X.
! 93: *
! 94: * LDX (input) INTEGER
! 95: * The leading dimension of the array X. LDX >= max(1,N).
! 96: *
! 97: * WORK (workspace) DOUBLE PRECISION array, dimension (N*NRHS)
! 98: * This array is used to hold the residual vectors.
! 99: *
! 100: * SWORK (workspace) REAL array, dimension (N*(N+NRHS))
! 101: * This array is used to use the single precision matrix and the
! 102: * right-hand sides or solutions in single precision.
! 103: *
! 104: * ITER (output) INTEGER
! 105: * < 0: iterative refinement has failed, double precision
! 106: * factorization has been performed
! 107: * -1 : the routine fell back to full precision for
! 108: * implementation- or machine-specific reasons
! 109: * -2 : narrowing the precision induced an overflow,
! 110: * the routine fell back to full precision
! 111: * -3 : failure of SGETRF
! 112: * -31: stop the iterative refinement after the 30th
! 113: * iterations
! 114: * > 0: iterative refinement has been sucessfully used.
! 115: * Returns the number of iterations
! 116: *
! 117: * INFO (output) INTEGER
! 118: * = 0: successful exit
! 119: * < 0: if INFO = -i, the i-th argument had an illegal value
! 120: * > 0: if INFO = i, U(i,i) computed in DOUBLE PRECISION is
! 121: * exactly zero. The factorization has been completed,
! 122: * but the factor U is exactly singular, so the solution
! 123: * could not be computed.
! 124: *
! 125: * =========
! 126: *
! 127: * .. Parameters ..
! 128: LOGICAL DOITREF
! 129: PARAMETER ( DOITREF = .TRUE. )
! 130: *
! 131: INTEGER ITERMAX
! 132: PARAMETER ( ITERMAX = 30 )
! 133: *
! 134: DOUBLE PRECISION BWDMAX
! 135: PARAMETER ( BWDMAX = 1.0E+00 )
! 136: *
! 137: DOUBLE PRECISION NEGONE, ONE
! 138: PARAMETER ( NEGONE = -1.0D+0, ONE = 1.0D+0 )
! 139: *
! 140: * .. Local Scalars ..
! 141: INTEGER I, IITER, PTSA, PTSX
! 142: DOUBLE PRECISION ANRM, CTE, EPS, RNRM, XNRM
! 143: *
! 144: * .. External Subroutines ..
! 145: EXTERNAL DAXPY, DGEMM, DLACPY, DLAG2S, SLAG2D, SGETRF,
! 146: + SGETRS, XERBLA
! 147: * ..
! 148: * .. External Functions ..
! 149: INTEGER IDAMAX
! 150: DOUBLE PRECISION DLAMCH, DLANGE
! 151: EXTERNAL IDAMAX, DLAMCH, DLANGE
! 152: * ..
! 153: * .. Intrinsic Functions ..
! 154: INTRINSIC ABS, DBLE, MAX, SQRT
! 155: * ..
! 156: * .. Executable Statements ..
! 157: *
! 158: INFO = 0
! 159: ITER = 0
! 160: *
! 161: * Test the input parameters.
! 162: *
! 163: IF( N.LT.0 ) THEN
! 164: INFO = -1
! 165: ELSE IF( NRHS.LT.0 ) THEN
! 166: INFO = -2
! 167: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
! 168: INFO = -4
! 169: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
! 170: INFO = -7
! 171: ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
! 172: INFO = -9
! 173: END IF
! 174: IF( INFO.NE.0 ) THEN
! 175: CALL XERBLA( 'DSGESV', -INFO )
! 176: RETURN
! 177: END IF
! 178: *
! 179: * Quick return if (N.EQ.0).
! 180: *
! 181: IF( N.EQ.0 )
! 182: + RETURN
! 183: *
! 184: * Skip single precision iterative refinement if a priori slower
! 185: * than double precision factorization.
! 186: *
! 187: IF( .NOT.DOITREF ) THEN
! 188: ITER = -1
! 189: GO TO 40
! 190: END IF
! 191: *
! 192: * Compute some constants.
! 193: *
! 194: ANRM = DLANGE( 'I', N, N, A, LDA, WORK )
! 195: EPS = DLAMCH( 'Epsilon' )
! 196: CTE = ANRM*EPS*SQRT( DBLE( N ) )*BWDMAX
! 197: *
! 198: * Set the indices PTSA, PTSX for referencing SA and SX in SWORK.
! 199: *
! 200: PTSA = 1
! 201: PTSX = PTSA + N*N
! 202: *
! 203: * Convert B from double precision to single precision and store the
! 204: * result in SX.
! 205: *
! 206: CALL DLAG2S( N, NRHS, B, LDB, SWORK( PTSX ), N, INFO )
! 207: *
! 208: IF( INFO.NE.0 ) THEN
! 209: ITER = -2
! 210: GO TO 40
! 211: END IF
! 212: *
! 213: * Convert A from double precision to single precision and store the
! 214: * result in SA.
! 215: *
! 216: CALL DLAG2S( N, N, A, LDA, SWORK( PTSA ), N, INFO )
! 217: *
! 218: IF( INFO.NE.0 ) THEN
! 219: ITER = -2
! 220: GO TO 40
! 221: END IF
! 222: *
! 223: * Compute the LU factorization of SA.
! 224: *
! 225: CALL SGETRF( N, N, SWORK( PTSA ), N, IPIV, INFO )
! 226: *
! 227: IF( INFO.NE.0 ) THEN
! 228: ITER = -3
! 229: GO TO 40
! 230: END IF
! 231: *
! 232: * Solve the system SA*SX = SB.
! 233: *
! 234: CALL SGETRS( 'No transpose', N, NRHS, SWORK( PTSA ), N, IPIV,
! 235: + SWORK( PTSX ), N, INFO )
! 236: *
! 237: * Convert SX back to double precision
! 238: *
! 239: CALL SLAG2D( N, NRHS, SWORK( PTSX ), N, X, LDX, INFO )
! 240: *
! 241: * Compute R = B - AX (R is WORK).
! 242: *
! 243: CALL DLACPY( 'All', N, NRHS, B, LDB, WORK, N )
! 244: *
! 245: CALL DGEMM( 'No Transpose', 'No Transpose', N, NRHS, N, NEGONE, A,
! 246: + LDA, X, LDX, ONE, WORK, N )
! 247: *
! 248: * Check whether the NRHS normwise backward errors satisfy the
! 249: * stopping criterion. If yes, set ITER=0 and return.
! 250: *
! 251: DO I = 1, NRHS
! 252: XNRM = ABS( X( IDAMAX( N, X( 1, I ), 1 ), I ) )
! 253: RNRM = ABS( WORK( IDAMAX( N, WORK( 1, I ), 1 ), I ) )
! 254: IF( RNRM.GT.XNRM*CTE )
! 255: + GO TO 10
! 256: END DO
! 257: *
! 258: * If we are here, the NRHS normwise backward errors satisfy the
! 259: * stopping criterion. We are good to exit.
! 260: *
! 261: ITER = 0
! 262: RETURN
! 263: *
! 264: 10 CONTINUE
! 265: *
! 266: DO 30 IITER = 1, ITERMAX
! 267: *
! 268: * Convert R (in WORK) from double precision to single precision
! 269: * and store the result in SX.
! 270: *
! 271: CALL DLAG2S( N, NRHS, WORK, N, SWORK( PTSX ), N, INFO )
! 272: *
! 273: IF( INFO.NE.0 ) THEN
! 274: ITER = -2
! 275: GO TO 40
! 276: END IF
! 277: *
! 278: * Solve the system SA*SX = SR.
! 279: *
! 280: CALL SGETRS( 'No transpose', N, NRHS, SWORK( PTSA ), N, IPIV,
! 281: + SWORK( PTSX ), N, INFO )
! 282: *
! 283: * Convert SX back to double precision and update the current
! 284: * iterate.
! 285: *
! 286: CALL SLAG2D( N, NRHS, SWORK( PTSX ), N, WORK, N, INFO )
! 287: *
! 288: DO I = 1, NRHS
! 289: CALL DAXPY( N, ONE, WORK( 1, I ), 1, X( 1, I ), 1 )
! 290: END DO
! 291: *
! 292: * Compute R = B - AX (R is WORK).
! 293: *
! 294: CALL DLACPY( 'All', N, NRHS, B, LDB, WORK, N )
! 295: *
! 296: CALL DGEMM( 'No Transpose', 'No Transpose', N, NRHS, N, NEGONE,
! 297: + A, LDA, X, LDX, ONE, WORK, N )
! 298: *
! 299: * Check whether the NRHS normwise backward errors satisfy the
! 300: * stopping criterion. If yes, set ITER=IITER>0 and return.
! 301: *
! 302: DO I = 1, NRHS
! 303: XNRM = ABS( X( IDAMAX( N, X( 1, I ), 1 ), I ) )
! 304: RNRM = ABS( WORK( IDAMAX( N, WORK( 1, I ), 1 ), I ) )
! 305: IF( RNRM.GT.XNRM*CTE )
! 306: + GO TO 20
! 307: END DO
! 308: *
! 309: * If we are here, the NRHS normwise backward errors satisfy the
! 310: * stopping criterion, we are good to exit.
! 311: *
! 312: ITER = IITER
! 313: *
! 314: RETURN
! 315: *
! 316: 20 CONTINUE
! 317: *
! 318: 30 CONTINUE
! 319: *
! 320: * If we are at this place of the code, this is because we have
! 321: * performed ITER=ITERMAX iterations and never satisified the
! 322: * stopping criterion, set up the ITER flag accordingly and follow up
! 323: * on double precision routine.
! 324: *
! 325: ITER = -ITERMAX - 1
! 326: *
! 327: 40 CONTINUE
! 328: *
! 329: * Single-precision iterative refinement failed to converge to a
! 330: * satisfactory solution, so we resort to double precision.
! 331: *
! 332: CALL DGETRF( N, N, A, LDA, IPIV, INFO )
! 333: *
! 334: IF( INFO.NE.0 )
! 335: + RETURN
! 336: *
! 337: CALL DLACPY( 'All', N, NRHS, B, LDB, X, LDX )
! 338: CALL DGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, X, LDX,
! 339: + INFO )
! 340: *
! 341: RETURN
! 342: *
! 343: * End of DSGESV.
! 344: *
! 345: END
CVSweb interface <joel.bertrand@systella.fr>