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