1 *> \brief <b> DSPOSV 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 DSPOSV + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsposv.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsposv.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsposv.f">
21 * SUBROUTINE DSPOSV( UPLO, N, NRHS, A, LDA, B, LDB, X, LDX, WORK,
24 * .. Scalar Arguments ..
26 * INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
28 * .. Array Arguments ..
30 * DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( N, * ),
40 *> DSPOSV computes the solution to a real system of linear equations
42 *> where A is an N-by-N symmetric positive definite matrix and X and B
43 *> are N-by-NRHS matrices.
45 *> DSPOSV first attempts to factorize the matrix in SINGLE PRECISION
46 *> and use this factorization within an iterative refinement procedure
47 *> to produce a solution with DOUBLE PRECISION normwise backward error
48 *> quality (see below). If the approach fails the method switches to a
49 *> DOUBLE PRECISION factorization and solve.
51 *> The iterative refinement is not going to be a winning strategy if
52 *> the ratio SINGLE PRECISION performance over DOUBLE PRECISION
53 *> performance is too small. A reasonable strategy should take the
54 *> number of right-hand sides and the size of the matrix into account.
55 *> This might be done with a call to ILAENV in the future. Up to now, we
56 *> always try iterative refinement.
58 *> The iterative refinement process is stopped if
60 *> or for all the RHS we have:
61 *> RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX
63 *> o ITER is the number of the current iteration in the iterative
65 *> o RNRM is the infinity-norm of the residual
66 *> o XNRM is the infinity-norm of the solution
67 *> o ANRM is the infinity-operator-norm of the matrix A
68 *> o EPS is the machine epsilon returned by DLAMCH('Epsilon')
69 *> The value ITERMAX and BWDMAX are fixed to 30 and 1.0D+00
78 *> UPLO is CHARACTER*1
79 *> = 'U': Upper triangle of A is stored;
80 *> = 'L': Lower triangle of A is stored.
86 *> The number of linear equations, i.e., the order of the
93 *> The number of right hand sides, i.e., the number of columns
94 *> of the matrix B. NRHS >= 0.
99 *> A is DOUBLE PRECISION array,
101 *> On entry, the symmetric matrix A. If UPLO = 'U', the leading
102 *> N-by-N upper triangular part of A contains the upper
103 *> triangular part of the matrix A, and the strictly lower
104 *> triangular part of A is not referenced. If UPLO = 'L', the
105 *> leading N-by-N lower triangular part of A contains the lower
106 *> triangular part of the matrix A, and the strictly upper
107 *> triangular part of A is not referenced.
108 *> On exit, if iterative refinement has been successfully used
109 *> (INFO.EQ.0 and ITER.GE.0, see description below), then A is
110 *> unchanged, if double precision factorization has been used
111 *> (INFO.EQ.0 and ITER.LT.0, see description below), then the
112 *> array A contains the factor U or L from the Cholesky
113 *> factorization A = U**T*U or A = L*L**T.
119 *> The leading dimension of the array A. LDA >= max(1,N).
124 *> B is DOUBLE PRECISION array, dimension (LDB,NRHS)
125 *> The N-by-NRHS right hand side matrix B.
131 *> The leading dimension of the array B. LDB >= max(1,N).
136 *> X is DOUBLE PRECISION array, dimension (LDX,NRHS)
137 *> If INFO = 0, the N-by-NRHS solution matrix X.
143 *> The leading dimension of the array X. LDX >= max(1,N).
148 *> WORK is DOUBLE PRECISION array, dimension (N,NRHS)
149 *> This array is used to hold the residual vectors.
154 *> SWORK is REAL array, dimension (N*(N+NRHS))
155 *> This array is used to use the single precision matrix and the
156 *> right-hand sides or solutions in single precision.
162 *> < 0: iterative refinement has failed, double precision
163 *> factorization has been performed
164 *> -1 : the routine fell back to full precision for
165 *> implementation- or machine-specific reasons
166 *> -2 : narrowing the precision induced an overflow,
167 *> the routine fell back to full precision
168 *> -3 : failure of SPOTRF
169 *> -31: stop the iterative refinement after the 30th
171 *> > 0: iterative refinement has been successfully used.
172 *> Returns the number of iterations
178 *> = 0: successful exit
179 *> < 0: if INFO = -i, the i-th argument had an illegal value
180 *> > 0: if INFO = i, the leading minor of order i of (DOUBLE
181 *> PRECISION) A is not positive definite, so the
182 *> factorization could not be completed, and the solution
183 *> has not been computed.
189 *> \author Univ. of Tennessee
190 *> \author Univ. of California Berkeley
191 *> \author Univ. of Colorado Denver
196 *> \ingroup doublePOsolve
198 * =====================================================================
199 SUBROUTINE DSPOSV( UPLO, N, NRHS, A, LDA, B, LDB, X, LDX, WORK,
200 $ SWORK, ITER, INFO )
202 * -- LAPACK driver routine (version 3.6.1) --
203 * -- LAPACK is a software package provided by Univ. of Tennessee, --
204 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
207 * .. Scalar Arguments ..
209 INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
211 * .. Array Arguments ..
213 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( N, * ),
217 * =====================================================================
221 PARAMETER ( DOITREF = .TRUE. )
224 PARAMETER ( ITERMAX = 30 )
226 DOUBLE PRECISION BWDMAX
227 PARAMETER ( BWDMAX = 1.0E+00 )
229 DOUBLE PRECISION NEGONE, ONE
230 PARAMETER ( NEGONE = -1.0D+0, ONE = 1.0D+0 )
232 * .. Local Scalars ..
233 INTEGER I, IITER, PTSA, PTSX
234 DOUBLE PRECISION ANRM, CTE, EPS, RNRM, XNRM
236 * .. External Subroutines ..
237 EXTERNAL DAXPY, DSYMM, DLACPY, DLAT2S, DLAG2S, SLAG2D,
238 $ SPOTRF, SPOTRS, XERBLA
240 * .. External Functions ..
242 DOUBLE PRECISION DLAMCH, DLANSY
244 EXTERNAL IDAMAX, DLAMCH, DLANSY, LSAME
246 * .. Intrinsic Functions ..
247 INTRINSIC ABS, DBLE, MAX, SQRT
249 * .. Executable Statements ..
254 * Test the input parameters.
256 IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
258 ELSE IF( N.LT.0 ) THEN
260 ELSE IF( NRHS.LT.0 ) THEN
262 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
264 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
266 ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
270 CALL XERBLA( 'DSPOSV', -INFO )
274 * Quick return if (N.EQ.0).
279 * Skip single precision iterative refinement if a priori slower
280 * than double precision factorization.
282 IF( .NOT.DOITREF ) THEN
287 * Compute some constants.
289 ANRM = DLANSY( 'I', UPLO, N, A, LDA, WORK )
290 EPS = DLAMCH( 'Epsilon' )
291 CTE = ANRM*EPS*SQRT( DBLE( N ) )*BWDMAX
293 * Set the indices PTSA, PTSX for referencing SA and SX in SWORK.
298 * Convert B from double precision to single precision and store the
301 CALL DLAG2S( N, NRHS, B, LDB, SWORK( PTSX ), N, INFO )
308 * Convert A from double precision to single precision and store the
311 CALL DLAT2S( UPLO, N, A, LDA, SWORK( PTSA ), N, INFO )
318 * Compute the Cholesky factorization of SA.
320 CALL SPOTRF( UPLO, N, SWORK( PTSA ), N, INFO )
327 * Solve the system SA*SX = SB.
329 CALL SPOTRS( UPLO, N, NRHS, SWORK( PTSA ), N, SWORK( PTSX ), N,
332 * Convert SX back to double precision
334 CALL SLAG2D( N, NRHS, SWORK( PTSX ), N, X, LDX, INFO )
336 * Compute R = B - AX (R is WORK).
338 CALL DLACPY( 'All', N, NRHS, B, LDB, WORK, N )
340 CALL DSYMM( 'Left', UPLO, N, NRHS, NEGONE, A, LDA, X, LDX, ONE,
343 * Check whether the NRHS normwise backward errors satisfy the
344 * stopping criterion. If yes, set ITER=0 and return.
347 XNRM = ABS( X( IDAMAX( N, X( 1, I ), 1 ), I ) )
348 RNRM = ABS( WORK( IDAMAX( N, WORK( 1, I ), 1 ), I ) )
349 IF( RNRM.GT.XNRM*CTE )
353 * If we are here, the NRHS normwise backward errors satisfy the
354 * stopping criterion. We are good to exit.
361 DO 30 IITER = 1, ITERMAX
363 * Convert R (in WORK) from double precision to single precision
364 * and store the result in SX.
366 CALL DLAG2S( N, NRHS, WORK, N, SWORK( PTSX ), N, INFO )
373 * Solve the system SA*SX = SR.
375 CALL SPOTRS( UPLO, N, NRHS, SWORK( PTSA ), N, SWORK( PTSX ), N,
378 * Convert SX back to double precision and update the current
381 CALL SLAG2D( N, NRHS, SWORK( PTSX ), N, WORK, N, INFO )
384 CALL DAXPY( N, ONE, WORK( 1, I ), 1, X( 1, I ), 1 )
387 * Compute R = B - AX (R is WORK).
389 CALL DLACPY( 'All', N, NRHS, B, LDB, WORK, N )
391 CALL DSYMM( 'L', UPLO, N, NRHS, NEGONE, A, LDA, X, LDX, ONE,
394 * Check whether the NRHS normwise backward errors satisfy the
395 * stopping criterion. If yes, set ITER=IITER>0 and return.
398 XNRM = ABS( X( IDAMAX( N, X( 1, I ), 1 ), I ) )
399 RNRM = ABS( WORK( IDAMAX( N, WORK( 1, I ), 1 ), I ) )
400 IF( RNRM.GT.XNRM*CTE )
404 * If we are here, the NRHS normwise backward errors satisfy the
405 * stopping criterion, we are good to exit.
415 * If we are at this place of the code, this is because we have
416 * performed ITER=ITERMAX iterations and never satisified the
417 * stopping criterion, set up the ITER flag accordingly and follow
418 * up on double precision routine.
424 * Single-precision iterative refinement failed to converge to a
425 * satisfactory solution, so we resort to double precision.
427 CALL DPOTRF( UPLO, N, A, LDA, INFO )
432 CALL DLACPY( 'All', N, NRHS, B, LDB, X, LDX )
433 CALL DPOTRS( UPLO, N, NRHS, A, LDA, X, LDX, INFO )