1 SUBROUTINE pdgecon( NORM, N, A, IA, JA, DESCA, ANORM, RCOND, WORK,
2 $ LWORK, IWORK, LIWORK, INFO )
11 INTEGER IA, INFO, JA, LIWORK, LWORK, N
12 DOUBLE PRECISION ANORM, RCOND
15 INTEGER DESCA( * ), IWORK( * )
16 DOUBLE PRECISION A( * ), WORK( * )
175 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
176 $ lld_, mb_, m_, nb_, n_, rsrc_
177 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
178 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
179 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
180 DOUBLE PRECISION ONE, ZERO
181 parameter( one = 1.0d+0, zero = 0.0d+0 )
184 LOGICAL LQUERY, ONENRM
185 CHARACTER CBTOP, COLCTOP, NORMIN, ROWCTOP
186 INTEGER IACOL, IAROW, ICOFF, ICTXT, IIA, IPNL, IPNU,
187 $ ipv, ipw, ipx, iroff, iv, ix, ixx, jja, jv, jx,
188 $ kase, kase1, liwmin, lwmin, mycol, myrow, np,
189 $ npcol, npmod, nprow, nq, nqmod
190 DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU, WMAX
193 INTEGER DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 3 ),
204 INTEGER ICEIL, INDXG2P, NUMROC
205 DOUBLE PRECISION PDLAMCH
206 EXTERNAL iceil, indxg2p, lsame, numroc, pdlamch
209 INTRINSIC abs, dble, ichar,
max, mod
215 ictxt = desca( ctxt_ )
216 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
221 IF( nprow.EQ.-1 )
THEN
222 info = -( 600 + ctxt_ )
224 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
226 onenrm = norm.EQ.
'1' .OR. lsame( norm,
'O' )
227 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
229 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
231 npmod = numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
232 $ myrow, iarow, nprow )
233 nqmod = numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
234 $ mycol, iacol, npcol )
235 lwmin = 2*npmod + 2*nqmod +
236 $
max( 2,
max( desca( nb_ )*
237 $
max( 1, iceil( nprow-1, npcol ) ), nqmod +
239 $
max( 1, iceil( npcol-1, nprow ) ) ) )
240 work( 1 ) = dble( lwmin )
241 liwmin =
max( 1, npmod )
243 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
245 IF( .NOT.onenrm .AND. .NOT.lsame( norm,
'I' ) )
THEN
247 ELSE IF( anorm.LT.zero )
THEN
249 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
251 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
257 idum1( 1 ) = ichar(
'1' )
259 idum1( 1 ) = ichar(
'I' )
262 IF( lwork.EQ.-1 )
THEN
268 IF( liwork.EQ.-1 )
THEN
274 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 3, idum1, idum2,
279 CALL pxerbla( ictxt,
'PDGECON', -info )
281 ELSE IF( lquery )
THEN
291 ELSE IF( anorm.EQ.zero )
THEN
293 ELSE IF( n.EQ.1 )
THEN
298 CALL pb_topget( ictxt,
'Combine',
'Columnwise', colctop )
299 CALL pb_topget( ictxt,
'Combine',
'Rowwise', rowctop )
300 CALL pb_topset( ictxt,
'Combine',
'Columnwise',
'1-tree' )
301 CALL pb_topset( ictxt,
'Combine',
'Rowwise',
'1-tree' )
303 smlnum = pdlamch( ictxt,
'Safe minimum' )
304 iroff = mod( ia-1, desca( mb_ ) )
305 icoff = mod( ja-1, desca( nb_ ) )
306 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
308 np = numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
309 nq = numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
321 CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
322 $ ictxt,
max( 1, np ) )
323 CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
324 $ ictxt,
max( 1, np ) )
338 CALL pdlacon( n, work( ipv ), iv, jv, descv, work( ipx ), ix, jx,
339 $ descx, iwork, ainvnm, kase )
341 IF( kase.EQ.kase1 )
THEN
345 descx( csrc_ ) = iacol
346 CALL pdlatrs(
'Lower',
'No transpose',
'Unit', normin,
347 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
348 $ descx, sl, work( ipnl ), work( ipw ) )
349 descx( csrc_ ) = mycol
353 descx( csrc_ ) = iacol
354 CALL pdlatrs(
'Upper',
'No transpose',
'Non-unit', normin,
355 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
356 $ descx, su, work( ipnu ), work( ipw ) )
357 descx( csrc_ ) = mycol
362 descx( csrc_ ) = iacol
363 CALL pdlatrs(
'Upper',
'Transpose',
'Non-unit', normin,
364 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
365 $ descx, su, work( ipnu ), work( ipw ) )
366 descx( csrc_ ) = mycol
370 descx( csrc_ ) = iacol
371 CALL pdlatrs(
'Lower',
'Transpose',
'Unit', normin,
372 $ n, a, ia, ja, desca, work( ipx ), ix, jx,
373 $ descx, sl, work( ipnl ), work( ipw ) )
374 descx( csrc_ ) = mycol
381 IF( scale.NE.one )
THEN
382 CALL pdamax( n, wmax, ixx, work( ipx ), ix, jx, descx, 1 )
383 IF( descx( m_ ).EQ.1 .AND. n.EQ.1 )
THEN
384 CALL pb_topget( ictxt,
'Broadcast',
'Columnwise', cbtop )
385 IF( myrow.EQ.iarow )
THEN
386 CALL dgebs2d( ictxt,
'Column', cbtop, 1, 1, wmax, 1 )
388 CALL dgebr2d( ictxt,
'Column', cbtop, 1, 1, wmax, 1,
392 IF( scale.LT.abs( wmax )*smlnum .OR. scale.EQ.zero )
394 CALL pdrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
402 $ rcond = ( one / ainvnm ) / anorm
406 CALL pb_topset( ictxt,
'Combine',
'Columnwise', colctop )
407 CALL pb_topset( ictxt,
'Combine',
'Rowwise', rowctop )