KTH framework for Nek5000 toolboxes; testing version  0.0.1
dsyrfs.f
Go to the documentation of this file.
1  SUBROUTINE dsyrfs( UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,
2  $ X, LDX, FERR, BERR, WORK, IWORK, INFO )
3 *
4 * -- LAPACK routine (version 3.0) --
5 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
6 * Courant Institute, Argonne National Lab, and Rice University
7 * September 30, 1994
8 *
9 * .. Scalar Arguments ..
10  CHARACTER UPLO
11  INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS
12 * ..
13 * .. Array Arguments ..
14  INTEGER IPIV( * ), IWORK( * )
15  DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),
16  $ berr( * ), ferr( * ), work( * ), x( ldx, * )
17 * ..
18 *
19 * Purpose
20 * =======
21 *
22 * DSYRFS improves the computed solution to a system of linear
23 * equations when the coefficient matrix is symmetric indefinite, and
24 * provides error bounds and backward error estimates for the solution.
25 *
26 * Arguments
27 * =========
28 *
29 * UPLO (input) CHARACTER*1
30 * = 'U': Upper triangle of A is stored;
31 * = 'L': Lower triangle of A is stored.
32 *
33 * N (input) INTEGER
34 * The order of the matrix A. N >= 0.
35 *
36 * NRHS (input) INTEGER
37 * The number of right hand sides, i.e., the number of columns
38 * of the matrices B and X. NRHS >= 0.
39 *
40 * A (input) DOUBLE PRECISION array, dimension (LDA,N)
41 * The symmetric matrix A. If UPLO = 'U', the leading N-by-N
42 * upper triangular part of A contains the upper triangular part
43 * of the matrix A, and the strictly lower triangular part of A
44 * is not referenced. If UPLO = 'L', the leading N-by-N lower
45 * triangular part of A contains the lower triangular part of
46 * the matrix A, and the strictly upper triangular part of A is
47 * not referenced.
48 *
49 * LDA (input) INTEGER
50 * The leading dimension of the array A. LDA >= max(1,N).
51 *
52 * AF (input) DOUBLE PRECISION array, dimension (LDAF,N)
53 * The factored form of the matrix A. AF contains the block
54 * diagonal matrix D and the multipliers used to obtain the
55 * factor U or L from the factorization A = U*D*U**T or
56 * A = L*D*L**T as computed by DSYTRF.
57 *
58 * LDAF (input) INTEGER
59 * The leading dimension of the array AF. LDAF >= max(1,N).
60 *
61 * IPIV (input) INTEGER array, dimension (N)
62 * Details of the interchanges and the block structure of D
63 * as determined by DSYTRF.
64 *
65 * B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)
66 * The right hand side matrix B.
67 *
68 * LDB (input) INTEGER
69 * The leading dimension of the array B. LDB >= max(1,N).
70 *
71 * X (input/output) DOUBLE PRECISION array, dimension (LDX,NRHS)
72 * On entry, the solution matrix X, as computed by DSYTRS.
73 * On exit, the improved solution matrix X.
74 *
75 * LDX (input) INTEGER
76 * The leading dimension of the array X. LDX >= max(1,N).
77 *
78 * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
79 * The estimated forward error bound for each solution vector
80 * X(j) (the j-th column of the solution matrix X).
81 * If XTRUE is the true solution corresponding to X(j), FERR(j)
82 * is an estimated upper bound for the magnitude of the largest
83 * element in (X(j) - XTRUE) divided by the magnitude of the
84 * largest element in X(j). The estimate is as reliable as
85 * the estimate for RCOND, and is almost always a slight
86 * overestimate of the true error.
87 *
88 * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
89 * The componentwise relative backward error of each solution
90 * vector X(j) (i.e., the smallest relative change in
91 * any element of A or B that makes X(j) an exact solution).
92 *
93 * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
94 *
95 * IWORK (workspace) INTEGER array, dimension (N)
96 *
97 * INFO (output) INTEGER
98 * = 0: successful exit
99 * < 0: if INFO = -i, the i-th argument had an illegal value
100 *
101 * Internal Parameters
102 * ===================
103 *
104 * ITMAX is the maximum number of steps of iterative refinement.
105 *
106 * =====================================================================
107 *
108 * .. Parameters ..
109  INTEGER ITMAX
110  parameter( itmax = 5 )
111  DOUBLE PRECISION ZERO
112  parameter( zero = 0.0d+0 )
113  DOUBLE PRECISION ONE
114  parameter( one = 1.0d+0 )
115  DOUBLE PRECISION TWO
116  parameter( two = 2.0d+0 )
117  DOUBLE PRECISION THREE
118  parameter( three = 3.0d+0 )
119 * ..
120 * .. Local Scalars ..
121  LOGICAL UPPER
122  INTEGER COUNT, I, J, K, KASE, NZ
123  DOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK
124 * ..
125 * .. External Subroutines ..
126  EXTERNAL daxpy, dcopy, dlacon, dsymv, dsytrs, xerbla
127 * ..
128 * .. Intrinsic Functions ..
129  INTRINSIC abs, max
130 * ..
131 * .. External Functions ..
132  LOGICAL LSAME
133  DOUBLE PRECISION DLAMCH
134  EXTERNAL lsame, dlamch
135 * ..
136 * .. Executable Statements ..
137 *
138 * Test the input parameters.
139 *
140  info = 0
141  upper = lsame( uplo, 'U' )
142  IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
143  info = -1
144  ELSE IF( n.LT.0 ) THEN
145  info = -2
146  ELSE IF( nrhs.LT.0 ) THEN
147  info = -3
148  ELSE IF( lda.LT.max( 1, n ) ) THEN
149  info = -5
150  ELSE IF( ldaf.LT.max( 1, n ) ) THEN
151  info = -7
152  ELSE IF( ldb.LT.max( 1, n ) ) THEN
153  info = -10
154  ELSE IF( ldx.LT.max( 1, n ) ) THEN
155  info = -12
156  END IF
157  IF( info.NE.0 ) THEN
158  CALL xerbla( 'DSYRFS', -info )
159  RETURN
160  END IF
161 *
162 * Quick return if possible
163 *
164  IF( n.EQ.0 .OR. nrhs.EQ.0 ) THEN
165  DO 10 j = 1, nrhs
166  ferr( j ) = zero
167  berr( j ) = zero
168  10 CONTINUE
169  RETURN
170  END IF
171 *
172 * NZ = maximum number of nonzero elements in each row of A, plus 1
173 *
174  nz = n + 1
175  eps = dlamch( 'Epsilon' )
176  safmin = dlamch( 'Safe minimum' )
177  safe1 = nz*safmin
178  safe2 = safe1 / eps
179 *
180 * Do for each right hand side
181 *
182  DO 140 j = 1, nrhs
183 *
184  count = 1
185  lstres = three
186  20 CONTINUE
187 *
188 * Loop until stopping criterion is satisfied.
189 *
190 * Compute residual R = B - A * X
191 *
192  CALL dcopy( n, b( 1, j ), 1, work( n+1 ), 1 )
193  CALL dsymv( uplo, n, -one, a, lda, x( 1, j ), 1, one,
194  $ work( n+1 ), 1 )
195 *
196 * Compute componentwise relative backward error from formula
197 *
198 * max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )
199 *
200 * where abs(Z) is the componentwise absolute value of the matrix
201 * or vector Z. If the i-th component of the denominator is less
202 * than SAFE2, then SAFE1 is added to the i-th components of the
203 * numerator and denominator before dividing.
204 *
205  DO 30 i = 1, n
206  work( i ) = abs( b( i, j ) )
207  30 CONTINUE
208 *
209 * Compute abs(A)*abs(X) + abs(B).
210 *
211  IF( upper ) THEN
212  DO 50 k = 1, n
213  s = zero
214  xk = abs( x( k, j ) )
215  DO 40 i = 1, k - 1
216  work( i ) = work( i ) + abs( a( i, k ) )*xk
217  s = s + abs( a( i, k ) )*abs( x( i, j ) )
218  40 CONTINUE
219  work( k ) = work( k ) + abs( a( k, k ) )*xk + s
220  50 CONTINUE
221  ELSE
222  DO 70 k = 1, n
223  s = zero
224  xk = abs( x( k, j ) )
225  work( k ) = work( k ) + abs( a( k, k ) )*xk
226  DO 60 i = k + 1, n
227  work( i ) = work( i ) + abs( a( i, k ) )*xk
228  s = s + abs( a( i, k ) )*abs( x( i, j ) )
229  60 CONTINUE
230  work( k ) = work( k ) + s
231  70 CONTINUE
232  END IF
233  s = zero
234  DO 80 i = 1, n
235  IF( work( i ).GT.safe2 ) THEN
236  s = max( s, abs( work( n+i ) ) / work( i ) )
237  ELSE
238  s = max( s, ( abs( work( n+i ) )+safe1 ) /
239  $ ( work( i )+safe1 ) )
240  END IF
241  80 CONTINUE
242  berr( j ) = s
243 *
244 * Test stopping criterion. Continue iterating if
245 * 1) The residual BERR(J) is larger than machine epsilon, and
246 * 2) BERR(J) decreased by at least a factor of 2 during the
247 * last iteration, and
248 * 3) At most ITMAX iterations tried.
249 *
250  IF( berr( j ).GT.eps .AND. two*berr( j ).LE.lstres .AND.
251  $ count.LE.itmax ) THEN
252 *
253 * Update solution and try again.
254 *
255  CALL dsytrs( uplo, n, 1, af, ldaf, ipiv, work( n+1 ), n,
256  $ info )
257  CALL daxpy( n, one, work( n+1 ), 1, x( 1, j ), 1 )
258  lstres = berr( j )
259  count = count + 1
260  GO TO 20
261  END IF
262 *
263 * Bound error from formula
264 *
265 * norm(X - XTRUE) / norm(X) .le. FERR =
266 * norm( abs(inv(A))*
267 * ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)
268 *
269 * where
270 * norm(Z) is the magnitude of the largest component of Z
271 * inv(A) is the inverse of A
272 * abs(Z) is the componentwise absolute value of the matrix or
273 * vector Z
274 * NZ is the maximum number of nonzeros in any row of A, plus 1
275 * EPS is machine epsilon
276 *
277 * The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))
278 * is incremented by SAFE1 if the i-th component of
279 * abs(A)*abs(X) + abs(B) is less than SAFE2.
280 *
281 * Use DLACON to estimate the infinity-norm of the matrix
282 * inv(A) * diag(W),
283 * where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) )))
284 *
285  DO 90 i = 1, n
286  IF( work( i ).GT.safe2 ) THEN
287  work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
288  ELSE
289  work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
290  END IF
291  90 CONTINUE
292 *
293  kase = 0
294  100 CONTINUE
295  CALL dlacon( n, work( 2*n+1 ), work( n+1 ), iwork, ferr( j ),
296  $ kase )
297  IF( kase.NE.0 ) THEN
298  IF( kase.EQ.1 ) THEN
299 *
300 * Multiply by diag(W)*inv(A').
301 *
302  CALL dsytrs( uplo, n, 1, af, ldaf, ipiv, work( n+1 ), n,
303  $ info )
304  DO 110 i = 1, n
305  work( n+i ) = work( i )*work( n+i )
306  110 CONTINUE
307  ELSE IF( kase.EQ.2 ) THEN
308 *
309 * Multiply by inv(A)*diag(W).
310 *
311  DO 120 i = 1, n
312  work( n+i ) = work( i )*work( n+i )
313  120 CONTINUE
314  CALL dsytrs( uplo, n, 1, af, ldaf, ipiv, work( n+1 ), n,
315  $ info )
316  END IF
317  GO TO 100
318  END IF
319 *
320 * Normalize error.
321 *
322  lstres = zero
323  DO 130 i = 1, n
324  lstres = max( lstres, abs( x( i, j ) ) )
325  130 CONTINUE
326  IF( lstres.NE.zero )
327  $ ferr( j ) = ferr( j ) / lstres
328 *
329  140 CONTINUE
330 *
331  RETURN
332 *
333 * End of DSYRFS
334 *
335  END
subroutine daxpy(n, da, dx, incx, dy, incy)
Definition: daxpy.f:2
subroutine dcopy(n, dx, incx, dy, incy)
Definition: dcopy.f:2
subroutine dlacon(N, V, X, ISGN, EST, KASE)
Definition: dlacon.f:2
subroutine dsymv(UPLO, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
Definition: dsymv.f:3
subroutine dsyrfs(UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO)
Definition: dsyrfs.f:3
subroutine xerbla(SRNAME, INFO)
Definition: xerbla.f:2