Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgerfs.f
5191 views
1
SUBROUTINE CGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,
2
$ X, LDX, FERR, BERR, WORK, RWORK, 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 TRANS
11
INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS
12
* ..
13
* .. Array Arguments ..
14
INTEGER IPIV( * )
15
REAL BERR( * ), FERR( * ), RWORK( * )
16
COMPLEX A( LDA, * ), AF( LDAF, * ), B( LDB, * ),
17
$ WORK( * ), X( LDX, * )
18
* ..
19
*
20
* Purpose
21
* =======
22
*
23
* CGERFS improves the computed solution to a system of linear
24
* equations and provides error bounds and backward error estimates for
25
* the solution.
26
*
27
* Arguments
28
* =========
29
*
30
* TRANS (input) CHARACTER*1
31
* Specifies the form of the system of equations:
32
* = 'N': A * X = B (No transpose)
33
* = 'T': A**T * X = B (Transpose)
34
* = 'C': A**H * X = B (Conjugate transpose)
35
*
36
* N (input) INTEGER
37
* The order of the matrix A. N >= 0.
38
*
39
* NRHS (input) INTEGER
40
* The number of right hand sides, i.e., the number of columns
41
* of the matrices B and X. NRHS >= 0.
42
*
43
* A (input) COMPLEX array, dimension (LDA,N)
44
* The original N-by-N matrix A.
45
*
46
* LDA (input) INTEGER
47
* The leading dimension of the array A. LDA >= max(1,N).
48
*
49
* AF (input) COMPLEX array, dimension (LDAF,N)
50
* The factors L and U from the factorization A = P*L*U
51
* as computed by CGETRF.
52
*
53
* LDAF (input) INTEGER
54
* The leading dimension of the array AF. LDAF >= max(1,N).
55
*
56
* IPIV (input) INTEGER array, dimension (N)
57
* The pivot indices from CGETRF; for 1<=i<=N, row i of the
58
* matrix was interchanged with row IPIV(i).
59
*
60
* B (input) COMPLEX array, dimension (LDB,NRHS)
61
* The right hand side matrix B.
62
*
63
* LDB (input) INTEGER
64
* The leading dimension of the array B. LDB >= max(1,N).
65
*
66
* X (input/output) COMPLEX array, dimension (LDX,NRHS)
67
* On entry, the solution matrix X, as computed by CGETRS.
68
* On exit, the improved solution matrix X.
69
*
70
* LDX (input) INTEGER
71
* The leading dimension of the array X. LDX >= max(1,N).
72
*
73
* FERR (output) REAL array, dimension (NRHS)
74
* The estimated forward error bound for each solution vector
75
* X(j) (the j-th column of the solution matrix X).
76
* If XTRUE is the true solution corresponding to X(j), FERR(j)
77
* is an estimated upper bound for the magnitude of the largest
78
* element in (X(j) - XTRUE) divided by the magnitude of the
79
* largest element in X(j). The estimate is as reliable as
80
* the estimate for RCOND, and is almost always a slight
81
* overestimate of the true error.
82
*
83
* BERR (output) REAL array, dimension (NRHS)
84
* The componentwise relative backward error of each solution
85
* vector X(j) (i.e., the smallest relative change in
86
* any element of A or B that makes X(j) an exact solution).
87
*
88
* WORK (workspace) COMPLEX array, dimension (2*N)
89
*
90
* RWORK (workspace) REAL array, dimension (N)
91
*
92
* INFO (output) INTEGER
93
* = 0: successful exit
94
* < 0: if INFO = -i, the i-th argument had an illegal value
95
*
96
* Internal Parameters
97
* ===================
98
*
99
* ITMAX is the maximum number of steps of iterative refinement.
100
*
101
* =====================================================================
102
*
103
* .. Parameters ..
104
INTEGER ITMAX
105
PARAMETER ( ITMAX = 5 )
106
REAL ZERO
107
PARAMETER ( ZERO = 0.0E+0 )
108
COMPLEX ONE
109
PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ) )
110
REAL TWO
111
PARAMETER ( TWO = 2.0E+0 )
112
REAL THREE
113
PARAMETER ( THREE = 3.0E+0 )
114
* ..
115
* .. Local Scalars ..
116
LOGICAL NOTRAN
117
CHARACTER TRANSN, TRANST
118
INTEGER COUNT, I, J, K, KASE, NZ
119
REAL EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK
120
COMPLEX ZDUM
121
* ..
122
* .. External Functions ..
123
LOGICAL LSAME
124
REAL SLAMCH
125
EXTERNAL LSAME, SLAMCH
126
* ..
127
* .. External Subroutines ..
128
EXTERNAL CAXPY, CCOPY, CGEMV, CGETRS, CLACON, XERBLA
129
* ..
130
* .. Intrinsic Functions ..
131
INTRINSIC ABS, AIMAG, MAX, REAL
132
* ..
133
* .. Statement Functions ..
134
REAL CABS1
135
* ..
136
* .. Statement Function definitions ..
137
CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
138
* ..
139
* .. Executable Statements ..
140
*
141
* Test the input parameters.
142
*
143
INFO = 0
144
NOTRAN = LSAME( TRANS, 'N' )
145
IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
146
$ LSAME( TRANS, 'C' ) ) THEN
147
INFO = -1
148
ELSE IF( N.LT.0 ) THEN
149
INFO = -2
150
ELSE IF( NRHS.LT.0 ) THEN
151
INFO = -3
152
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
153
INFO = -5
154
ELSE IF( LDAF.LT.MAX( 1, N ) ) THEN
155
INFO = -7
156
ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
157
INFO = -10
158
ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
159
INFO = -12
160
END IF
161
IF( INFO.NE.0 ) THEN
162
CALL XERBLA( 'CGERFS', -INFO )
163
RETURN
164
END IF
165
*
166
* Quick return if possible
167
*
168
IF( N.EQ.0 .OR. NRHS.EQ.0 ) THEN
169
DO 10 J = 1, NRHS
170
FERR( J ) = ZERO
171
BERR( J ) = ZERO
172
10 CONTINUE
173
RETURN
174
END IF
175
*
176
IF( NOTRAN ) THEN
177
TRANSN = 'N'
178
TRANST = 'C'
179
ELSE
180
TRANSN = 'C'
181
TRANST = 'N'
182
END IF
183
*
184
* NZ = maximum number of nonzero elements in each row of A, plus 1
185
*
186
NZ = N + 1
187
EPS = SLAMCH( 'Epsilon' )
188
SAFMIN = SLAMCH( 'Safe minimum' )
189
SAFE1 = NZ*SAFMIN
190
SAFE2 = SAFE1 / EPS
191
*
192
* Do for each right hand side
193
*
194
DO 140 J = 1, NRHS
195
*
196
COUNT = 1
197
LSTRES = THREE
198
20 CONTINUE
199
*
200
* Loop until stopping criterion is satisfied.
201
*
202
* Compute residual R = B - op(A) * X,
203
* where op(A) = A, A**T, or A**H, depending on TRANS.
204
*
205
CALL CCOPY( N, B( 1, J ), 1, WORK, 1 )
206
CALL CGEMV( TRANS, N, N, -ONE, A, LDA, X( 1, J ), 1, ONE, WORK,
207
$ 1 )
208
*
209
* Compute componentwise relative backward error from formula
210
*
211
* max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )
212
*
213
* where abs(Z) is the componentwise absolute value of the matrix
214
* or vector Z. If the i-th component of the denominator is less
215
* than SAFE2, then SAFE1 is added to the i-th components of the
216
* numerator and denominator before dividing.
217
*
218
DO 30 I = 1, N
219
RWORK( I ) = CABS1( B( I, J ) )
220
30 CONTINUE
221
*
222
* Compute abs(op(A))*abs(X) + abs(B).
223
*
224
IF( NOTRAN ) THEN
225
DO 50 K = 1, N
226
XK = CABS1( X( K, J ) )
227
DO 40 I = 1, N
228
RWORK( I ) = RWORK( I ) + CABS1( A( I, K ) )*XK
229
40 CONTINUE
230
50 CONTINUE
231
ELSE
232
DO 70 K = 1, N
233
S = ZERO
234
DO 60 I = 1, N
235
S = S + CABS1( A( I, K ) )*CABS1( X( I, J ) )
236
60 CONTINUE
237
RWORK( K ) = RWORK( K ) + S
238
70 CONTINUE
239
END IF
240
S = ZERO
241
DO 80 I = 1, N
242
IF( RWORK( I ).GT.SAFE2 ) THEN
243
S = MAX( S, CABS1( WORK( I ) ) / RWORK( I ) )
244
ELSE
245
S = MAX( S, ( CABS1( WORK( I ) )+SAFE1 ) /
246
$ ( RWORK( I )+SAFE1 ) )
247
END IF
248
80 CONTINUE
249
BERR( J ) = S
250
*
251
* Test stopping criterion. Continue iterating if
252
* 1) The residual BERR(J) is larger than machine epsilon, and
253
* 2) BERR(J) decreased by at least a factor of 2 during the
254
* last iteration, and
255
* 3) At most ITMAX iterations tried.
256
*
257
IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.
258
$ COUNT.LE.ITMAX ) THEN
259
*
260
* Update solution and try again.
261
*
262
CALL CGETRS( TRANS, N, 1, AF, LDAF, IPIV, WORK, N, INFO )
263
CALL CAXPY( N, ONE, WORK, 1, X( 1, J ), 1 )
264
LSTRES = BERR( J )
265
COUNT = COUNT + 1
266
GO TO 20
267
END IF
268
*
269
* Bound error from formula
270
*
271
* norm(X - XTRUE) / norm(X) .le. FERR =
272
* norm( abs(inv(op(A)))*
273
* ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)
274
*
275
* where
276
* norm(Z) is the magnitude of the largest component of Z
277
* inv(op(A)) is the inverse of op(A)
278
* abs(Z) is the componentwise absolute value of the matrix or
279
* vector Z
280
* NZ is the maximum number of nonzeros in any row of A, plus 1
281
* EPS is machine epsilon
282
*
283
* The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))
284
* is incremented by SAFE1 if the i-th component of
285
* abs(op(A))*abs(X) + abs(B) is less than SAFE2.
286
*
287
* Use CLACON to estimate the infinity-norm of the matrix
288
* inv(op(A)) * diag(W),
289
* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))
290
*
291
DO 90 I = 1, N
292
IF( RWORK( I ).GT.SAFE2 ) THEN
293
RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I )
294
ELSE
295
RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I ) +
296
$ SAFE1
297
END IF
298
90 CONTINUE
299
*
300
KASE = 0
301
100 CONTINUE
302
CALL CLACON( N, WORK( N+1 ), WORK, FERR( J ), KASE )
303
IF( KASE.NE.0 ) THEN
304
IF( KASE.EQ.1 ) THEN
305
*
306
* Multiply by diag(W)*inv(op(A)**H).
307
*
308
CALL CGETRS( TRANST, N, 1, AF, LDAF, IPIV, WORK, N,
309
$ INFO )
310
DO 110 I = 1, N
311
WORK( I ) = RWORK( I )*WORK( I )
312
110 CONTINUE
313
ELSE
314
*
315
* Multiply by inv(op(A))*diag(W).
316
*
317
DO 120 I = 1, N
318
WORK( I ) = RWORK( I )*WORK( I )
319
120 CONTINUE
320
CALL CGETRS( TRANSN, N, 1, AF, LDAF, IPIV, WORK, N,
321
$ INFO )
322
END IF
323
GO TO 100
324
END IF
325
*
326
* Normalize error.
327
*
328
LSTRES = ZERO
329
DO 130 I = 1, N
330
LSTRES = MAX( LSTRES, CABS1( X( I, J ) ) )
331
130 CONTINUE
332
IF( LSTRES.NE.ZERO )
333
$ FERR( J ) = FERR( J ) / LSTRES
334
*
335
140 CONTINUE
336
*
337
RETURN
338
*
339
* End of CGERFS
340
*
341
END
342
343