1 SUBROUTINE pctrcon( NORM, UPLO, DIAG, N, A, IA, JA, DESCA, RCOND,
2 $ WORK, LWORK, RWORK, LRWORK, INFO )
11 CHARACTER DIAG, NORM, UPLO
12 INTEGER IA, JA, INFO, LRWORK, LWORK, N
18 COMPLEX A( * ), WORK( * )
182 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
183 $ lld_, mb_, m_, nb_, n_, rsrc_
184 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
185 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
186 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
188 parameter( one = 1.0e+0, zero = 0.0e+0 )
191 LOGICAL LQUERY, NOUNIT, ONENRM, UPPER
192 CHARACTER CBTOP, COLCTOP, NORMIN, ROWCTOP
193 INTEGER IACOL, IAROW, ICOFF, ICTXT, IIA, IPN, IPV, IPW,
194 $ ipx, iroff, iv, ix, ixx, jja, jv, jx, kase,
195 $ kase1, lrwmin, lwmin, mycol, myrow, np, npcol,
196 $ npmod, nprow, nqmod
197 REAL AINVNM, ANORM, SCALE, SMLNUM
201 INTEGER DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 5 ),
205 EXTERNAL blacs_gridinfo, cgebr2d, cgebs2d,
chk1mat,
212 INTEGER ICEIL, INDXG2P, NUMROC
213 REAL PCLANTR, PSLAMCH
214 EXTERNAL iceil, indxg2p, lsame, numroc, pclantr,
218 INTRINSIC abs, aimag, ichar,
max, mod, real
224 cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
230 ictxt = desca( ctxt_ )
231 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
236 IF( nprow.EQ.-1 )
THEN
237 info = -( 800 + ctxt_ )
239 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 8, info )
241 upper = lsame( uplo,
'U' )
242 onenrm = norm.EQ.
'1' .OR. lsame( norm,
'O' )
243 nounit = lsame( diag,
'N' )
244 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
246 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
248 npmod = numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
249 $ myrow, iarow, nprow )
250 nqmod = numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
251 $ mycol, iacol, npcol )
253 $
max( 2,
max( desca( nb_ )*
254 $
max( 1, iceil( nprow-1, npcol ) ), nqmod +
256 $
max( 1, iceil( npcol-1, nprow ) ) ) )
257 work( 1 ) = real( lwmin )
259 rwork( 1 ) = real( lrwmin )
260 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
262 IF( .NOT.onenrm .AND. .NOT.lsame( norm,
'I' ) )
THEN
264 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
266 ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag,
'U' ) )
THEN
268 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
270 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery )
THEN
276 idum1( 1 ) = ichar(
'1' )
278 idum1( 1 ) = ichar(
'I' )
282 idum1( 2 ) = ichar(
'U' )
284 idum1( 2 ) = ichar(
'L' )
288 idum1( 3 ) = ichar(
'N' )
290 idum1( 3 ) = ichar(
'U' )
293 IF( lwork.EQ.-1 )
THEN
299 IF( lrwork.EQ.-1 )
THEN
305 CALL pchk1mat( n, 4, n, 4, ia, ja, desca, 8, 5, idum1, idum2,
310 CALL pxerbla( ictxt,
'PCTRCON', -info )
312 ELSE IF( lquery )
THEN
323 CALL pb_topget( ictxt,
'Combine',
'Columnwise', colctop )
324 CALL pb_topget( ictxt,
'Combine',
'Rowwise', rowctop )
325 CALL pb_topset( ictxt,
'Combine',
'Columnwise',
'1-tree' )
326 CALL pb_topset( ictxt,
'Combine',
'Rowwise',
'1-tree' )
329 smlnum = pslamch( ictxt,
'Safe minimum' )*real(
max( 1, n ) )
330 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
332 iroff = mod( ia-1, desca( mb_ ) )
333 icoff = mod( ja-1, desca( nb_ ) )
334 np = numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
345 CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
346 $ ictxt,
max( 1, np ) )
347 CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
348 $ ictxt,
max( 1, np ) )
352 anorm = pclantr( norm, uplo, diag, n, n, a, ia, ja, desca, rwork )
356 IF( anorm.GT.zero )
THEN
369 CALL pclacon( n, work( ipv ), iv, jv, descv, work( ipx ),
370 $ ix, jx, descx, ainvnm, kase )
372 IF( kase.EQ.kase1 )
THEN
376 descx( csrc_ ) = iacol
377 CALL pclatrs( uplo,
'No transpose', diag, normin,
378 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
379 $ descx, scale, rwork( ipn ), work( ipw ) )
380 descx( csrc_ ) = mycol
385 descx( csrc_ ) = iacol
386 CALL pclatrs( uplo,
'Conjugate transpose', diag, normin,
387 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
388 $ descx, scale, rwork( ipn ), work( ipw ) )
389 descx( csrc_ ) = mycol
395 IF( scale.NE.one )
THEN
396 CALL pcamax( n, wmax, ixx, work( ipx ), ix, jx,
398 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 )
THEN
399 CALL pb_topget( ictxt,
'Broadcast',
'Columnwise',
401 IF( myrow.EQ.iarow )
THEN
402 CALL cgebs2d( ictxt,
'Column', cbtop, 1, 1, wmax,
405 CALL cgebr2d( ictxt,
'Column', cbtop, 1, 1, wmax,
409 IF( scale.LT.cabs1( wmax )*smlnum .OR. scale.EQ.zero )
411 CALL pcsrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
419 $ rcond = ( one / anorm ) / ainvnm
424 CALL pb_topset( ictxt,
'Combine',
'Columnwise', colctop )
425 CALL pb_topset( ictxt,
'Combine',
'Rowwise', rowctop )