1 SUBROUTINE pztrcon( 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
13 DOUBLE PRECISION RCOND
17 DOUBLE PRECISION RWORK( * )
18 COMPLEX*16 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 )
187 DOUBLE PRECISION ONE, ZERO
188 parameter( one = 1.0d+0, zero = 0.0d+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 DOUBLE PRECISION AINVNM, ANORM, SCALE, SMLNUM
198 COMPLEX*16 WMAX, ZDUM
201 INTEGER DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 5 ),
212 INTEGER ICEIL, INDXG2P, NUMROC
213 DOUBLE PRECISION PDLAMCH, PZLANTR
214 EXTERNAL iceil, indxg2p, lsame, numroc, pdlamch,
218 INTRINSIC abs, dble, dimag, ichar,
max, mod
221 DOUBLE PRECISION CABS1
224 cabs1( zdum ) = abs( dble( zdum ) ) + abs( dimag( 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 ) = dble( lwmin )
259 rwork( 1 ) = dble( 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,
'PZTRCON', -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 = pdlamch( ictxt,
'Safe minimum' )*dble(
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 = pzlantr( norm, uplo, diag, n, n, a, ia, ja, desca, rwork )
356 IF( anorm.GT.zero )
THEN
369 CALL pzlacon( 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 pzlatrs( 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 pzlatrs( 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 pzamax( 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 zgebs2d( ictxt,
'Column', cbtop, 1, 1, wmax,
405 CALL zgebr2d( ictxt,
'Column', cbtop, 1, 1, wmax,
409 IF( scale.LT.cabs1( wmax )*smlnum .OR. scale.EQ.zero )
411 CALL pzdrscl( 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 )