1 SUBROUTINE pcposvx( FACT, UPLO, N, NRHS, A, IA, JA, DESCA, AF,
2 $ IAF, JAF, DESCAF, EQUED, SR, SC, B, IB, JB,
3 $ DESCB, X, IX, JX, DESCX, RCOND, FERR, BERR,
4 $ WORK, LWORK, RWORK, LRWORK, INFO )
12 CHARACTER EQUED, FACT, UPLO
13 INTEGER IA, IAF, IB, INFO, IX, JA, JAF, JB, JX, LRWORK,
18 INTEGER DESCA( * ), DESCAF( * ), DESCB( * ), DESCX( * )
19 REAL BERR( * ), FERR( * ), SC( * ),
21 COMPLEX A( * ), AF( * ),
22 $ b( * ), work( * ), x( * )
352 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
353 $ LLD_, MB_, M_, NB_, N_, RSRC_
354 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dtype_ = 1,
355 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
356 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
358 PARAMETER ( ONE = 1.0e+0, zero = 0.0e+0 )
361 LOGICAL EQUIL, LQUERY, NOFACT, RCEQU
362 INTEGER I, IACOL, IAROW, IAFROW, IBROW, IBCOL, ICOFF,
363 $ ICOFFA, ICTXT, IDUMM, IIA, IIB, IIX, INFEQU,
364 $ iroff, iroffa, iroffaf, iroffb, iroffx, ixcol,
365 $ ixrow, j, jja, jjb, jjx, ldb, ldx, lrwmin,
366 $ lwmin, mycol, myrow, np, npcol, nprow, nrhsq,
368 REAL AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
371 INTEGER IDUM1( 5 ), IDUM2( 5 )
382 INTEGER INDXG2P, NUMROC
383 REAL PCLANHE, PSLAMCH
384 EXTERNAL indxg2p, lsame, numroc, pclanhe, pslamch
387 INTRINSIC ichar,
max,
min, mod
393 ictxt = desca( ctxt_ )
394 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
399 IF( nprow.EQ.-1 )
THEN
402 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 8, info )
403 IF( lsame( fact,
'F' ) )
404 $
CALL chk1mat( n, 3, n, 3, iaf, jaf, descaf, 12, info )
405 CALL chk1mat( n, 3, nrhs, 4, ib, jb, descb, 20, info )
407 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
409 iafrow = indxg2p( iaf, descaf( mb_ ), myrow,
410 $ descaf( rsrc_ ), nprow )
411 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
413 ixrow = indxg2p( ix, descx( mb_ ), myrow, descx( rsrc_ ),
415 iroffa = mod( ia-1, desca( mb_ ) )
416 iroffaf = mod( iaf-1, descaf( mb_ ) )
417 icoffa = mod( ja-1, desca( nb_ ) )
418 iroffb = mod( ib-1, descb( mb_ ) )
419 iroffx = mod( ix-1, descx( mb_ ) )
420 CALL infog2l( ia, ja, desca, nprow, npcol, myrow,
421 $ mycol, iia, jja, iarow, iacol )
422 np = numroc( n+iroffa, desca( mb_ ), myrow, iarow, nprow )
425 nq = numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
428 lwmin = 3*desca( lld_ )
429 lrwmin =
max( 2*nq, np )
430 nofact = lsame( fact,
'N' )
431 equil = lsame( fact,
'E' )
432 IF( nofact .OR. equil )
THEN
436 rcequ = lsame( equed,
'Y' )
437 smlnum = pslamch( ictxt,
'Safe minimum' )
438 bignum = one / smlnum
440 IF( .NOT.nofact .AND. .NOT.equil .AND.
441 $ .NOT.lsame( fact,
'F' ) )
THEN
443 ELSE IF( .NOT.lsame( uplo,
'U' ) .AND.
444 $ .NOT.lsame( uplo,
'L' ) )
THEN
446 ELSE IF( iroffa.NE.0 )
THEN
448 ELSE IF( icoffa.NE.0 .OR. iroffa.NE.icoffa )
THEN
450 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
452 ELSE IF( iafrow.NE.iarow )
THEN
454 ELSE IF( iroffaf.NE.0 )
THEN
456 ELSE IF( ictxt.NE.descaf( ctxt_ ) )
THEN
458 ELSE IF( lsame( fact,
'F' ) .AND. .NOT.
459 $ ( rcequ .OR. lsame( equed,
'N' ) ) )
THEN
466 DO 10 j = iia, iia + np - 1
467 smin =
min( smin, sr( j ) )
468 smax =
max( smax, sr( j ) )
470 CALL sgamn2d( ictxt,
'Columnwise',
' ', 1, 1, smin,
471 $ 1, idumm, idumm, -1, -1, mycol )
472 CALL sgamx2d( ictxt,
'Columnwise',
' ', 1, 1, smax,
473 $ 1, idumm, idumm, -1, -1, mycol )
474 IF( smin.LE.zero )
THEN
476 ELSE IF( n.GT.0 )
THEN
477 scond =
max( smin, smlnum ) /
min( smax, bignum )
485 work( 1 ) = real( lwmin )
486 rwork( 1 ) = real( lrwmin )
487 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
489 IF( ibrow.NE.iarow )
THEN
491 ELSE IF( ixrow.NE.ibrow )
THEN
493 ELSE IF( descb( mb_ ).NE.desca( nb_ ) )
THEN
495 ELSE IF( ictxt.NE.descb( ctxt_ ) )
THEN
497 ELSE IF( ictxt.NE.descx( ctxt_ ) )
THEN
499 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
501 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery )
THEN
504 idum1( 1 ) = ichar( fact )
506 idum1( 2 ) = ichar( uplo )
508 IF( lsame( fact,
'F' ) )
THEN
509 idum1( 3 ) = ichar( equed )
511 IF( lwork.EQ.-1 )
THEN
517 IF( lrwork.EQ.-1 )
THEN
523 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 8, n, 3, nrhs,
524 $ 4, ib, jb, descb, 19, 5, idum1, idum2,
527 IF( lwork.EQ.-1 )
THEN
533 IF( lrwork.EQ.-1 )
THEN
539 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 8, n, 3, nrhs,
540 $ 4, ib, jb, descb, 19, 4, idum1, idum2,
547 CALL pxerbla( ictxt,
'PCPOSVX', -info )
549 ELSE IF( lquery )
THEN
557 CALL pcpoequ( n, a, ia, ja, desca, sr, sc, scond, amax,
560 IF( infequ.EQ.0 )
THEN
564 CALL pclaqsy( uplo, n, a, ia, ja, desca, sr, sc, scond,
566 rcequ = lsame( equed,
'Y' )
572 CALL infog2l( ib, jb, descb, nprow, npcol, myrow, mycol, iib,
573 $ jjb, ibrow, ibcol )
575 iroff = mod( ib-1, descb( mb_ ) )
576 icoff = mod( jb-1, descb( nb_ ) )
577 np = numroc( n+iroff, descb( mb_ ), myrow, ibrow, nprow )
578 nrhsq = numroc( nrhs+icoff, descb( nb_ ), mycol, ibcol, npcol )
579 IF( myrow.EQ.ibrow ) np = np-iroff
580 IF( mycol.EQ.ibcol ) nrhsq = nrhsq-icoff
583 DO 30 j = jjb, jjb+nrhsq-1
584 DO 20 i = iib, iib+np-1
585 b( i + ( j-1 )*ldb ) = sr( i )*b( i + ( j-1 )*ldb )
590 IF( nofact .OR. equil )
THEN
594 CALL pclacpy(
'Full', n, n, a, ia, ja, desca, af, iaf, jaf,
596 CALL pcpotrf( uplo, n, af, iaf, jaf, descaf, info )
609 anorm = pclanhe(
'1', uplo, n, a, ia, ja, desca, rwork )
613 CALL pcpocon( uplo, n, af, iaf, jaf, descaf, anorm, rcond, work,
614 $ lwork, rwork, lrwork, info )
618 IF( rcond.LT.pslamch( ictxt,
'Epsilon' ) )
THEN
625 CALL pclacpy(
'Full', n, nrhs, b, ib, jb, descb, x, ix, jx,
627 CALL pcpotrs( uplo, n, nrhs, af, iaf, jaf, descaf, x, ix, jx,
633 CALL pcporfs( uplo, n, nrhs, a, ia, ja, desca, af, iaf, jaf,
634 $ descaf, b, ib, jb, descb, x, ix, jx, descx, ferr,
635 $ berr, work, lwork, rwork, lrwork, info )
640 CALL infog2l( ix, jx, descx, nprow, npcol, myrow, mycol, iix,
641 $ jjx, ixrow, ixcol )
643 iroff = mod( ix-1, descx( mb_ ) )
644 icoff = mod( jx-1, descx( nb_ ) )
645 np = numroc( n+iroff, descx( mb_ ), myrow, ixrow, nprow )
646 nrhsq = numroc( nrhs+icoff, descx( nb_ ), mycol, ixcol, npcol )
647 IF( myrow.EQ.ibrow ) np = np-iroff
648 IF( mycol.EQ.ibcol ) nrhsq = nrhsq-icoff
651 DO 50 j = jjx, jjx+nrhsq-1
652 DO 40 i = iix, iix+np-1
653 x( i + ( j-1 )*ldx ) = sr( i )*x( i + ( j-1 )*ldx )
656 DO 60 j = jjx, jjx+nrhsq-1
657 ferr( j ) = ferr( j ) / scond
661 work( 1 ) = real( lwmin )
662 rwork( 1 ) = real( lrwmin )