File:  [local] / rpl / lapack / lapack / zcposv.f
Revision 1.3: download - view: text, annotated - select for diffs - revision graph
Fri Aug 13 21:04:01 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_0_19, rpl-4_0_18, HEAD
Patches pour OS/2

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

CVSweb interface <joel.bertrand@systella.fr>