3
    4
    5
    6
    7
    8
    9
   10
   11      CHARACTER          DIAG, NORM, UPLO
   12      INTEGER            IA, JA, INFO, LIWORK, LWORK, N
   13      DOUBLE PRECISION   RCOND
   14
   15
   16      INTEGER            DESCA( * ), IWORK( * )
   17      DOUBLE PRECISION   A( * ), WORK( * )
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  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 )
  189
  190
  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, LIWMIN, LWMIN, MYCOL, MYROW, NP, NPCOL,
  196     $                   NPMOD, NPROW, NQ, NQMOD
  197      DOUBLE PRECISION   AINVNM, ANORM, SCALE, SMLNUM
  198      DOUBLE PRECISION   WMAX
  199
  200
  201      INTEGER            DESCV( DLEN_ ), DESCX( DLEN_ ), IDUM1( 5 ),
  202     $                   IDUM2( 5 )
  203
  204
  209
  210
  211      LOGICAL            LSAME
  212      INTEGER            ICEIL, INDXG2P, NUMROC
  213      DOUBLE PRECISION   PDLAMCH, PDLANTR
  216
  217
  218      INTRINSIC          abs, dble, ichar, 
max, mod
 
  219
  220
  221
  222
  223
  224      ictxt = desca( ctxt_ )
  225      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  226
  227
  228
  229      info = 0
  230      IF( nprow.EQ.-1 ) THEN
  231         info = -( 800 + ctxt_ )
  232      ELSE
  233         CALL chk1mat( n, 4, n, 4, ia, ja, desca, 8, info )
 
  234         IF( info.EQ.0 ) THEN
  235            upper = 
lsame( uplo, 
'U' )
 
  236            onenrm = norm.EQ.
'1' .OR. 
lsame( norm, 
'O' )
 
  237            nounit = 
lsame( diag, 
'N' )
 
  238            iarow = 
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
 
  239     $                       nprow )
  240            iacol = 
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
 
  241     $                       npcol )
  242            npmod = 
numroc( n + mod( ia-1, desca( mb_ ) ), desca( mb_ ),
 
  243     $                      myrow, iarow, nprow )
  244            nqmod = 
numroc( n + mod( ja-1, desca( nb_ ) ), desca( nb_ ),
 
  245     $                      mycol, iacol, npcol )
  246            lwmin = 2*npmod + nqmod +
  247     $              
max( 2, 
max( desca( nb_ )*
 
  248     $                   
max( 1, 
iceil( nprow-1, npcol ) ), nqmod +
 
  249     $                   desca( nb_ )*
  250     $                   
max( 1, 
iceil( npcol-1, nprow ) ) ) )
 
  251            work( 1 ) = dble( lwmin )
  252            liwmin = npmod
  253            iwork( 1 ) = liwmin
  254            lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
  255
  256            IF( .NOT.onenrm .AND. .NOT.
lsame( norm, 
'I' ) ) 
THEN 
  257               info = -1
  258            ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo, 
'L' ) ) 
THEN 
  259               info = -2
  260            ELSE IF( .NOT.nounit .AND. .NOT.
lsame( diag, 
'U' ) ) 
THEN 
  261               info = -3
  262            ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
  263               info = -11
  264            ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
  265               info = -13
  266            END IF
  267         END IF
  268
  269         IF( onenrm ) THEN
  270            idum1( 1 ) = ichar( '1' )
  271         ELSE
  272            idum1( 1 ) = ichar( 'I' )
  273         END IF
  274         idum2( 1 ) = 1
  275         IF( upper ) THEN
  276            idum1( 2 ) = ichar( 'U' )
  277         ELSE
  278            idum1( 2 ) = ichar( 'L' )
  279         END IF
  280         idum2( 2 ) = 2
  281         IF( nounit ) THEN
  282            idum1( 3 ) = ichar( 'N' )
  283         ELSE
  284            idum1( 3 ) = ichar( 'U' )
  285         END IF
  286         idum2( 3 ) = 3
  287         IF( lwork.EQ.-1 ) THEN
  288            idum1( 4 ) = -1
  289         ELSE
  290            idum1( 4 ) = 1
  291         END IF
  292         idum2( 4 ) = 11
  293         IF( liwork.EQ.-1 ) THEN
  294            idum1( 5 ) = -1
  295         ELSE
  296            idum1( 5 ) = 1
  297         END IF
  298         idum2( 5 ) = 13
  299         CALL pchk1mat( n, 4, n, 4, ia, ja, desca, 8, 5, idum1, idum2,
 
  300     $                  info )
  301      END IF
  302
  303      IF( info.NE.0 ) THEN
  304         CALL pxerbla( ictxt, 
'PDTRCON', -info )
 
  305         RETURN
  306      ELSE IF( lquery ) THEN
  307         RETURN
  308      END IF
  309
  310
  311
  312      IF( n.EQ.0 ) THEN
  313         rcond = one
  314         RETURN
  315      END IF
  316
  317      CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
  318      CALL pb_topget( ictxt, 'Combine', 'Rowwise',    rowctop )
  319      CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
  320      CALL pb_topset( ictxt, 'Combine', 'Rowwise',    '1-tree' )
  321
  322      rcond = zero
  323      smlnum = 
