File:
[local] /
rpl /
lapack /
lapack /
dtbrfs.f
Revision
1.13:
download - view:
text,
annotated -
select for diffs -
revision graph
Mon Jan 27 09:28:29 2014 UTC (10 years, 7 months ago) by
bertrand
Branches:
MAIN
CVS tags:
rpl-4_1_24,
rpl-4_1_23,
rpl-4_1_22,
rpl-4_1_21,
rpl-4_1_20,
rpl-4_1_19,
rpl-4_1_18,
rpl-4_1_17,
HEAD
Cohérence.
1: *> \brief \b DTBRFS
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download DTBRFS + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtbrfs.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtbrfs.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtbrfs.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE DTBRFS( UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B,
22: * LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )
23: *
24: * .. Scalar Arguments ..
25: * CHARACTER DIAG, TRANS, UPLO
26: * INTEGER INFO, KD, LDAB, LDB, LDX, N, NRHS
27: * ..
28: * .. Array Arguments ..
29: * INTEGER IWORK( * )
30: * DOUBLE PRECISION AB( LDAB, * ), B( LDB, * ), BERR( * ),
31: * $ FERR( * ), WORK( * ), X( LDX, * )
32: * ..
33: *
34: *
35: *> \par Purpose:
36: * =============
37: *>
38: *> \verbatim
39: *>
40: *> DTBRFS provides error bounds and backward error estimates for the
41: *> solution to a system of linear equations with a triangular band
42: *> coefficient matrix.
43: *>
44: *> The solution matrix X must be computed by DTBTRS or some other
45: *> means before entering this routine. DTBRFS does not do iterative
46: *> refinement because doing so cannot improve the backward error.
47: *> \endverbatim
48: *
49: * Arguments:
50: * ==========
51: *
52: *> \param[in] UPLO
53: *> \verbatim
54: *> UPLO is CHARACTER*1
55: *> = 'U': A is upper triangular;
56: *> = 'L': A is lower triangular.
57: *> \endverbatim
58: *>
59: *> \param[in] TRANS
60: *> \verbatim
61: *> TRANS is CHARACTER*1
62: *> Specifies the form of the system of equations:
63: *> = 'N': A * X = B (No transpose)
64: *> = 'T': A**T * X = B (Transpose)
65: *> = 'C': A**H * X = B (Conjugate transpose = Transpose)
66: *> \endverbatim
67: *>
68: *> \param[in] DIAG
69: *> \verbatim
70: *> DIAG is CHARACTER*1
71: *> = 'N': A is non-unit triangular;
72: *> = 'U': A is unit triangular.
73: *> \endverbatim
74: *>
75: *> \param[in] N
76: *> \verbatim
77: *> N is INTEGER
78: *> The order of the matrix A. N >= 0.
79: *> \endverbatim
80: *>
81: *> \param[in] KD
82: *> \verbatim
83: *> KD is INTEGER
84: *> The number of superdiagonals or subdiagonals of the
85: *> triangular band matrix A. KD >= 0.
86: *> \endverbatim
87: *>
88: *> \param[in] NRHS
89: *> \verbatim
90: *> NRHS is INTEGER
91: *> The number of right hand sides, i.e., the number of columns
92: *> of the matrices B and X. NRHS >= 0.
93: *> \endverbatim
94: *>
95: *> \param[in] AB
96: *> \verbatim
97: *> AB is DOUBLE PRECISION array, dimension (LDAB,N)
98: *> The upper or lower triangular band matrix A, stored in the
99: *> first kd+1 rows of the array. The j-th column of A is stored
100: *> in the j-th column of the array AB as follows:
101: *> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
102: *> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
103: *> If DIAG = 'U', the diagonal elements of A are not referenced
104: *> and are assumed to be 1.
105: *> \endverbatim
106: *>
107: *> \param[in] LDAB
108: *> \verbatim
109: *> LDAB is INTEGER
110: *> The leading dimension of the array AB. LDAB >= KD+1.
111: *> \endverbatim
112: *>
113: *> \param[in] B
114: *> \verbatim
115: *> B is DOUBLE PRECISION array, dimension (LDB,NRHS)
116: *> The right hand side matrix B.
117: *> \endverbatim
118: *>
119: *> \param[in] LDB
120: *> \verbatim
121: *> LDB is INTEGER
122: *> The leading dimension of the array B. LDB >= max(1,N).
123: *> \endverbatim
124: *>
125: *> \param[in] X
126: *> \verbatim
127: *> X is DOUBLE PRECISION array, dimension (LDX,NRHS)
128: *> The solution matrix X.
129: *> \endverbatim
130: *>
131: *> \param[in] LDX
132: *> \verbatim
133: *> LDX is INTEGER
134: *> The leading dimension of the array X. LDX >= max(1,N).
135: *> \endverbatim
136: *>
137: *> \param[out] FERR
138: *> \verbatim
139: *> FERR is DOUBLE PRECISION array, dimension (NRHS)
140: *> The estimated forward error bound for each solution vector
141: *> X(j) (the j-th column of the solution matrix X).
142: *> If XTRUE is the true solution corresponding to X(j), FERR(j)
143: *> is an estimated upper bound for the magnitude of the largest
144: *> element in (X(j) - XTRUE) divided by the magnitude of the
145: *> largest element in X(j). The estimate is as reliable as
146: *> the estimate for RCOND, and is almost always a slight
147: *> overestimate of the true error.
148: *> \endverbatim
149: *>
150: *> \param[out] BERR
151: *> \verbatim
152: *> BERR is DOUBLE PRECISION array, dimension (NRHS)
153: *> The componentwise relative backward error of each solution
154: *> vector X(j) (i.e., the smallest relative change in
155: *> any element of A or B that makes X(j) an exact solution).
156: *> \endverbatim
157: *>
158: *> \param[out] WORK
159: *> \verbatim
160: *> WORK is DOUBLE PRECISION array, dimension (3*N)
161: *> \endverbatim
162: *>
163: *> \param[out] IWORK
164: *> \verbatim
165: *> IWORK is INTEGER array, dimension (N)
166: *> \endverbatim
167: *>
168: *> \param[out] INFO
169: *> \verbatim
170: *> INFO is INTEGER
171: *> = 0: successful exit
172: *> < 0: if INFO = -i, the i-th argument had an illegal value
173: *> \endverbatim
174: *
175: * Authors:
176: * ========
177: *
178: *> \author Univ. of Tennessee
179: *> \author Univ. of California Berkeley
180: *> \author Univ. of Colorado Denver
181: *> \author NAG Ltd.
182: *
183: *> \date November 2011
184: *
185: *> \ingroup doubleOTHERcomputational
186: *
187: * =====================================================================
188: SUBROUTINE DTBRFS( UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B,
189: $ LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )
190: *
191: * -- LAPACK computational routine (version 3.4.0) --
192: * -- LAPACK is a software package provided by Univ. of Tennessee, --
193: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
194: * November 2011
195: *
196: * .. Scalar Arguments ..
197: CHARACTER DIAG, TRANS, UPLO
198: INTEGER INFO, KD, LDAB, LDB, LDX, N, NRHS
199: * ..
200: * .. Array Arguments ..
201: INTEGER IWORK( * )
202: DOUBLE PRECISION AB( LDAB, * ), B( LDB, * ), BERR( * ),
203: $ FERR( * ), WORK( * ), X( LDX, * )
204: * ..
205: *
206: * =====================================================================
207: *
208: * .. Parameters ..
209: DOUBLE PRECISION ZERO
210: PARAMETER ( ZERO = 0.0D+0 )
211: DOUBLE PRECISION ONE
212: PARAMETER ( ONE = 1.0D+0 )
213: * ..
214: * .. Local Scalars ..
215: LOGICAL NOTRAN, NOUNIT, UPPER
216: CHARACTER TRANST
217: INTEGER I, J, K, KASE, NZ
218: DOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK
219: * ..
220: * .. Local Arrays ..
221: INTEGER ISAVE( 3 )
222: * ..
223: * .. External Subroutines ..
224: EXTERNAL DAXPY, DCOPY, DLACN2, DTBMV, DTBSV, XERBLA
225: * ..
226: * .. Intrinsic Functions ..
227: INTRINSIC ABS, MAX, MIN
228: * ..
229: * .. External Functions ..
230: LOGICAL LSAME
231: DOUBLE PRECISION DLAMCH
232: EXTERNAL LSAME, DLAMCH
233: * ..
234: * .. Executable Statements ..
235: *
236: * Test the input parameters.
237: *
238: INFO = 0
239: UPPER = LSAME( UPLO, 'U' )
240: NOTRAN = LSAME( TRANS, 'N' )
241: NOUNIT = LSAME( DIAG, 'N' )
242: *
243: IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
244: INFO = -1
245: ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
246: $ LSAME( TRANS, 'C' ) ) THEN
247: INFO = -2
248: ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
249: INFO = -3
250: ELSE IF( N.LT.0 ) THEN
251: INFO = -4
252: ELSE IF( KD.LT.0 ) THEN
253: INFO = -5
254: ELSE IF( NRHS.LT.0 ) THEN
255: INFO = -6
256: ELSE IF( LDAB.LT.KD+1 ) THEN
257: INFO = -8
258: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
259: INFO = -10
260: ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
261: INFO = -12
262: END IF
263: IF( INFO.NE.0 ) THEN
264: CALL XERBLA( 'DTBRFS', -INFO )
265: RETURN
266: END IF
267: *
268: * Quick return if possible
269: *
270: IF( N.EQ.0 .OR. NRHS.EQ.0 ) THEN
271: DO 10 J = 1, NRHS
272: FERR( J ) = ZERO
273: BERR( J ) = ZERO
274: 10 CONTINUE
275: RETURN
276: END IF
277: *
278: IF( NOTRAN ) THEN
279: TRANST = 'T'
280: ELSE
281: TRANST = 'N'
282: END IF
283: *
284: * NZ = maximum number of nonzero elements in each row of A, plus 1
285: *
286: NZ = KD + 2
287: EPS = DLAMCH( 'Epsilon' )
288: SAFMIN = DLAMCH( 'Safe minimum' )
289: SAFE1 = NZ*SAFMIN
290: SAFE2 = SAFE1 / EPS
291: *
292: * Do for each right hand side
293: *
294: DO 250 J = 1, NRHS
295: *
296: * Compute residual R = B - op(A) * X,
297: * where op(A) = A or A**T, depending on TRANS.
298: *
299: CALL DCOPY( N, X( 1, J ), 1, WORK( N+1 ), 1 )
300: CALL DTBMV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, WORK( N+1 ),
301: $ 1 )
302: CALL DAXPY( N, -ONE, B( 1, J ), 1, WORK( N+1 ), 1 )
303: *
304: * Compute componentwise relative backward error from formula
305: *
306: * max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )
307: *
308: * where abs(Z) is the componentwise absolute value of the matrix
309: * or vector Z. If the i-th component of the denominator is less
310: * than SAFE2, then SAFE1 is added to the i-th components of the
311: * numerator and denominator before dividing.
312: *
313: DO 20 I = 1, N
314: WORK( I ) = ABS( B( I, J ) )
315: 20 CONTINUE
316: *
317: IF( NOTRAN ) THEN
318: *
319: * Compute abs(A)*abs(X) + abs(B).
320: *
321: IF( UPPER ) THEN
322: IF( NOUNIT ) THEN
323: DO 40 K = 1, N
324: XK = ABS( X( K, J ) )
325: DO 30 I = MAX( 1, K-KD ), K
326: WORK( I ) = WORK( I ) +
327: $ ABS( AB( KD+1+I-K, K ) )*XK
328: 30 CONTINUE
329: 40 CONTINUE
330: ELSE
331: DO 60 K = 1, N
332: XK = ABS( X( K, J ) )
333: DO 50 I = MAX( 1, K-KD ), K - 1
334: WORK( I ) = WORK( I ) +
335: $ ABS( AB( KD+1+I-K, K ) )*XK
336: 50 CONTINUE
337: WORK( K ) = WORK( K ) + XK
338: 60 CONTINUE
339: END IF
340: ELSE
341: IF( NOUNIT ) THEN
342: DO 80 K = 1, N
343: XK = ABS( X( K, J ) )
344: DO 70 I = K, MIN( N, K+KD )
345: WORK( I ) = WORK( I ) + ABS( AB( 1+I-K, K ) )*XK
346: 70 CONTINUE
347: 80 CONTINUE
348: ELSE
349: DO 100 K = 1, N
350: XK = ABS( X( K, J ) )
351: DO 90 I = K + 1, MIN( N, K+KD )
352: WORK( I ) = WORK( I ) + ABS( AB( 1+I-K, K ) )*XK
353: 90 CONTINUE
354: WORK( K ) = WORK( K ) + XK
355: 100 CONTINUE
356: END IF
357: END IF
358: ELSE
359: *
360: * Compute abs(A**T)*abs(X) + abs(B).
361: *
362: IF( UPPER ) THEN
363: IF( NOUNIT ) THEN
364: DO 120 K = 1, N
365: S = ZERO
366: DO 110 I = MAX( 1, K-KD ), K
367: S = S + ABS( AB( KD+1+I-K, K ) )*
368: $ ABS( X( I, J ) )
369: 110 CONTINUE
370: WORK( K ) = WORK( K ) + S
371: 120 CONTINUE
372: ELSE
373: DO 140 K = 1, N
374: S = ABS( X( K, J ) )
375: DO 130 I = MAX( 1, K-KD ), K - 1
376: S = S + ABS( AB( KD+1+I-K, K ) )*
377: $ ABS( X( I, J ) )
378: 130 CONTINUE
379: WORK( K ) = WORK( K ) + S
380: 140 CONTINUE
381: END IF
382: ELSE
383: IF( NOUNIT ) THEN
384: DO 160 K = 1, N
385: S = ZERO
386: DO 150 I = K, MIN( N, K+KD )
387: S = S + ABS( AB( 1+I-K, K ) )*ABS( X( I, J ) )
388: 150 CONTINUE
389: WORK( K ) = WORK( K ) + S
390: 160 CONTINUE
391: ELSE
392: DO 180 K = 1, N
393: S = ABS( X( K, J ) )
394: DO 170 I = K + 1, MIN( N, K+KD )
395: S = S + ABS( AB( 1+I-K, K ) )*ABS( X( I, J ) )
396: 170 CONTINUE
397: WORK( K ) = WORK( K ) + S
398: 180 CONTINUE
399: END IF
400: END IF
401: END IF
402: S = ZERO
403: DO 190 I = 1, N
404: IF( WORK( I ).GT.SAFE2 ) THEN
405: S = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )
406: ELSE
407: S = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /
408: $ ( WORK( I )+SAFE1 ) )
409: END IF
410: 190 CONTINUE
411: BERR( J ) = S
412: *
413: * Bound error from formula
414: *
415: * norm(X - XTRUE) / norm(X) .le. FERR =
416: * norm( abs(inv(op(A)))*
417: * ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)
418: *
419: * where
420: * norm(Z) is the magnitude of the largest component of Z
421: * inv(op(A)) is the inverse of op(A)
422: * abs(Z) is the componentwise absolute value of the matrix or
423: * vector Z
424: * NZ is the maximum number of nonzeros in any row of A, plus 1
425: * EPS is machine epsilon
426: *
427: * The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))
428: * is incremented by SAFE1 if the i-th component of
429: * abs(op(A))*abs(X) + abs(B) is less than SAFE2.
430: *
431: * Use DLACN2 to estimate the infinity-norm of the matrix
432: * inv(op(A)) * diag(W),
433: * where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))
434: *
435: DO 200 I = 1, N
436: IF( WORK( I ).GT.SAFE2 ) THEN
437: WORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )
438: ELSE
439: WORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1
440: END IF
441: 200 CONTINUE
442: *
443: KASE = 0
444: 210 CONTINUE
445: CALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),
446: $ KASE, ISAVE )
447: IF( KASE.NE.0 ) THEN
448: IF( KASE.EQ.1 ) THEN
449: *
450: * Multiply by diag(W)*inv(op(A)**T).
451: *
452: CALL DTBSV( UPLO, TRANST, DIAG, N, KD, AB, LDAB,
453: $ WORK( N+1 ), 1 )
454: DO 220 I = 1, N
455: WORK( N+I ) = WORK( I )*WORK( N+I )
456: 220 CONTINUE
457: ELSE
458: *
459: * Multiply by inv(op(A))*diag(W).
460: *
461: DO 230 I = 1, N
462: WORK( N+I ) = WORK( I )*WORK( N+I )
463: 230 CONTINUE
464: CALL DTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB,
465: $ WORK( N+1 ), 1 )
466: END IF
467: GO TO 210
468: END IF
469: *
470: * Normalize error.
471: *
472: LSTRES = ZERO
473: DO 240 I = 1, N
474: LSTRES = MAX( LSTRES, ABS( X( I, J ) ) )
475: 240 CONTINUE
476: IF( LSTRES.NE.ZERO )
477: $ FERR( J ) = FERR( J ) / LSTRES
478: *
479: 250 CONTINUE
480: *
481: RETURN
482: *
483: * End of DTBRFS
484: *
485: END
CVSweb interface <joel.bertrand@systella.fr>