PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
sposvx.f
Go to the documentation of this file.
1  SUBROUTINE sposvx( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, EQUED,
2  $ s, b, ldb, x, ldx, rcond, ferr, berr, work,
3  $ iwork, info )
4 *
5  include 'plasmaf.h'
6 *
7 * -- LAPACK driver routine (version 3.2) --
8 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
9 * November 2006
10 *
11 * .. Scalar Arguments ..
12  CHARACTER equed, fact, uplo
13  INTEGER info, lda, ldaf, ldb, ldx, n, nrhs
14  INTEGER plasma_uplo
15  REAL rcond
16 * ..
17 * .. Array Arguments ..
18  INTEGER iwork( * )
19  REAL a( lda, * ), af( ldaf, * ), b( ldb, * ),
20  $ berr( * ), ferr( * ), s( * ), work( * ),
21  $ x( ldx, * )
22 * ..
23 *
24 * Purpose
25 * =======
26 *
27 * SPOSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to
28 * compute the solution to a real system of linear equations
29 * A * X = B,
30 * where A is an N-by-N symmetric positive definite matrix and X and B
31 * are N-by-NRHS matrices.
32 *
33 * Error bounds on the solution and a condition estimate are also
34 * provided.
35 *
36 * Description
37 * ===========
38 *
39 * The following steps are performed:
40 *
41 * 1. If FACT = 'E', real scaling factors are computed to equilibrate
42 * the system:
43 * diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B
44 * Whether or not the system will be equilibrated depends on the
45 * scaling of the matrix A, but if equilibration is used, A is
46 * overwritten by diag(S)*A*diag(S) and B by diag(S)*B.
47 *
48 * 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to
49 * factor the matrix A (after equilibration if FACT = 'E') as
50 * A = U**T* U, if UPLO = 'U', or
51 * A = L * L**T, if UPLO = 'L',
52 * where U is an upper triangular matrix and L is a lower triangular
53 * matrix.
54 *
55 * 3. If the leading i-by-i principal minor is not positive definite,
56 * then the routine returns with INFO = i. Otherwise, the factored
57 * form of A is used to estimate the condition number of the matrix
58 * A. If the reciprocal of the condition number is less than machine
59 * precision, INFO = N+1 is returned as a warning, but the routine
60 * still goes on to solve for X and compute error bounds as
61 * described below.
62 *
63 * 4. The system of equations is solved for X using the factored form
64 * of A.
65 *
66 * 5. Iterative refinement is applied to improve the computed solution
67 * matrix and calculate error bounds and backward error estimates
68 * for it.
69 *
70 * 6. If equilibration was used, the matrix X is premultiplied by
71 * diag(S) so that it solves the original system before
72 * equilibration.
73 *
74 * Arguments
75 * =========
76 *
77 * FACT (input) CHARACTER*1
78 * Specifies whether or not the factored form of the matrix A is
79 * supplied on entry, and if not, whether the matrix A should be
80 * equilibrated before it is factored.
81 * = 'F': On entry, AF contains the factored form of A.
82 * If EQUED = 'Y', the matrix A has been equilibrated
83 * with scaling factors given by S. A and AF will not
84 * be modified.
85 * = 'N': The matrix A will be copied to AF and factored.
86 * = 'E': The matrix A will be equilibrated if necessary, then
87 * copied to AF and factored.
88 *
89 * UPLO (input) CHARACTER*1
90 * = 'U': Upper triangle of A is stored;
91 * = 'L': Lower triangle of A is stored.
92 *
93 * N (input) INTEGER
94 * The number of linear equations, i.e., the order of the
95 * matrix A. N >= 0.
96 *
97 * NRHS (input) INTEGER
98 * The number of right hand sides, i.e., the number of columns
99 * of the matrices B and X. NRHS >= 0.
100 *
101 * A (input/output) REAL array, dimension (LDA,N)
102 * On entry, the symmetric matrix A, except if FACT = 'F' and
103 * EQUED = 'Y', then A must contain the equilibrated matrix
104 * diag(S)*A*diag(S). If UPLO = 'U', the leading
105 * N-by-N upper triangular part of A contains the upper
106 * triangular part of the matrix A, and the strictly lower
107 * triangular part of A is not referenced. If UPLO = 'L', the
108 * leading N-by-N lower triangular part of A contains the lower
109 * triangular part of the matrix A, and the strictly upper
110 * triangular part of A is not referenced. A is not modified if
111 * FACT = 'F' or 'N', or if FACT = 'E' and EQUED = 'N' on exit.
112 *
113 * On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by
114 * diag(S)*A*diag(S).
115 *
116 * LDA (input) INTEGER
117 * The leading dimension of the array A. LDA >= max(1,N).
118 *
119 * AF (input or output) REAL array, dimension (LDAF,N)
120 * If FACT = 'F', then AF is an input argument and on entry
121 * contains the triangular factor U or L from the Cholesky
122 * factorization A = U**T*U or A = L*L**T, in the same storage
123 * format as A. If EQUED .ne. 'N', then AF is the factored form
124 * of the equilibrated matrix diag(S)*A*diag(S).
125 *
126 * If FACT = 'N', then AF is an output argument and on exit
127 * returns the triangular factor U or L from the Cholesky
128 * factorization A = U**T*U or A = L*L**T of the original
129 * matrix A.
130 *
131 * If FACT = 'E', then AF is an output argument and on exit
132 * returns the triangular factor U or L from the Cholesky
133 * factorization A = U**T*U or A = L*L**T of the equilibrated
134 * matrix A (see the description of A for the form of the
135 * equilibrated matrix).
136 *
137 * LDAF (input) INTEGER
138 * The leading dimension of the array AF. LDAF >= max(1,N).
139 *
140 * EQUED (input or output) CHARACTER*1
141 * Specifies the form of equilibration that was done.
142 * = 'N': No equilibration (always true if FACT = 'N').
143 * = 'Y': Equilibration was done, i.e., A has been replaced by
144 * diag(S) * A * diag(S).
145 * EQUED is an input argument if FACT = 'F'; otherwise, it is an
146 * output argument.
147 *
148 * S (input or output) REAL array, dimension (N)
149 * The scale factors for A; not accessed if EQUED = 'N'. S is
150 * an input argument if FACT = 'F'; otherwise, S is an output
151 * argument. If FACT = 'F' and EQUED = 'Y', each element of S
152 * must be positive.
153 *
154 * B (input/output) REAL array, dimension (LDB,NRHS)
155 * On entry, the N-by-NRHS right hand side matrix B.
156 * On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',
157 * B is overwritten by diag(S) * B.
158 *
159 * LDB (input) INTEGER
160 * The leading dimension of the array B. LDB >= max(1,N).
161 *
162 * X (output) REAL array, dimension (LDX,NRHS)
163 * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to
164 * the original system of equations. Note that if EQUED = 'Y',
165 * A and B are modified on exit, and the solution to the
166 * equilibrated system is inv(diag(S))*X.
167 *
168 * LDX (input) INTEGER
169 * The leading dimension of the array X. LDX >= max(1,N).
170 *
171 * RCOND (output) REAL
172 * The estimate of the reciprocal condition number of the matrix
173 * A after equilibration (if done). If RCOND is less than the
174 * machine precision (in particular, if RCOND = 0), the matrix
175 * is singular to working precision. This condition is
176 * indicated by a return code of INFO > 0.
177 *
178 * FERR (output) REAL array, dimension (NRHS)
179 * The estimated forward error bound for each solution vector
180 * X(j) (the j-th column of the solution matrix X).
181 * If XTRUE is the true solution corresponding to X(j), FERR(j)
182 * is an estimated upper bound for the magnitude of the largest
183 * element in (X(j) - XTRUE) divided by the magnitude of the
184 * largest element in X(j). The estimate is as reliable as
185 * the estimate for RCOND, and is almost always a slight
186 * overestimate of the true error.
187 *
188 * BERR (output) REAL array, dimension (NRHS)
189 * The componentwise relative backward error of each solution
190 * vector X(j) (i.e., the smallest relative change in
191 * any element of A or B that makes X(j) an exact solution).
192 *
193 * WORK (workspace) REAL array, dimension (3*N)
194 *
195 * IWORK (workspace) INTEGER array, dimension (N)
196 *
197 * INFO (output) INTEGER
198 * = 0: successful exit
199 * < 0: if INFO = -i, the i-th argument had an illegal value
200 * > 0: if INFO = i, and i is
201 * <= N: the leading minor of order i of A is
202 * not positive definite, so the factorization
203 * could not be completed, and the solution has not
204 * been computed. RCOND = 0 is returned.
205 * = N+1: U is nonsingular, but RCOND is less than machine
206 * precision, meaning that the matrix is singular
207 * to working precision. Nevertheless, the
208 * solution and error bounds are computed because
209 * there are a number of situations where the
210 * computed solution can be more accurate than the
211 * value of RCOND would suggest.
212 *
213 * =====================================================================
214 *
215 * .. Parameters ..
216  REAL zero, one
217  parameter( zero = 0.0e+0, one = 1.0e+0 )
218 * ..
219 * .. Local Scalars ..
220  LOGICAL equil, nofact, rcequ
221  INTEGER i, infequ, j
222  REAL amax, anorm, bignum, scond, smax, smin, smlnum
223 * ..
224 * .. External Functions ..
225  LOGICAL lsame
226  REAL slamch, slansy
227  EXTERNAL lsame, slamch, slansy
228 * ..
229 * .. External Subroutines ..
230  EXTERNAL slacpy, slaqsy, spocon, spoequ, sporfs, spotrf,
231  $ spotrs, xerbla
232 * ..
233 * .. Intrinsic Functions ..
234  INTRINSIC max, min
235 * ..
236 * .. Executable Statements ..
237 *
238  info = 0
239  nofact = lsame( fact, 'N' )
240  equil = lsame( fact, 'E' )
241  IF( nofact .OR. equil ) THEN
242  equed = 'N'
243  rcequ = .false.
244  ELSE
245  rcequ = lsame( equed, 'Y' )
246  smlnum = slamch( 'Safe minimum' )
247  bignum = one / smlnum
248  END IF
249 *
250 * Test the input parameters.
251 *
252  IF( .NOT.nofact .AND. .NOT.equil .AND. .NOT.lsame( fact, 'F' ) )
253  $ THEN
254  info = -1
255  ELSE IF( .NOT.lsame( uplo, 'U' ) .AND. .NOT.lsame( uplo, 'L' ) )
256  $ THEN
257  info = -2
258  ELSE IF( n.LT.0 ) THEN
259  info = -3
260  ELSE IF( nrhs.LT.0 ) THEN
261  info = -4
262  ELSE IF( lda.LT.max( 1, n ) ) THEN
263  info = -6
264  ELSE IF( ldaf.LT.max( 1, n ) ) THEN
265  info = -8
266  ELSE IF( lsame( fact, 'F' ) .AND. .NOT.
267  $ ( rcequ .OR. lsame( equed, 'N' ) ) ) THEN
268  info = -9
269  ELSE
270  IF( rcequ ) THEN
271  smin = bignum
272  smax = zero
273  DO 10 j = 1, n
274  smin = min( smin, s( j ) )
275  smax = max( smax, s( j ) )
276  10 continue
277  IF( smin.LE.zero ) THEN
278  info = -10
279  ELSE IF( n.GT.0 ) THEN
280  scond = max( smin, smlnum ) / min( smax, bignum )
281  ELSE
282  scond = one
283  END IF
284  END IF
285  IF( info.EQ.0 ) THEN
286  IF( ldb.LT.max( 1, n ) ) THEN
287  info = -12
288  ELSE IF( ldx.LT.max( 1, n ) ) THEN
289  info = -14
290  END IF
291  END IF
292  END IF
293 *
294  IF( info.NE.0 ) THEN
295  CALL xerbla( 'SPOSVX', -info )
296  return
297  END IF
298 *
299  IF( lsame( uplo, 'U' ) ) THEN
300  plasma_uplo = plasmaupper
301  ELSE
302  plasma_uplo = plasmalower
303  ENDIF
304 *
305  IF( equil ) THEN
306 *
307 * Compute row and column scalings to equilibrate the matrix A.
308 *
309  CALL spoequ( n, a, lda, s, scond, amax, infequ )
310  IF( infequ.EQ.0 ) THEN
311 *
312 * Equilibrate the matrix.
313 *
314  CALL slaqsy( uplo, n, a, lda, s, scond, amax, equed )
315  rcequ = lsame( equed, 'Y' )
316  END IF
317  END IF
318 *
319 * Scale the right hand side.
320 *
321  IF( rcequ ) THEN
322  DO 30 j = 1, nrhs
323  DO 20 i = 1, n
324  b( i, j ) = s( i )*b( i, j )
325  20 continue
326  30 continue
327  END IF
328 *
329  IF( nofact .OR. equil ) THEN
330 *
331 * Compute the Cholesky factorization A = U'*U or A = L*L'.
332 *
333  CALL slacpy( uplo, n, n, a, lda, af, ldaf )
334  CALL plasma_spotrf( plasma_uplo, n, af, ldaf, info )
335 *
336 * Return if INFO is non-zero.
337 *
338  IF( info.GT.0 )THEN
339  rcond = zero
340  return
341  END IF
342  END IF
343 *
344 * Compute the norm of the matrix A.
345 *
346  anorm = slansy( '1', uplo, n, a, lda, work )
347 *
348 * Compute the reciprocal of the condition number of A.
349 *
350  CALL spocon( uplo, n, af, ldaf, anorm, rcond, work, iwork, info )
351 *
352 * Compute the solution matrix X.
353 *
354  CALL slacpy( 'Full', n, nrhs, b, ldb, x, ldx )
355  CALL plasma_spotrs( plasma_uplo, n, nrhs, af, ldaf, x, ldx, info )
356 *
357 * Use iterative refinement to improve the computed solution and
358 * compute error bounds and backward error estimates for it.
359 *
360  CALL sporfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x, ldx,
361  $ ferr, berr, work, iwork, info )
362 *
363 * Transform the solution matrix X to a solution of the original
364 * system.
365 *
366  IF( rcequ ) THEN
367  DO 50 j = 1, nrhs
368  DO 40 i = 1, n
369  x( i, j ) = s( i )*x( i, j )
370  40 continue
371  50 continue
372  DO 60 j = 1, nrhs
373  ferr( j ) = ferr( j ) / scond
374  60 continue
375  END IF
376 *
377 * Set INFO = N+1 if the matrix is singular to working precision.
378 *
379  IF( rcond.LT.slamch( 'Epsilon' ) )
380  $ info = n + 1
381 *
382  return
383 *
384 * End of SPOSVX
385 *
386  END