pdlamch( ictxt, 
'Safe minimum' )*dble( 
max( 1, n ) )
 
  324      CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
 
  325     $              iarow, iacol )
  326      iroff = mod( ia-1, desca( mb_ ) )
  327      icoff = mod( ja-1, desca( nb_ ) )
  328      np = 
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
 
  329      nq = 
numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
 
  330      iv = iroff + 1
  331      ix = iv
  332      jv = icoff + 1
  333      jx = jv
  334
  335      ipx  = 1
  336      ipv  = ipx + np
  337      ipn = ipv + np
  338      ipw  = ipn + nq
  339
  340      CALL descset( descv, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
 
  341     $              ictxt, 
max( 1, np ) )
 
  342      CALL descset( descx, n+iroff, 1, desca( mb_ ), 1, iarow, mycol,
 
  343     $              ictxt, 
max( 1, np ) )
 
  344
  345
  346
  347      anorm = 
pdlantr( norm, uplo, diag, n, n, a, ia, ja, desca, work )
 
  348
  349
  350
  351      IF( anorm.GT.zero ) THEN
  352
  353
  354
  355         ainvnm = zero
  356         normin = 'N'
  357         IF( onenrm ) THEN
  358            kase1 = 1
  359         ELSE
  360            kase1 = 2
  361         END IF
  362         kase = 0
  363   10    CONTINUE
  364         CALL pdlacon( n, work( ipv ), iv, jv, descv, work( ipx ),
 
  365     $                 ix, jx, descx, iwork, ainvnm, kase )
  366         IF( kase.NE.0 ) THEN
  367            IF( kase.EQ.kase1 ) THEN
  368
  369
  370
  371               descx( csrc_ ) = iacol
  372               CALL pdlatrs( uplo, 
'No transpose', diag, normin,
 
  373     $                       n, a, ia, ja, desca, work( ipx ), ix, jx,
  374     $                       descx, scale, work( ipn ), work( ipw ) )
  375               descx( csrc_ ) = mycol
  376            ELSE
  377
  378
  379
  380               descx( csrc_ ) = iacol
  381               CALL pdlatrs( uplo, 
'Transpose', diag, normin,
 
  382     $                       n, a, ia, ja, desca, work( ipx ), ix, jx,
  383     $                       descx, scale, work( ipn ), work( ipw ) )
  384               descx( csrc_ ) = mycol
  385            END IF
  386            normin = 'Y'
  387
  388
  389
  390            IF( scale.NE.one ) THEN
  391               CALL pdamax( n, wmax, ixx, work( ipx ), ix, jx,
  392     $                   descx, 1 )
  393               IF( descx( m_ ).EQ.1 .AND. n.EQ.1 ) THEN
  394                  CALL pb_topget( ictxt, 'Broadcast', 'Columnwise',
  395     $                          cbtop )
  396                  IF( myrow.EQ.iarow ) THEN
  397                     CALL dgebs2d( ictxt, 'Column', cbtop, 1, 1, wmax,
  398     $                             1 )
  399                  ELSE
  400                     CALL dgebr2d( ictxt, 'Column', cbtop, 1, 1, wmax,
  401     $                             1, iarow, mycol )
  402                  END IF
  403               END IF
  404               IF( scale.LT.abs( wmax )*smlnum .OR. scale.EQ.zero )
  405     $            GO TO 20
  406               CALL pdrscl( n, scale, work( ipx ), ix, jx, descx, 1 )
 
  407            END IF
  408            GO TO 10
  409         END IF
  410
  411
  412
  413         IF( ainvnm.NE.zero )
  414     $      rcond = ( one / anorm ) / ainvnm
  415      END IF
  416
  417   20 CONTINUE
  418
  419      CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
  420      CALL pb_topset( ictxt, 'Combine', 'Rowwise',    rowctop )
  421
  422      RETURN
  423
  424
  425
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
 
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
 
integer function iceil(inum, idenom)
 
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
 
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
 
integer function numroc(n, nb, iproc, isrcproc, nprocs)
 
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
 
double precision function pdlamch(ictxt, cmach)
 
subroutine pdlacon(n, v, iv, jv, descv, x, ix, jx, descx, isgn, est, kase)
 
double precision function pdlantr(norm, uplo, diag, m, n, a, ia, ja, desca, work)
 
subroutine pdlatrs(uplo, trans, diag, normin, n, a, ia, ja, desca, x, ix, jx, descx, scale, cnorm, work)
 
subroutine pdrscl(n, sa, sx, ix, jx, descx, incx)
 
subroutine pxerbla(ictxt, srname, info)