OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
pstrrfs.f
Go to the documentation of this file.
1 SUBROUTINE pstrrfs( UPLO, TRANS, DIAG, N, NRHS, A, IA, JA, DESCA,
2 $ B, IB, JB, DESCB, X, IX, JX, DESCX, FERR,
3 $ BERR, WORK, LWORK, IWORK, LIWORK, INFO )
4*
5* -- ScaLAPACK routine (version 1.7) --
6* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
7* and University of California, Berkeley.
8* May 1, 1997
9*
10* .. Scalar Arguments ..
11 CHARACTER DIAG, TRANS, UPLO
12 INTEGER INFO, IA, IB, IX, JA, JB, JX, LIWORK, LWORK,
13 $ n, nrhs
14* ..
15* .. Array Arguments ..
16 INTEGER DESCA( * ), DESCB( * ), DESCX( * ), IWORK( * )
17 REAL A( * ), B( * ), BERR( * ), FERR( * ),
18 $ work( * ), x( * )
19* ..
20*
21* Purpose
22* =======
23*
24* PSTRRFS provides error bounds and backward error estimates for the
25* solution to a system of linear equations with a triangular
26* coefficient matrix.
27*
28* The solution matrix X must be computed by PSTRTRS or some other
29* means before entering this routine. PSTRRFS does not do iterative
30* refinement because doing so cannot improve the backward error.
31*
32* Notes
33* =====
34*
35* Each global data object is described by an associated description
36* vector. This vector stores the information required to establish
37* the mapping between an object element and its corresponding process
38* and memory location.
39*
40* Let A be a generic term for any 2D block cyclicly distributed array.
41* Such a global array has an associated description vector DESCA.
42* In the following comments, the character _ should be read as
43* "of the global array".
44*
45* NOTATION STORED IN EXPLANATION
46* --------------- -------------- --------------------------------------
47* DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case,
48* DTYPE_A = 1.
49* CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
50* the BLACS process grid A is distribu-
51* ted over. The context itself is glo-
52* bal, but the handle (the integer
53* value) may vary.
54* M_A (global) DESCA( M_ ) The number of rows in the global
55* array A.
56* N_A (global) DESCA( N_ ) The number of columns in the global
57* array A.
58* MB_A (global) DESCA( MB_ ) The blocking factor used to distribute
59* the rows of the array.
60* NB_A (global) DESCA( NB_ ) The blocking factor used to distribute
61* the columns of the array.
62* RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
63* row of the array A is distributed.
64* CSRC_A (global) DESCA( CSRC_ ) The process column over which the
65* first column of the array A is
66* distributed.
67* LLD_A (local) DESCA( LLD_ ) The leading dimension of the local
68* array. LLD_A >= MAX(1,LOCr(M_A)).
69*
70* Let K be the number of rows or columns of a distributed matrix,
71* and assume that its process grid has dimension p x q.
72* LOCr( K ) denotes the number of elements of K that a process
73* would receive if K were distributed over the p processes of its
74* process column.
75* Similarly, LOCc( K ) denotes the number of elements of K that a
76* process would receive if K were distributed over the q processes of
77* its process row.
78* The values of LOCr() and LOCc() may be determined via a call to the
79* ScaLAPACK tool function, NUMROC:
80* LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
81* LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
82* An upper bound for these quantities may be computed by:
83* LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
84* LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
85*
86* In the following comments, sub( A ), sub( X ) and sub( B ) denote
87* respectively A(IA:IA+N-1,JA:JA+N-1), X(IX:IX+N-1,JX:JX+NRHS-1) and
88* B(IB:IB+N-1,JB:JB+NRHS-1).
89*
90* Arguments
91* =========
92*
93* UPLO (global input) CHARACTER*1
94* = 'U': sub( A ) is upper triangular;
95* = 'L': sub( A ) is lower triangular.
96*
97* TRANS (global input) CHARACTER*1
98* Specifies the form of the system of equations.
99* = 'N': sub( A ) * sub( X ) = sub( B ) (No transpose)
100* = 'T': sub( A )**T * sub( X ) = sub( B ) (Transpose)
101* = 'C': sub( A )**T * sub( X ) = sub( B )
102* (Conjugate transpose = Transpose)
103*
104*
105* DIAG (global input) CHARACTER*1
106* = 'N': sub( A ) is non-unit triangular;
107* = 'U': sub( A ) is unit triangular.
108*
109* N (global input) INTEGER
110* The order of the matrix sub( A ). N >= 0.
111*
112* NRHS (global input) INTEGER
113* The number of right hand sides, i.e., the number of columns
114* of the matrices sub( B ) and sub( X ). NRHS >= 0.
115*
116* A (local input) REAL pointer into the local memory
117* to an array of local dimension (LLD_A,LOCc(JA+N-1) ). This
118* array contains the local pieces of the original triangular
119* distributed matrix sub( A ).
120* If UPLO = 'U', the leading N-by-N upper triangular part of
121* sub( A ) contains the upper triangular part of the matrix,
122* and its strictly lower triangular part is not referenced.
123* If UPLO = 'L', the leading N-by-N lower triangular part of
124* sub( A ) contains the lower triangular part of the distribu-
125* ted matrix, and its strictly upper triangular part is not
126* referenced.
127* If DIAG = 'U', the diagonal elements of sub( A ) are also
128* not referenced and are assumed to be 1.
129*
130* IA (global input) INTEGER
131* The row index in the global array A indicating the first
132* row of sub( A ).
133*
134* JA (global input) INTEGER
135* The column index in the global array A indicating the
136* first column of sub( A ).
137*
138* DESCA (global and local input) INTEGER array of dimension DLEN_.
139* The array descriptor for the distributed matrix A.
140*
141* B (local input) REAL pointer into the local memory
142* to an array of local dimension (LLD_B, LOCc(JB+NRHS-1) ).
143* On entry, this array contains the the local pieces of the
144* right hand sides sub( B ).
145*
146* IB (global input) INTEGER
147* The row index in the global array B indicating the first
148* row of sub( B ).
149*
150* JB (global input) INTEGER
151* The column index in the global array B indicating the
152* first column of sub( B ).
153*
154* DESCB (global and local input) INTEGER array of dimension DLEN_.
155* The array descriptor for the distributed matrix B.
156*
157* X (local input) REAL pointer into the local memory
158* to an array of local dimension (LLD_X, LOCc(JX+NRHS-1) ).
159* On entry, this array contains the the local pieces of the
160* solution vectors sub( X ).
161*
162* IX (global input) INTEGER
163* The row index in the global array X indicating the first
164* row of sub( X ).
165*
166* JX (global input) INTEGER
167* The column index in the global array X indicating the
168* first column of sub( X ).
169*
170* DESCX (global and local input) INTEGER array of dimension DLEN_.
171* The array descriptor for the distributed matrix X.
172*
173* FERR (local output) REAL array of local dimension
174* LOCc(JB+NRHS-1). The estimated forward error bounds for
175* each solution vector of sub( X ). If XTRUE is the true
176* solution, FERR bounds the magnitude of the largest entry
177* in (sub( X ) - XTRUE) divided by the magnitude of the
178* largest entry in sub( X ). The estimate is as reliable as
179* the estimate for RCOND, and is almost always a slight
180* overestimate of the true error.
181* This array is tied to the distributed matrix X.
182*
183* BERR (local output) REAL array of local dimension
184* LOCc(JB+NRHS-1). The componentwise relative backward
185* error of each solution vector (i.e., the smallest re-
186* lative change in any entry of sub( A ) or sub( B )
187* that makes sub( X ) an exact solution).
188* This array is tied to the distributed matrix X.
189*
190* WORK (local workspace/local output) REAL array,
191* dimension (LWORK)
192* On exit, WORK(1) returns the minimal and optimal LWORK.
193*
194* LWORK (local or global input) INTEGER
195* The dimension of the array WORK.
196* LWORK is local input and must be at least
197* LWORK >= 3*LOCr( N + MOD( IA-1, MB_A ) ).
198*
199* If LWORK = -1, then LWORK is global input and a workspace
200* query is assumed; the routine only calculates the minimum
201* and optimal size for all work arrays. Each of these
202* values is returned in the first entry of the corresponding
203* work array, and no error message is issued by PXERBLA.
204*
205* IWORK (local workspace/local output) INTEGER array,
206* dimension (LIWORK)
207* On exit, IWORK(1) returns the minimal and optimal LIWORK.
208*
209* LIWORK (local or global input) INTEGER
210* The dimension of the array IWORK.
211* LIWORK is local input and must be at least
212* LIWORK >= LOCr( N + MOD( IB-1, MB_B ) ).
213*
214* If LIWORK = -1, then LIWORK is global input and a workspace
215* query is assumed; the routine only calculates the minimum
216* and optimal size for all work arrays. Each of these
217* values is returned in the first entry of the corresponding
218* work array, and no error message is issued by PXERBLA.
219*
220*
221* INFO (global output) INTEGER
222* = 0: successful exit
223* < 0: If the i-th argument is an array and the j-entry had
224* an illegal value, then INFO = -(i*100+j), if the i-th
225* argument is a scalar and had an illegal value, then
226* INFO = -i.
227*
228* Notes
229* =====
230*
231* This routine temporarily returns when N <= 1.
232*
233* The distributed submatrices sub( X ) and sub( B ) should be
234* distributed the same way on the same processes. These conditions
235* ensure that sub( X ) and sub( B ) are "perfectly" aligned.
236*
237* Moreover, this routine requires the distributed submatrices sub( A ),
238* sub( X ), and sub( B ) to be aligned on a block boundary,
239* i.e., if f(x,y) = MOD( x-1, y ):
240* f( IA, DESCA( MB_ ) ) = f( JA, DESCA( NB_ ) ) = 0,
241* f( IB, DESCB( MB_ ) ) = f( JB, DESCB( NB_ ) ) = 0, and
242* f( IX, DESCX( MB_ ) ) = f( JX, DESCX( NB_ ) ) = 0.
243*
244* =====================================================================
245*
246* .. Parameters ..
247 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
248 $ LLD_, MB_, M_, NB_, N_, RSRC_
249 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
250 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
251 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
252 REAL ZERO, ONE
253 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
254* ..
255* .. Local Scalars ..
256 LOGICAL LQUERY, NOTRAN, NOUNIT, UPPER
257 CHARACTER TRANST
258 INTEGER IAROW, IXBCOL, IXBROW, IXCOL, IXROW, ICOFFA,
259 $ icoffb, icoffx, ictxt, icurcol, idum, ii, iixb,
260 $ iiw, ioffxb, ipb, ipr, ipv, iroffa, iroffb,
261 $ iroffx, iw, j, jbrhs, jj, jjfbe, jjxb, jn, jw,
262 $ k, kase, ldxb, liwmin, lwmin, mycol, myrhs,
263 $ myrow, np, np0, npcol, npmod, nprow, nz
264 REAL EPS, EST, LSTRES, S, SAFE1, SAFE2, SAFMIN
265* ..
266* .. Local Arrays ..
267 INTEGER DESCW( DLEN_ ), IDUM1( 5 ), IDUM2( 5 )
268* ..
269* .. External Functions ..
270 LOGICAL LSAME
271 INTEGER ICEIL, INDXG2P, NUMROC
272 REAL PSLAMCH
273 EXTERNAL iceil, indxg2p, lsame, numroc, pslamch
274* ..
275* .. External Subroutines ..
277 $ pchk1mat, pchk2mat, psatrmv, psaxpy,
278 $ pscopy, pslacon, pstrsv, pstrmv,
279 $ pxerbla, sgamx2d, sgebr2d, sgebs2d
280* ..
281* .. Intrinsic Functions ..
282 INTRINSIC abs, ichar, max, min, mod, real
283* ..
284* .. Executable Statements ..
285*
286* Get grid parameters
287*
288 ictxt = desca( ctxt_ )
289 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
290*
291* Test the input parameters.
292*
293 info = 0
294 IF( nprow.EQ.-1 ) THEN
295 info = -( 900+ctxt_ )
296 ELSE
297 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 9, info )
298 CALL chk1mat( n, 4, nrhs, 5, ib, jb, descb, 13, info )
299 CALL chk1mat( n, 4, nrhs, 5, ix, jx, descx, 17, info )
300 IF( info.EQ.0 ) THEN
301 upper = lsame( uplo, 'U' )
302 notran = lsame( trans, 'N' )
303 nounit = lsame( diag, 'N' )
304 iroffa = mod( ia-1, desca( mb_ ) )
305 icoffa = mod( ja-1, desca( nb_ ) )
306 iroffb = mod( ib-1, descb( mb_ ) )
307 icoffb = mod( jb-1, descb( nb_ ) )
308 iroffx = mod( ix-1, descx( mb_ ) )
309 icoffx = mod( jx-1, descx( nb_ ) )
310 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
311 $ nprow )
312 CALL infog2l( ib, jb, descb, nprow, npcol, myrow, mycol,
313 $ iixb, jjxb, ixbrow, ixbcol )
314 ixrow = indxg2p( ix, descx( mb_ ), myrow, descx( rsrc_ ),
315 $ nprow )
316 ixcol = indxg2p( jx, descx( nb_ ), mycol, descx( csrc_ ),
317 $ npcol )
318 npmod = numroc( n+iroffa, desca( mb_ ), myrow, iarow,
319 $ nprow )
320 lwmin = 3*npmod
321 work( 1 ) = real( lwmin )
322 liwmin = npmod
323 iwork( 1 ) = liwmin
324 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
325*
326 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
327 info = -1
328 ELSE IF( .NOT.notran .AND. .NOT.lsame( trans, 'T' ) .AND.
329 $ .NOT.lsame( trans, 'C' ) ) THEN
330 info = -2
331 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag, 'U' ) ) THEN
332 info = -3
333 ELSE IF( n.LT.0 ) THEN
334 info = -4
335 ELSE IF( nrhs.LT.0 ) THEN
336 info = -5
337 ELSE IF( iroffa.NE.0 ) THEN
338 info = -7
339 ELSE IF( icoffa.NE.0 ) THEN
340 info = -8
341 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
342 info = -( 900+nb_ )
343 ELSE IF( iroffa.NE.iroffb .OR. iarow.NE.ixbrow ) THEN
344 info = -11
345 ELSE IF( desca( mb_ ).NE.descb( mb_ ) ) THEN
346 info = -( 1300+mb_ )
347 ELSE IF( ictxt.NE.descb( ctxt_ ) ) THEN
348 info = -( 1300+ctxt_ )
349 ELSE IF( iroffx.NE.0 .OR. ixbrow.NE.ixrow ) THEN
350 info = -15
351 ELSE IF( icoffb.NE.icoffx .OR. ixbcol.NE.ixcol ) THEN
352 info = -16
353 ELSE IF( descb( mb_ ).NE.descx( mb_ ) ) THEN
354 info = -( 1700+mb_ )
355 ELSE IF( descb( nb_ ).NE.descx( nb_ ) ) THEN
356 info = -( 1700+nb_ )
357 ELSE IF( ictxt.NE.descx( ctxt_ ) ) THEN
358 info = -( 1700+ctxt_ )
359 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
360 info = -21
361 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
362 info = -23
363 END IF
364 END IF
365*
366 IF( upper ) THEN
367 idum1( 1 ) = ichar( 'U' )
368 ELSE
369 idum1( 1 ) = ichar( 'L' )
370 END IF
371 idum2( 1 ) = 1
372 IF( notran ) THEN
373 idum1( 2 ) = ichar( 'N' )
374 ELSE IF( lsame( trans, 'T' ) ) THEN
375 idum1( 2 ) = ichar( 'T' )
376 ELSE
377 idum1( 2 ) = ichar( 'C' )
378 END IF
379 idum2( 2 ) = 2
380 IF( nounit ) THEN
381 idum1( 3 ) = ichar( 'N' )
382 ELSE
383 idum1( 3 ) = ichar( 'U' )
384 END IF
385 idum2( 3 ) = 3
386 IF( lwork.EQ.-1 ) THEN
387 idum1( 4 ) = -1
388 ELSE
389 idum1( 4 ) = 1
390 END IF
391 idum2( 4 ) = 21
392 IF( liwork.EQ.-1 ) THEN
393 idum1( 5 ) = -1
394 ELSE
395 idum1( 5 ) = 1
396 END IF
397 idum2( 5 ) = 23
398 CALL pchk1mat( n, 4, n, 4, ia, ja, desca, 9, 0, idum1, idum2,
399 $ info )
400 CALL pchk2mat( n, 4, nrhs, 5, ib, jb, descb, 13, n, 4, nrhs, 5,
401 $ ix, jx, descx, 17, 5, idum1, idum2, info )
402 END IF
403 IF( info.NE.0 ) THEN
404 CALL pxerbla( ictxt, 'PSTRRFS', -info )
405 RETURN
406 ELSE IF( lquery ) THEN
407 RETURN
408 END IF
409*
410 jjfbe = jjxb
411 myrhs = numroc( jb+nrhs-1, descb( nb_ ), mycol, descb( csrc_ ),
412 $ npcol )
413*
414* Quick return if possible
415*
416 IF( n.LE.1 .OR. nrhs.EQ.0 ) THEN
417 DO 10 jj = jjfbe, myrhs
418 ferr( jj ) = zero
419 berr( jj ) = zero
420 10 CONTINUE
421 RETURN
422 END IF
423*
424 IF( notran ) THEN
425 transt = 'T'
426 ELSE
427 transt = 'n'
428 END IF
429*
430 NP0 = NUMROC( N+IROFFB, DESCB( MB_ ), MYROW, IXBROW, NPROW )
431 CALL DESCSET( DESCW, N+IROFFB, 1, DESCA( MB_ ), 1, IXBROW, IXBCOL,
432 $ ICTXT, MAX( 1, NP0 ) )
433 IPB = 1
434 IPR = IPB + NP0
435 IPV = IPR + NP0
436.EQ. IF( MYROWIXBROW ) THEN
437 IIW = 1 + IROFFB
438 NP = NP0 - IROFFB
439 ELSE
440 IIW = 1
441 NP = NP0
442 END IF
443 IW = 1 + IROFFB
444 JW = 1
445 LDXB = DESCB( LLD_ )
446 IOFFXB = ( JJXB-1 )*LDXB
447*
448* NZ = maximum number of nonzero entries in each row of A, plus 1
449*
450 NZ = N + 1
451 EPS = PSLAMCH( ICTXT, 'epsilon' )
452 SAFMIN = PSLAMCH( ICTXT, 'safe minimum' )
453 SAFE1 = NZ*SAFMIN
454 SAFE2 = SAFE1 / EPS
455 JN = MIN( ICEIL( JB, DESCB( NB_ ) )*DESCB( NB_ ), JB+NRHS-1 )
456*
457* Handle first block separately
458*
459 JBRHS = JN - JB + 1
460 DO 90 K = 0, JBRHS - 1
461*
462* Compute residual R = B - op(A) * X,
463* where op(A) = A or A', depending on TRANS.
464*
465 CALL PSCOPY( N, X, IX, JX+K, DESCX, 1, WORK( IPR ), IW, JW,
466 $ DESCW, 1 )
467 CALL PSTRMV( UPLO, TRANS, DIAG, N, A, IA, JA, DESCA,
468 $ WORK( IPR ), IW, JW, DESCW, 1 )
469 CALL PSAXPY( N, -ONE, B, IB, JB+K, DESCB, 1, WORK( IPR ), IW,
470 $ JW, DESCW, 1 )
471*
472* Compute componentwise relative backward error from formula
473*
474* max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )
475*
476* where abs(Z) is the componentwise absolute value of the matrix
477* or vector Z. If the i-th component of the denominator is less
478* than SAFE2, then SAFE1 is added to the i-th components of the
479* numerator and denominator before dividing.
480*
481.EQ. IF( MYCOLIXBCOL ) THEN
482.GT. IF( NP0 ) THEN
483 DO 20 II = IIXB, IIXB + NP - 1
484 WORK( IIW+II-IIXB ) = ABS( B( II+IOFFXB ) )
485 20 CONTINUE
486 END IF
487 END IF
488*
489 CALL PSATRMV( UPLO, TRANS, DIAG, N, ONE, A, IA, JA, DESCA, X,
490 $ IX, JX+K, DESCX, 1, ONE, WORK( IPB ), IW, JW,
491 $ DESCW, 1 )
492*
493 S = ZERO
494.EQ. IF( MYCOLIXBCOL ) THEN
495.GT. IF( NP0 ) THEN
496 DO 30 II = IIW - 1, IIW + NP - 2
497.GT. IF( WORK( IPB+II )SAFE2 ) THEN
498 S = MAX( S, ABS( WORK( IPR+II ) ) /
499 $ WORK( IPB+II ) )
500 ELSE
501 S = MAX( S, ( ABS( WORK( IPR+II ) )+SAFE1 ) /
502 $ ( WORK( IPB+II )+SAFE1 ) )
503 END IF
504 30 CONTINUE
505 END IF
506 END IF
507*
508 CALL SGAMX2D( ICTXT, 'all', ' ', 1, 1, S, 1, IDUM, IDUM, 1,
509 $ -1, MYCOL )
510.EQ. IF( MYCOLIXBCOL )
511 $ BERR( JJFBE ) = S
512*
513* Bound error from formula
514*
515* norm(X - XTRUE) / norm(X) .le. FERR =
516* norm( abs(inv(op(A)))*
517* ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)
518*
519* where
520* norm(Z) is the magnitude of the largest component of Z
521* inv(op(A)) is the inverse of op(A)
522* abs(Z) is the componentwise absolute value of the matrix or
523* vector Z
524* NZ is the maximum number of nonzeros in any row of A, plus 1
525* EPS is machine epsilon
526*
527* The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))
528* is incremented by SAFE1 if the i-th component of
529* abs(op(A))*abs(X) + abs(B) is less than SAFE2.
530*
531* Use PSLACON to estimate the infinity-norm of the matrix
532* inv(op(A)) * diag(W),
533* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))
534*
535.EQ. IF( MYCOLIXBCOL ) THEN
536.GT. IF( NP0 ) THEN
537 DO 40 II = IIW - 1, IIW + NP - 2
538.GT. IF( WORK( IPB+II )SAFE2 ) THEN
539 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
540 $ NZ*EPS*WORK( IPB+II )
541 ELSE
542 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
543 $ NZ*EPS*WORK( IPB+II ) + SAFE1
544 END IF
545 40 CONTINUE
546 END IF
547 END IF
548*
549 KASE = 0
550 50 CONTINUE
551.EQ. IF( MYCOLIXBCOL ) THEN
552 CALL SGEBS2D( ICTXT, 'rowwise', ' ', NP, 1, WORK( IPR ),
553 $ DESCW( LLD_ ) )
554 ELSE
555 CALL SGEBR2D( ICTXT, 'rowwise', ' ', NP, 1, WORK( IPR ),
556 $ DESCW( LLD_ ), MYROW, IXBCOL )
557 END IF
558 DESCW( CSRC_ ) = MYCOL
559 CALL PSLACON( N, WORK( IPV ), IW, JW, DESCW, WORK( IPR ),
560 $ IW, JW, DESCW, IWORK, EST, KASE )
561 DESCW( CSRC_ ) = IXBCOL
562*
563.NE. IF( KASE0 ) THEN
564.EQ. IF( KASE1 ) THEN
565*
566* Multiply by diag(W)*inv(op(A)').
567*
568 CALL PSTRSV( UPLO, TRANST, DIAG, N, A, IA, JA, DESCA,
569 $ WORK( IPR ), IW, JW, DESCW, 1 )
570.EQ. IF( MYCOLIXBCOL ) THEN
571.GT. IF( NP0 ) THEN
572 DO 60 II = IIW - 1, IIW + NP - 2
573 WORK( IPR+II ) = WORK( IPB+II )*WORK( IPR+II )
574 60 CONTINUE
575 END IF
576 END IF
577 ELSE
578*
579* Multiply by inv(op(A))*diag(W).
580*
581.EQ. IF( MYCOLIXBCOL ) THEN
582.GT. IF( NP0 ) THEN
583 DO 70 II = IIW - 1, IIW + NP - 2
584 WORK( IPR+II ) = WORK( IPB+II )*WORK( IPR+II )
585 70 CONTINUE
586 END IF
587 END IF
588 CALL PSTRSV( UPLO, TRANS, DIAG, N, A, IA, JA, DESCA,
589 $ WORK( IPR ), IW, JW, DESCW, 1 )
590 END IF
591 GO TO 50
592 END IF
593*
594* Normalize error.
595*
596 LSTRES = ZERO
597.EQ. IF( MYCOLIXBCOL ) THEN
598.GT. IF( NP0 ) THEN
599 DO 80 II = IIXB, IIXB + NP - 1
600 LSTRES = MAX( LSTRES, ABS( X( IOFFXB+II ) ) )
601 80 CONTINUE
602 END IF
603 CALL SGAMX2D( ICTXT, 'column', ' ', 1, 1, LSTRES, 1, IDUM,
604 $ IDUM, 1, -1, MYCOL )
605.NE. IF( LSTRESZERO )
606 $ FERR( JJFBE ) = EST / LSTRES
607*
608 JJXB = JJXB + 1
609 JJFBE = JJFBE + 1
610 IOFFXB = IOFFXB + LDXB
611*
612 END IF
613*
614 90 CONTINUE
615*
616 ICURCOL = MOD( IXBCOL+1, NPCOL )
617*
618* Do for each right hand side
619*
620 DO 180 J = JN + 1, JB + NRHS - 1, DESCB( NB_ )
621 JBRHS = MIN( JB+NRHS-J, DESCB( NB_ ) )
622 DESCW( CSRC_ ) = ICURCOL
623*
624 DO 170 K = 0, JBRHS - 1
625*
626* Compute residual R = B - op(A) * X,
627* where op(A) = A or A', depending on TRANS.
628*
629 CALL PSCOPY( N, X, IX, J+K, DESCX, 1, WORK( IPR ), IW, JW,
630 $ DESCW, 1 )
631 CALL PSTRMV( UPLO, TRANS, DIAG, N, A, IA, JA, DESCA,
632 $ WORK( IPR ), IW, JW, DESCW, 1 )
633 CALL PSAXPY( N, -ONE, B, IB, J+K, DESCB, 1, WORK( IPR ),
634 $ IW, JW, DESCW, 1 )
635*
636* Compute componentwise relative backward error from formula
637*
638* max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )
639*
640* where abs(Z) is the componentwise absolute value of the
641* matrix or vector Z. If the i-th component of the
642* denominator is less than SAFE2, then SAFE1 is added to the
643* i-th components of the numerator and denominator before
644* dividing.
645*
646.EQ. IF( MYCOLIXBCOL ) THEN
647.GT. IF( NP0 ) THEN
648 DO 100 II = IIXB, IIXB + NP - 1
649 WORK( IIW+II-IIXB ) = ABS( B( II+IOFFXB ) )
650 100 CONTINUE
651 END IF
652 END IF
653*
654 CALL PSATRMV( UPLO, TRANS, DIAG, N, ONE, A, IA, JA, DESCA,
655 $ X, IX, J+K, DESCX, 1, ONE, WORK( IPB ), IW,
656 $ JW, DESCW, 1 )
657*
658 S = ZERO
659.EQ. IF( MYCOLIXBCOL ) THEN
660.GT. IF( NP0 ) THEN
661 DO 110 II = IIW - 1, IIW + NP - 2
662.GT. IF( WORK( IPB+II )SAFE2 ) THEN
663 S = MAX( S, ABS( WORK( IPR+II ) ) /
664 $ WORK( IPB+II ) )
665 ELSE
666 S = MAX( S, ( ABS( WORK( IPR+II ) )+SAFE1 ) /
667 $ ( WORK( IPB+II )+SAFE1 ) )
668 END IF
669 110 CONTINUE
670 END IF
671 END IF
672*
673 CALL SGAMX2D( ICTXT, 'all', ' ', 1, 1, S, 1, IDUM, IDUM, 1,
674 $ -1, MYCOL )
675.EQ. IF( MYCOLIXBCOL )
676 $ BERR( JJFBE ) = S
677*
678* Bound error from formula
679*
680* norm(X - XTRUE) / norm(X) .le. FERR =
681* norm( abs(inv(op(A)))*
682* ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))/norm(X)
683*
684* where
685* norm(Z) is the magnitude of the largest component of Z
686* inv(op(A)) is the inverse of op(A)
687* abs(Z) is the componentwise absolute value of the matrix
688* or vector Z
689* NZ is the maximum number of nonzeros in any row of A,
690* plus 1
691* EPS is machine epsilon
692*
693* The i-th component of
694* abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))
695* is incremented by SAFE1 if the i-th component of
696* abs(op(A))*abs(X) + abs(B) is less than SAFE2.
697*
698* Use PSLACON to estimate the infinity-norm of the matrix
699* inv(op(A)) * diag(W),
700* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))
701*
702.EQ. IF( MYCOLIXBCOL ) THEN
703.GT. IF( NP0 ) THEN
704 DO 120 II = IIW - 1, IIW + NP - 2
705.GT. IF( WORK( IPB+II )SAFE2 ) THEN
706 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
707 $ NZ*EPS*WORK( IPB+II )
708 ELSE
709 WORK( IPB+II ) = ABS( WORK( IPR+II ) ) +
710 $ NZ*EPS*WORK( IPB+II ) + SAFE1
711 END IF
712 120 CONTINUE
713 END IF
714 END IF
715*
716 KASE = 0
717 130 CONTINUE
718.EQ. IF( MYCOLIXBCOL ) THEN
719 CALL SGEBS2D( ICTXT, 'rowwise', ' ', NP, 1, WORK( IPR ),
720 $ DESCW( LLD_ ) )
721 ELSE
722 CALL SGEBR2D( ICTXT, 'rowwise', ' ', NP, 1, WORK( IPR ),
723 $ DESCW( LLD_ ), MYROW, IXBCOL )
724 END IF
725 DESCW( CSRC_ ) = MYCOL
726 CALL PSLACON( N, WORK( IPV ), IW, JW, DESCW, WORK( IPR ),
727 $ IW, JW, DESCW, IWORK, EST, KASE )
728 DESCW( CSRC_ ) = IXBCOL
729*
730.NE. IF( KASE0 ) THEN
731.EQ. IF( KASE1 ) THEN
732*
733* Multiply by diag(W)*inv(op(A)').
734*
735 CALL PSTRSV( UPLO, TRANST, DIAG, N, A, IA, JA, DESCA,
736 $ WORK( IPR ), IW, JW, DESCW, 1 )
737.EQ. IF( MYCOLIXBCOL ) THEN
738.GT. IF( NP0 ) THEN
739 DO 140 II = IIW - 1, IIW + NP - 2
740 WORK( IPR+II ) = WORK( IPB+II )*
741 $ WORK( IPR+II )
742 140 CONTINUE
743 END IF
744 END IF
745 ELSE
746*
747* Multiply by inv(op(A))*diag(W).
748*
749.EQ. IF( MYCOLIXBCOL ) THEN
750.GT. IF( NP0 ) THEN
751 DO 150 II = IIW - 1, IIW + NP - 2
752 WORK( IPR+II ) = WORK( IPB+II )*
753 $ WORK( IPR+II )
754 150 CONTINUE
755 END IF
756 END IF
757 CALL PSTRSV( UPLO, TRANS, DIAG, N, A, IA, JA, DESCA,
758 $ WORK( IPR ), IW, JW, DESCW, 1 )
759 END IF
760 GO TO 130
761 END IF
762*
763* Normalize error.
764*
765 LSTRES = ZERO
766.EQ. IF( MYCOLIXBCOL ) THEN
767.GT. IF( NP0 ) THEN
768 DO 160 II = IIXB, IIXB + NP - 1
769 LSTRES = MAX( LSTRES, ABS( X( IOFFXB+II ) ) )
770 160 CONTINUE
771 END IF
772 CALL SGAMX2D( ICTXT, 'column', ' ', 1, 1, LSTRES, 1,
773 $ IDUM, IDUM, 1, -1, MYCOL )
774.NE. IF( LSTRESZERO )
775 $ FERR( JJFBE ) = EST / LSTRES
776*
777 JJXB = JJXB + 1
778 JJFBE = JJFBE + 1
779 IOFFXB = IOFFXB + LDXB
780*
781 END IF
782*
783 170 CONTINUE
784*
785 ICURCOL = MOD( ICURCOL+1, NPCOL )
786*
787 180 CONTINUE
788*
789 WORK( 1 ) = REAL( LWMIN )
790 IWORK( 1 ) = LIWMIN
791*
792 RETURN
793*
794* End of PSTRRFS
795*
796 END
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21
subroutine sgebs2d(contxt, scope, top, m, n, a, lda)
Definition mpi.f:1072
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
Definition mpi.f:1577
subroutine pxerbla(contxt, srname, info)
Definition mpi.f:1600
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
Definition mpi.f:1610
subroutine sgebr2d(contxt, scope, top, m, n, a, lda)
Definition mpi.f:1113
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
Definition mpi.f:1588
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
Definition mpi.f:937
subroutine blacs_gridinfo(cntxt, nprow, npcol, myrow, mycol)
Definition mpi.f:754
subroutine psaxpy(n, a, x, ix, jx, descx, incx, y, iy, jy, descy, incy)
Definition mpi.f:1448
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
Definition pchkxmat.f:3
subroutine pslacon(n, v, iv, jv, descv, x, ix, jx, descx, isgn, est, kase)
Definition pslacon.f:3
subroutine pstrrfs(uplo, trans, diag, n, nrhs, a, ia, ja, desca, b, ib, jb, descb, x, ix, jx, descx, ferr, berr, work, lwork, iwork, liwork, info)
Definition pstrrfs.f:4