1 SUBROUTINE pzposvx( 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,
15 DOUBLE PRECISION RCOND
18 INTEGER DESCA( * ), DESCAF( * ), DESCB( * ), DESCX( * )
19 DOUBLE PRECISION BERR( * ), FERR( * ), SC( * ),
21 COMPLEX*16 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 )
357 DOUBLE PRECISION ONE, ZERO
358 PARAMETER ( ONE = 1.0d+0, zero = 0.0d+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 DOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
371 INTEGER IDUM1( 5 ), IDUM2( 5 )
382 INTEGER INDXG2P, NUMROC
383 DOUBLE PRECISION PDLAMCH, PZLANHE
384 EXTERNAL pdlamch, indxg2p, lsame, numroc, pzlanhe
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 = pdlamch( 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 dgamn2d( ictxt,
'Columnwise',
' ', 1, 1, smin,
471 $ 1, idumm, idumm, -1, -1, mycol )
472 CALL dgamx2d( 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 ) = dble( lwmin )
486 rwork( 1 ) = dble( 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,
'PZPOSVX', -info )
549 ELSE IF( lquery )
THEN
557 CALL pzpoequ( n, a, ia, ja, desca, sr, sc, scond, amax,
560 IF( infequ.EQ.0 )
THEN
564 CALL pzlaqsy( 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 pzlacpy(
'Full', n, n, a, ia, ja, desca, af, iaf, jaf,
596 CALL pzpotrf( uplo, n, af, iaf, jaf, descaf, info )
609 anorm = pzlanhe(
'1', uplo, n, a, ia, ja, desca, rwork )
613 CALL pzpocon( uplo, n, af, iaf, jaf, descaf, anorm, rcond, work,
614 $ lwork, rwork, lrwork, info )
618 IF( rcond.LT.pdlamch( ictxt,
'Epsilon' ) )
THEN
625 CALL pzlacpy(
'Full', n, nrhs, b, ib, jb, descb, x, ix, jx,
627 CALL pzpotrs( uplo, n, nrhs, af, iaf, jaf, descaf, x, ix, jx,
633 CALL pzporfs( 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 ) = dble( lwmin )
662 rwork( 1 ) = dble( lrwmin )