SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pspocon.f
Go to the documentation of this file.
1 SUBROUTINE pspocon( UPLO, N, A, IA, JA, DESCA, ANORM, RCOND, WORK,
2 $ LWORK, IWORK, LIWORK, INFO )
3*
4* -- ScaLAPACK routine (version 1.7) --
5* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
6* and University of California, Berkeley.
7* May 25, 2001
8*
9* .. Scalar Arguments ..
10 CHARACTER UPLO
11 INTEGER IA, INFO, JA, LIWORK, LWORK, N
12 REAL ANORM, RCOND
13* ..
14* .. Array Arguments ..
15 INTEGER DESCA( * ), IWORK( * )
16 REAL A( * ), WORK( * )
17* ..
18*
19* Purpose
20* =======
21*
22* PSPOCON estimates the reciprocal of the condition number (in the
23* 1-norm) of a real symmetric positive definite distributed matrix
24* using the Cholesky factorization A = U**T*U or A = L*L**T computed by
25* PSPOTRF.
26*
27* An estimate is obtained for norm(inv(A(IA:IA+N-1,JA:JA+N-1))), and
28* the reciprocal of the condition number is computed as
29* RCOND = 1 / ( norm( A(IA:IA+N-1,JA:JA+N-1) ) *
30* norm( inv(A(IA:IA+N-1,JA:JA+N-1)) ) ).
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* Arguments
87* =========
88*
89* UPLO (global input) CHARACTER
90* Specifies whether the factor stored in
91* A(IA:IA+N-1,JA:JA+N-1) is upper or lower triangular.
92* = 'U': Upper triangular
93* = 'L': Lower triangular
94*
95* N (global input) INTEGER
96* The order of the distributed matrix A(IA:IA+N-1,JA:JA+N-1).
97* N >= 0.
98*
99* A (local input) REAL pointer into the local memory to
100* an array of dimension ( LLD_A, LOCc(JA+N-1) ). On entry, this
101* array contains the local pieces of the factors L or U from
102* the Cholesky factorization A(IA:IA+N-1,JA:JA+N-1) = U'*U or
103* L*L', as computed by PSPOTRF.
104*
105* IA (global input) INTEGER
106* The row index in the global array A indicating the first
107* row of sub( A ).
108*
109* JA (global input) INTEGER
110* The column index in the global array A indicating the
111* first column of sub( A ).
112*
113* DESCA (global and local input) INTEGER array of dimension DLEN_.
114* The array descriptor for the distributed matrix A.
115*
116* ANORM (global input) REAL
117* The 1-norm (or infinity-norm) of the symmetric distributed
118* matrix A(IA:IA+N-1,JA:JA+N-1).
119*
120* RCOND (global output) REAL
121* The reciprocal of the condition number of the distributed
122* matrix A(IA:IA+N-1,JA:JA+N-1), computed as
123* RCOND = 1 / ( norm( A(IA:IA+N-1,JA:JA+N-1) ) *
124* norm( inv(A(IA:IA+N-1,JA:JA+N-1)) ) ).
125*
126* WORK (local workspace/local output) REAL array,
127* dimension (LWORK)
128* On exit, WORK(1) returns the minimal and optimal LWORK.
129*
130* LWORK (local or global input) INTEGER
131* The dimension of the array WORK.
132* LWORK is local input and must be at least
133* LWORK >= 2*LOCr(N+MOD(IA-1,MB_A)) + 2*LOCc(N+MOD(JA-1,NB_A))+
134* MAX( 2, MAX(NB_A*CEIL(NPROW-1,NPCOL),LOCc(N+MOD(JA-1,NB_A)) +
135* NB_A*CEIL(NPCOL-1,NPROW)) ).
136*
137* If LWORK = -1, then LWORK is global input and a workspace
138* query is assumed; the routine only calculates the minimum
139* and optimal size for all work arrays. Each of these
140* values is returned in the first entry of the corresponding
141* work array, and no error message is issued by PXERBLA.
142*
143* IWORK (local workspace/local output) INTEGER array,
144* dimension (LIWORK)
145* On exit, IWORK(1) returns the minimal and optimal LIWORK.
146*
147* LIWORK (local or global input) INTEGER
148* The dimension of the array IWORK.
149* LIWORK is local input and must be at least
150* LIWORK >= LOCr(N+MOD(IA-1,MB_A)).
151*
152* If LIWORK = -1, then LIWORK is global input and a workspace
153* query is assumed; the routine only calculates the minimum
154* and optimal size for all work arrays. Each of these
155* values is returned in the first entry of the corresponding
156* work array, and no error message is issued by PXERBLA.
157*
158*
159* INFO (global output) INTEGER
160* = 0: successful exit
161* < 0: If the i-th argument is an array and the j-entry had
162* an illegal value, then INFO = -(i*100+j), if the i-th
163* argument is a scalar and had an illegal value, then
164* INFO = -i.
165*
166* =====================================================================
167*
168* .. Parameters ..
169 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
170 $ lld_, mb_, m_, nb_, n_, rsrc_
171 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
172 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
173 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
174 REAL ONE, ZERO
175 parameter( one = 1.0e+0, zero = 0.0e+0 )
176* ..
177* .. Local Scalars ..
178 LOGICAL LQUERY, UPPER
179 CHARACTER CBTOP, COLCTOP, NORMIN, ROWCTOP
180 INTEGER IACOL, IAROW, ICOFF, ICTXT, IIA, IPNL, IPNU,
181 $ ipv, ipw, ipx, iroff, iv, ix, ixx, jja, jv,
182 $ jx, kase, liwmin, lwmin, mycol, myrow, np,
183 $ npcol, nprow, npmod, nq, nqmod
184 REAL AINVNM, SCALE, SL, SU, SMLNUM
185 REAL WMAX
186* ..
187* .. Local Arrays ..
188 INTEGER DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 3 ),
189 $ idum2( 3 )
190* ..
191* .. External Subroutines ..
192 EXTERNAL blacs_gridinfo, chk1mat, descset, infog2l,
193 $ pchk1mat, psamax, pslatrs, pslacon,
194 $ psrscl, pb_topget, pb_topset, pxerbla, sgebr2d,
195 $ sgebs2d
196* ..
197* .. External Functions ..
198 LOGICAL LSAME
199 INTEGER ICEIL, INDXG2P, NUMROC
200 REAL PSLAMCH
201 EXTERNAL iceil, indxg2p, lsame, numroc, pslamch
202* ..
203* .. Intrinsic Functions ..
204 INTRINSIC abs, ichar, max, mod, real
205* ..
206* .. Executable Statements ..
207*
208* Get grid parameters
209*
210 ictxt = desca( ctxt_ )
211 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
212*
213* Test the input parameters
214*
215 info = 0
216 IF( nprow.EQ.-1 ) THEN
217 info = -(600+ctxt_)
218 ELSE
219 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
220 IF( info.EQ.0 ) THEN
221 upper = lsame( uplo, 'U' )
222 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
223 $ nprow )
224 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
225 $ npcol )
226 npmod = numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
227 $ myrow, iarow, nprow )
228 nqmod = numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
229 $ mycol, iacol, npcol )
230 lwmin = 2*npmod + 2*nqmod +
231 $ max( 2, max( desca( nb_ )*
232 $ max( 1, iceil( nprow-1, npcol ) ), nqmod +
233 $ desca( nb_ )*
234 $ max( 1, iceil( npcol-1, nprow ) ) ) )
235 work( 1 ) = real( lwmin )
236 liwmin = npmod
237 iwork( 1 ) = liwmin
238 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
239*
240 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
241 info = -1
242 ELSE IF( anorm.LT.zero ) THEN
243 info = -7
244 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
245 info = -10
246 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
247 iwork( 1 ) = liwmin
248 info = -12
249 END IF
250 END IF
251*
252 IF( upper ) THEN
253 idum1( 1 ) = ichar( 'U' )
254 ELSE
255 idum1( 1 ) = ichar( 'L' )
256 END IF
257 idum2( 1 ) = 1
258 IF( lwork.EQ.-1 ) THEN
259 idum1( 2 ) = -1
260 ELSE
261 idum1( 2 ) = 1
262 END IF
263 idum2( 2 ) = 10
264 IF( liwork.EQ.-1 ) THEN
265 idum1( 3 ) = -1
266 ELSE
267 idum1( 3 ) = 1
268 END IF
269 idum2( 3 ) = 12
270 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 3, idum1, idum2,
271 $ info )
272 END IF
273*
274 IF( info.NE.0 ) THEN
275 CALL pxerbla( ictxt, 'PSPOCON', -info )
276 RETURN
277 ELSE IF( lquery ) THEN
278 RETURN
279 END IF
280*
281* Quick return if possible
282*
283 rcond = zero
284 IF( n.EQ.0 ) THEN
285 rcond = one
286 RETURN
287 ELSE IF( anorm.EQ.zero ) THEN
288 RETURN
289 ELSE IF( n.EQ.1 ) THEN
290 rcond = one
291 RETURN
292 END IF
293*
294 CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
295 CALL pb_topget( ictxt, 'Combine', 'Rowwise', rowctop )
296 CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
297 CALL pb_topset( ictxt, 'Combine', 'Rowwise', '1-tree' )
298*
299 smlnum = pslamch( ictxt, 'Safe minimum' )
300 iroff = mod( ia-1, desca( mb_ ) )
301 icoff = mod( ja-1, desca( nb_ ) )
302 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
303 $ iarow, iacol )
304 np = numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
305 nq = numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
306 iv = iroff + 1
307 ix = iv
308 jv = icoff + 1
309 jx = jv
310*
311 ipx = 1
312 ipv = ipx + np
313 ipnl = ipv + np
314 ipnu = ipnl + nq
315 ipw = ipnu + nq
316*
317 CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
318 $ ictxt, max( 1, np ) )
319 CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
320 $ ictxt, max( 1, np ) )
321*
322* Estimate the 1-norm (or I-norm) of inv(A).
323*
324 ainvnm = zero
325 kase = 0
326 normin = 'N'
327*
328 10 CONTINUE
329 CALL pslacon( n, work( ipv ), iv, jv, descv, work( ipx ), ix, jx,
330 $ descx, iwork, ainvnm, kase )
331 IF( kase.NE.0 ) THEN
332 IF( upper ) THEN
333*
334* Multiply by inv(U').
335*
336 descx( csrc_ ) = iacol
337 CALL pslatrs( 'Upper', 'Transpose', 'Non-unit', normin,
338 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
339 $ descx, sl, work( ipnl ), work( ipw ) )
340 descx( csrc_ ) = mycol
341 normin = 'Y'
342*
343* Multiply by inv(U).
344*
345 descx( csrc_ ) = iacol
346 CALL pslatrs( 'Upper', 'No transpose', 'Non-unit', normin,
347 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
348 $ descx, su, work( ipnu ), work( ipw ) )
349 descx( csrc_ ) = mycol
350 ELSE
351*
352* Multiply by inv(L).
353*
354 descx( csrc_ ) = iacol
355 CALL pslatrs( 'Lower', 'No transpose', 'Non-unit', normin,
356 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
357 $ descx, sl, work( ipnl ), work( ipw ) )
358 descx( csrc_ ) = mycol
359 normin = 'Y'
360*
361* Multiply by inv(L').
362*
363 descx( csrc_ ) = iacol
364 CALL pslatrs( 'Lower', 'Transpose', 'Non-unit', normin,
365 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
366 $ descx, su, work( ipnu ), work( ipw ) )
367 descx( csrc_ ) = mycol
368 END IF
369*
370* Multiply by 1/SCALE if doing so will not cause overflow.
371*
372 scale = sl*su
373 IF( scale.NE.one ) THEN
374 CALL psamax( n, wmax, ixx, work( ipx ), ix, jx, descx, 1 )
375 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
376 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', cbtop )
377 IF( myrow.EQ.iarow ) THEN
378 CALL sgebs2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1 )
379 ELSE
380 CALL sgebr2d( ictxt, 'Column', cbtop, 1, 1, wmax, 1,
381 $ iarow, mycol )
382 END IF
383 END IF
384 IF( scale.LT.abs( wmax )*smlnum .OR. scale.EQ.zero )
385 $ GO TO 20
386 CALL psrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
387 END IF
388 GO TO 10
389 END IF
390*
391* Compute the estimate of the reciprocal condition number.
392*
393 IF( ainvnm.NE.zero )
394 $ rcond = ( one / ainvnm ) / anorm
395*
396 20 CONTINUE
397*
398 CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
399 CALL pb_topset( ictxt, 'Combine', 'Rowwise', rowctop )
400*
401 RETURN
402*
403* End of PSPOCON
404*
405 END
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
Definition chk1mat.f:3
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
Definition descset.f:3
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
Definition infog2l.f:3
#define max(A, B)
Definition pcgemr.c:180
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 pslatrs(uplo, trans, diag, normin, n, a, ia, ja, desca, x, ix, jx, descx, scale, cnorm, work)
Definition pslatrs.f:4
subroutine pspocon(uplo, n, a, ia, ja, desca, anorm, rcond, work, lwork, iwork, liwork, info)
Definition pspocon.f:3
subroutine psrscl(n, sa, sx, ix, jx, descx, incx)
Definition psrscl.f:2
subroutine pxerbla(ictxt, srname, info)
Definition pxerbla.f:2