1 *> \brief <b> ZCPOSV computes the solution to system of linear equations A * X = B for PO matrices</b>
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download ZCPOSV + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zcposv.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zcposv.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zcposv.f">
21 * SUBROUTINE ZCPOSV( UPLO, N, NRHS, A, LDA, B, LDB, X, LDX, WORK,
22 * SWORK, RWORK, ITER, INFO )
24 * .. Scalar Arguments ..
26 * INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
28 * .. Array Arguments ..
29 * DOUBLE PRECISION RWORK( * )
31 * COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( N, * ),
41 *> ZCPOSV computes the solution to a complex system of linear equations
43 *> where A is an N-by-N Hermitian positive definite matrix and X and B
44 *> are N-by-NRHS matrices.
46 *> ZCPOSV first attempts to factorize the matrix in COMPLEX and use this
47 *> factorization within an iterative refinement procedure to produce a
48 *> solution with COMPLEX*16 normwise backward error quality (see below).
49 *> If the approach fails the method switches to a COMPLEX*16
50 *> factorization and solve.
52 *> The iterative refinement is not going to be a winning strategy if
53 *> the ratio COMPLEX performance over COMPLEX*16 performance is too
54 *> small. A reasonable strategy should take the number of right-hand
55 *> sides and the size of the matrix into account. This might be done
56 *> with a call to ILAENV in the future. Up to now, we always try
57 *> iterative refinement.
59 *> The iterative refinement process is stopped if
61 *> or for all the RHS we have:
62 *> RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX
64 *> o ITER is the number of the current iteration in the iterative
66 *> o RNRM is the infinity-norm of the residual
67 *> o XNRM is the infinity-norm of the solution
68 *> o ANRM is the infinity-operator-norm of the matrix A
69 *> o EPS is the machine epsilon returned by DLAMCH('Epsilon')
70 *> The value ITERMAX and BWDMAX are fixed to 30 and 1.0D+00
79 *> UPLO is CHARACTER*1
80 *> = 'U': Upper triangle of A is stored;
81 *> = 'L': Lower triangle of A is stored.
87 *> The number of linear equations, i.e., the order of the
94 *> The number of right hand sides, i.e., the number of columns
95 *> of the matrix B. NRHS >= 0.
100 *> A is COMPLEX*16 array,
102 *> On entry, the Hermitian matrix A. If UPLO = 'U', the leading
103 *> N-by-N upper triangular part of A contains the upper
104 *> triangular part of the matrix A, and the strictly lower
105 *> triangular part of A is not referenced. If UPLO = 'L', the
106 *> leading N-by-N lower triangular part of A contains the lower
107 *> triangular part of the matrix A, and the strictly upper
108 *> triangular part of A is not referenced.
110 *> Note that the imaginary parts of the diagonal
111 *> elements need not be set and are assumed to be zero.
113 *> On exit, if iterative refinement has been successfully used
114 *> (INFO.EQ.0 and ITER.GE.0, see description below), then A is
115 *> unchanged, if double precision factorization has been used
116 *> (INFO.EQ.0 and ITER.LT.0, see description below), then the
117 *> array A contains the factor U or L from the Cholesky
118 *> factorization A = U**H*U or A = L*L**H.
124 *> The leading dimension of the array A. LDA >= max(1,N).
129 *> B is COMPLEX*16 array, dimension (LDB,NRHS)
130 *> The N-by-NRHS right hand side matrix B.
136 *> The leading dimension of the array B. LDB >= max(1,N).
141 *> X is COMPLEX*16 array, dimension (LDX,NRHS)
142 *> If INFO = 0, the N-by-NRHS solution matrix X.
148 *> The leading dimension of the array X. LDX >= max(1,N).
153 *> WORK is COMPLEX*16 array, dimension (N*NRHS)
154 *> This array is used to hold the residual vectors.
159 *> SWORK is COMPLEX array, dimension (N*(N+NRHS))
160 *> This array is used to use the single precision matrix and the
161 *> right-hand sides or solutions in single precision.
166 *> RWORK is DOUBLE PRECISION array, dimension (N)
172 *> < 0: iterative refinement has failed, COMPLEX*16
173 *> factorization has been performed
174 *> -1 : the routine fell back to full precision for
175 *> implementation- or machine-specific reasons
176 *> -2 : narrowing the precision induced an overflow,
177 *> the routine fell back to full precision
178 *> -3 : failure of CPOTRF
179 *> -31: stop the iterative refinement after the 30th
181 *> > 0: iterative refinement has been successfully used.
182 *> Returns the number of iterations
188 *> = 0: successful exit
189 *> < 0: if INFO = -i, the i-th argument had an illegal value
190 *> > 0: if INFO = i, the leading minor of order i of
191 *> (COMPLEX*16) A is not positive definite, so the
192 *> factorization could not be completed, and the solution
193 *> has not been computed.
199 *> \author Univ. of Tennessee
200 *> \author Univ. of California Berkeley
201 *> \author Univ. of Colorado Denver
206 *> \ingroup complex16POsolve
208 * =====================================================================
209 SUBROUTINE ZCPOSV( UPLO, N, NRHS, A, LDA, B, LDB, X, LDX, WORK,
210 $ SWORK, RWORK, ITER, INFO )
212 * -- LAPACK driver routine (version 3.6.1) --
213 * -- LAPACK is a software package provided by Univ. of Tennessee, --
214 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
217 * .. Scalar Arguments ..
219 INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
221 * .. Array Arguments ..
222 DOUBLE PRECISION RWORK( * )
224 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( N, * ),
228 * =====================================================================
232 PARAMETER ( DOITREF = .TRUE. )
235 PARAMETER ( ITERMAX = 30 )
237 DOUBLE PRECISION BWDMAX
238 PARAMETER ( BWDMAX = 1.0E+00 )
240 COMPLEX*16 NEGONE, ONE
241 PARAMETER ( NEGONE = ( -1.0D+00, 0.0D+00 ),
242 $ ONE = ( 1.0D+00, 0.0D+00 ) )
244 * .. Local Scalars ..
245 INTEGER I, IITER, PTSA, PTSX
246 DOUBLE PRECISION ANRM, CTE, EPS, RNRM, XNRM
249 * .. External Subroutines ..
250 EXTERNAL ZAXPY, ZHEMM, ZLACPY, ZLAT2C, ZLAG2C, CLAG2Z,
251 $ CPOTRF, CPOTRS, XERBLA
253 * .. External Functions ..
255 DOUBLE PRECISION DLAMCH, ZLANHE
257 EXTERNAL IZAMAX, DLAMCH, ZLANHE, LSAME
259 * .. Intrinsic Functions ..
260 INTRINSIC ABS, DBLE, MAX, SQRT
261 * .. Statement Functions ..
262 DOUBLE PRECISION CABS1
264 * .. Statement Function definitions ..
265 CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
267 * .. Executable Statements ..
272 * Test the input parameters.
274 IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
276 ELSE IF( N.LT.0 ) THEN
278 ELSE IF( NRHS.LT.0 ) THEN
280 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
282 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
284 ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
288 CALL XERBLA( 'ZCPOSV', -INFO )
292 * Quick return if (N.EQ.0).
297 * Skip single precision iterative refinement if a priori slower
298 * than double precision factorization.
300 IF( .NOT.DOITREF ) THEN
305 * Compute some constants.
307 ANRM = ZLANHE( 'I', UPLO, N, A, LDA, RWORK )
308 EPS = DLAMCH( 'Epsilon' )
309 CTE = ANRM*EPS*SQRT( DBLE( N ) )*BWDMAX
311 * Set the indices PTSA, PTSX for referencing SA and SX in SWORK.
316 * Convert B from double precision to single precision and store the
319 CALL ZLAG2C( N, NRHS, B, LDB, SWORK( PTSX ), N, INFO )
326 * Convert A from double precision to single precision and store the
329 CALL ZLAT2C( UPLO, N, A, LDA, SWORK( PTSA ), N, INFO )
336 * Compute the Cholesky factorization of SA.
338 CALL CPOTRF( UPLO, N, SWORK( PTSA ), N, INFO )
345 * Solve the system SA*SX = SB.
347 CALL CPOTRS( UPLO, N, NRHS, SWORK( PTSA ), N, SWORK( PTSX ), N,
350 * Convert SX back to COMPLEX*16
352 CALL CLAG2Z( N, NRHS, SWORK( PTSX ), N, X, LDX, INFO )
354 * Compute R = B - AX (R is WORK).
356 CALL ZLACPY( 'All', N, NRHS, B, LDB, WORK, N )
358 CALL ZHEMM( 'Left', UPLO, N, NRHS, NEGONE, A, LDA, X, LDX, ONE,
361 * Check whether the NRHS normwise backward errors satisfy the
362 * stopping criterion. If yes, set ITER=0 and return.
365 XNRM = CABS1( X( IZAMAX( N, X( 1, I ), 1 ), I ) )
366 RNRM = CABS1( WORK( IZAMAX( N, WORK( 1, I ), 1 ), I ) )
367 IF( RNRM.GT.XNRM*CTE )
371 * If we are here, the NRHS normwise backward errors satisfy the
372 * stopping criterion. We are good to exit.
379 DO 30 IITER = 1, ITERMAX
381 * Convert R (in WORK) from double precision to single precision
382 * and store the result in SX.
384 CALL ZLAG2C( N, NRHS, WORK, N, SWORK( PTSX ), N, INFO )
391 * Solve the system SA*SX = SR.
393 CALL CPOTRS( UPLO, N, NRHS, SWORK( PTSA ), N, SWORK( PTSX ), N,
396 * Convert SX back to double precision and update the current
399 CALL CLAG2Z( N, NRHS, SWORK( PTSX ), N, WORK, N, INFO )
402 CALL ZAXPY( N, ONE, WORK( 1, I ), 1, X( 1, I ), 1 )
405 * Compute R = B - AX (R is WORK).
407 CALL ZLACPY( 'All', N, NRHS, B, LDB, WORK, N )
409 CALL ZHEMM( 'L', UPLO, N, NRHS, NEGONE, A, LDA, X, LDX, ONE,
412 * Check whether the NRHS normwise backward errors satisfy the
413 * stopping criterion. If yes, set ITER=IITER>0 and return.
416 XNRM = CABS1( X( IZAMAX( N, X( 1, I ), 1 ), I ) )
417 RNRM = CABS1( WORK( IZAMAX( N, WORK( 1, I ), 1 ), I ) )
418 IF( RNRM.GT.XNRM*CTE )
422 * If we are here, the NRHS normwise backward errors satisfy the
423 * stopping criterion, we are good to exit.
433 * If we are at this place of the code, this is because we have
434 * performed ITER=ITERMAX iterations and never satisified the
435 * stopping criterion, set up the ITER flag accordingly and follow
436 * up on double precision routine.
442 * Single-precision iterative refinement failed to converge to a
443 * satisfactory solution, so we resort to double precision.
445 CALL ZPOTRF( UPLO, N, A, LDA, INFO )
450 CALL ZLACPY( 'All', N, NRHS, B, LDB, X, LDX )
451 CALL ZPOTRS( UPLO, N, NRHS, A, LDA, X, LDX, INFO )