Routine: PCTRTRI()  File: SRC\pctrtri.f

 
 
# lines: 353
  # code: 353
  # comment: 0
  # blank:0
# Variables:44
# Callers:2
# Callings:1
# Words:192
# Keywords:123
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PCTRTRI computes the inverse of a upper or lower triangular
  distributed matrix sub( A ) = A(IA:IA+N-1,JA:JA+N-1).
  Notes
  =====
  Each global data object is described by an associated description
  vector.  This vector stores the information required to establish
  the mapping between an object element and its corresponding process
  and memory location.
  Let A be a generic term for any 2D block cyclicly distributed array.
  Such a global array has an associated description vector DESCA.
  In the following comments, the character _ should be read as
  "of the global array".
  NOTATION        STORED IN      EXPLANATION
  --------------- -------------- --------------------------------------
  DTYPE_A(global) DESCA( DTYPE_ )The descriptor type.  In this case,
                                 DTYPE_A = 1.
  CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
                                 the BLACS process grid A is distribu-
                                 ted over. The context itself is glo-
                                 bal, but the handle (the integer
                                 value) may vary.
  M_A    (global) DESCA( M_ )    The number of rows in the global
                                 array A.
  N_A    (global) DESCA( N_ )    The number of columns in the global
                                 array A.
  MB_A   (global) DESCA( MB_ )   The blocking factor used to distribute
                                 the rows of the array.
  NB_A   (global) DESCA( NB_ )   The blocking factor used to distribute
                                 the columns of the array.
  RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
                                 row of the array A is distributed.
  CSRC_A (global) DESCA( CSRC_ ) The process column over which the
                                 first column of the array A is
                                 distributed.
  LLD_A  (local)  DESCA( LLD_ )  The leading dimension of the local
                                 array.  LLD_A >= MAX(1,LOCr(M_A)).
  Let K be the number of rows or columns of a distributed matrix,
  and assume that its process grid has dimension p x q.
  LOCr( K ) denotes the number of elements of K that a process
  would receive if K were distributed over the p processes of its
  process column.
  Similarly, LOCc( K ) denotes the number of elements of K that a
  process would receive if K were distributed over the q processes of
  its process row.
  The values of LOCr() and LOCc() may be determined via a call to the
  ScaLAPACK tool function, NUMROC:
          LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
          LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
  An upper bound for these quantities may be computed by:
          LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
          LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
  Arguments
  =========
  UPLO    (global input) CHARACTER
          Specifies whether the distributed matrix sub( A ) is upper
          or lower triangular:
          = 'U':  Upper triangular,
          = 'L':  Lower triangular.
  DIAG    (global input) CHARACTER
          Specifies whether or not the distributed matrix sub( A )
          is unit triangular:
          = 'N':  Non-unit triangular,
          = 'U':  Unit triangular.
  N       (global input) INTEGER
          The number of rows and columns to be operated on, i.e. the
          order of the distributed submatrix sub( A ). N >= 0.
  A       (local input/local output) COMPLEX pointer into the
          local memory to an array of dimension (LLD_A,LOCc(JA+N-1)).
          On entry, this array contains the local pieces of the
          triangular matrix sub( A ).  If UPLO = 'U', the leading
          N-by-N upper triangular part of the matrix sub( A ) contains
          the upper triangular matrix to be inverted, and the strictly
          lower triangular part of sub( A ) is not referenced.
          If UPLO = 'L', the leading N-by-N lower triangular part of
          the matrix sub( A ) contains the lower triangular matrix,
          and the strictly upper triangular part of sub( A ) is not
          referenced.
          On exit, the (triangular) inverse of the original matrix.
  IA      (global input) INTEGER
          The row index in the global array A indicating the first
          row of sub( A ).
  JA      (global input) INTEGER
          The column index in the global array A indicating the
          first column of sub( A ).
  DESCA   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix A.
  INFO    (global output) INTEGER
          = 0:  successful exit
          < 0:  If the i-th argument is an array and the j-entry had
                an illegal value, then INFO = -(i*100+j), if the i-th
                argument is a scalar and had an illegal value, then
                INFO = -i.
            > 0:  If INFO = K, A(IA+K-1,JA+K-1) is exactly zero.  The
                  triangular matrix sub( A ) is singular and its
                  inverse can not be computed.
  ====================================================================
     .. Parameters ..

 
Display dynamic version Find AutoScroll Reload FontSize: - + Hide Comments Hide Blanks Frame FullScreen MailPrint

 
001        SUBROUTINE PCTRTRI( UPLO , DIAG , N , A , IA , JA , DESCA , INFO )
002  
003  *     -- ScaLAPACK routine(version 1.7) --
004  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
005  *     and University of California , Berkeley.
006  *     May 1 , 1997
007  
008  *     .. Scalar Arguments ..
009        CHARACTER DIAG , UPLO
010        INTEGER IA , INFO , JA , N
011        INTEGER BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ ,
012       $LLD_ , MB_ , M_ , NB_ , N_ , RSRC_
013        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
014       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
015       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
016        COMPLEX ZERO , ONE
017        PARAMETER( ZERO = 0.0E + 0 , ONE = 1.0E + 0 )
018  *     ..
019  *     .. Local Scalars ..
020        LOGICAL NOUNIT , UPPER
021        INTEGER I , ICOFF , ICTXT , IROFF , ICURCOL , ICURROW ,
022       $IDUMMY , II , IOFFA , J , JB , JJ , JN , LDA , MYCOL ,
023       $MYROW , NN , NPCOL , NPROW
024  *     ..
025  *     .. Local Arrays ..
026        INTEGER IDUM1( 2 ) , IDUM2( 2 )
027  *     ..
028  *     .. External Subroutines ..
029        EXTERNAL BLACS_GRIDINFO , CHK1MAT , IGAMX2D , INFOG2L ,
030       $PCHK1MAT , PCTRTI2 , PCTRMM , PCTRSM ,
031       $PXERBLA
032  *     ..
033  *     .. External Functions ..
034        LOGICAL LSAME
035        INTEGER ICEIL
036        EXTERNAL ICEIL , LSAME
037  *     ..
038  *     .. Intrinsic Functions ..
039        INTRINSIC ICHAR , MIN , MOD
040  *     ..
041  *     .. Executable Statements ..
042  
043  *     Get grid parameters
044  
045        ICTXT = DESCA( CTXT_ )
046        CALL BLACS_GRIDINFO( ICTXT , NPROW , NPCOL , MYROW , MYCOL )
047  
048  *     Test input parameters
049  
050        INFO = 0
051        IF( NPROW.EQ. - 1 ) THEN
052            INFO = - (700 + CTXT_)
053        ELSE
054            UPPER = LSAME( UPLO , 'U' )
055            NOUNIT = LSAME( DIAG , 'N' )
056  
057            CALL CHK1MAT( N , 3 , N , 3 , IA , JA , DESCA , 7 , INFO )
058            IF( INFO.EQ.0 ) THEN
059                IROFF = MOD( IA - 1 , DESCA( MB_ ) )
060                ICOFF = MOD( JA - 1 , DESCA( NB_ ) )
061                IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO , 'L' ) ) THEN
062                    INFO = - 1
063                ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG , 'U' ) ) THEN
064                    INFO = - 2
065                ELSE IF( IROFF.NE.ICOFF .OR. IROFF.NE.0 ) THEN
066                    INFO = - 6
067                ELSE IF( DESCA( MB_ ).NE.DESCA( NB_ ) ) THEN
068                    INFO = - (700 + NB_)
069                END IF
070            END IF
071  
072            IF( UPPER ) THEN
073                IDUM1( 1 ) = ICHAR( 'U' )
074            ELSE
075                IDUM1( 1 ) = ICHAR( 'L' )
076            END IF
077            IDUM2( 1 ) = 1
078            IF( NOUNIT ) THEN
079                IDUM1( 2 ) = ICHAR( 'N' )
080            ELSE
081                IDUM1( 2 ) = ICHAR( 'U' )
082            END IF
083            IDUM2( 2 ) = 2
084  
085            CALL PCHK1MAT( N , 3 , N , 3 , IA , JA , DESCA , 7 , 2 , IDUM1 , IDUM2 ,
086       $    INFO )
087        END IF
088  
089        IF( INFO.NE.0 ) THEN
090            CALL PXERBLA( ICTXT , 'PCTRTRI' , - INFO )
091            RETURN
092        END IF
093  
094  *     Quick return if possible
095  
096        IF( N.EQ.0 )
097       $    RETURN
098  
099  *         Check for singularity if non - unit.
100  
101            JN = MIN( ICEIL( JA , DESCA( NB_ ) ) * DESCA( NB_ ) , JA + N - 1 )
102            IF( NOUNIT ) THEN
103                CALL INFOG2L( IA , JA , DESCA , NPROW , NPCOL , MYROW , MYCOL ,
104       $        II , JJ , ICURROW , ICURCOL )
105  
106  *             Handle first block separately
107  
108                JB = JN - JA + 1
109                LDA = DESCA( LLD_ )
110                IF( MYROW.EQ.ICURROW .AND. MYCOL.EQ.ICURCOL ) THEN
111                    IOFFA = II + (JJ - 1)*LDA
112                    DO 10 I = 0 , JB - 1
113                        IF( A( IOFFA ).EQ.ZERO .AND. INFO.EQ.0 )
114       $                    INFO = I + 1
115                            IOFFA = IOFFA + LDA + 1
116     10             CONTINUE
117                END IF
118                IF( MYROW.EQ.ICURROW )
119       $            II = II + JB
120                    IF( MYCOL.EQ.ICURCOL )
121       $                JJ = JJ + JB
122                        ICURROW = MOD( ICURROW + 1 , NPROW )
123                        ICURCOL = MOD( ICURCOL + 1 , NPCOL )
124  
125  *                     Loop over remaining blocks of columns
126  
127                        DO 30 J = JN + 1 , JA + N - 1 , DESCA( NB_ )
128                            JB = MIN( JA + N - J , DESCA( NB_ ) )
129                            IF( MYROW.EQ.ICURROW .AND. MYCOL.EQ.ICURCOL ) THEN
130                                IOFFA = II + (JJ - 1)*LDA
131                                DO 20 I = 0 , JB - 1
132                                    IF( A( IOFFA ).EQ.ZERO .AND. INFO.EQ.0 )
133       $                                INFO = J + I - JA + 1
134                                        IOFFA = IOFFA + LDA + 1
135     20                         CONTINUE
136                            END IF
137                            IF( MYROW.EQ.ICURROW )
138       $                        II = II + JB
139                                IF( MYCOL.EQ.ICURCOL )
140       $                            JJ = JJ + JB
141                                    ICURROW = MOD( ICURROW + 1 , NPROW )
142                                    ICURCOL = MOD( ICURCOL + 1 , NPCOL )
143     30                 CONTINUE
144                        CALL IGAMX2D( ICTXT , 'All' , ' ' , 1 , 1 , INFO , 1 , IDUMMY ,
145       $                IDUMMY , - 1 , - 1 , MYCOL )
146                        IF( INFO.NE.0 )
147       $                    RETURN
148                        END IF
149  
150  *                     Use blocked code
151  
152                        IF( UPPER ) THEN
153  
154  *                         Compute inverse of upper triangular matrix
155  
156                            JB = JN - JA + 1
157  
158  *                         Handle first block of column separately
159  
160                            CALL PCTRTI2 ( UPLO , DIAG , JB , A , IA , JA , DESCA , INFO )
161  
162  *                         Loop over remaining block of columns
163  
164                            DO 40 J = JN + 1 , JA + N - 1 , DESCA( NB_ )
165                                JB = MIN( DESCA( NB_ ) , JA + N - J )
166                                I = IA + J - JA
167  
168  *                             Compute rows 1 : j - 1 of current block column
169  
170                                CALL PCTRMM( 'Left' , UPLO , 'No transpose' , DIAG , J - JA , JB ,
171       $                        ONE , A , IA , JA , DESCA , A , IA , J , DESCA )
172                                CALL PCTRSM( 'Right' , UPLO , 'No transpose' , DIAG , J - JA ,
173       $                        JB , - ONE , A , I , J , DESCA , A , IA , J , DESCA )
174  
175  *                             Compute inverse of current diagonal block
176  
177                                CALL PCTRTI2 ( UPLO , DIAG , JB , A , I , J , DESCA , INFO )
178  
179     40                     CONTINUE
180  
181                        ELSE
182  
183  *                         Compute inverse of lower triangular matrix
184  
185                            NN =(( JA + N - 2 ) / DESCA( NB_ ) )*DESCA( NB_ ) + 1
186                            DO 50 J = NN , JN + 1 , - DESCA( NB_ )
187                                JB = MIN( DESCA( NB_ ) , JA + N - J )
188                                I = IA + J - JA
189                                IF( J + JB.LE.JA + N - 1 ) THEN
190  
191  *                                 Compute rows j + jb : ja + n - 1 of current block column
192  
193                                    CALL PCTRMM( 'Left' , UPLO , 'No transpose' , DIAG ,
194       $                            JA + N - J - JB , JB , ONE , A , I + JB , J + JB , DESCA ,
195       $                            A , I + JB , J , DESCA )
196                                    CALL PCTRSM( 'Right' , UPLO , 'No transpose' , DIAG ,
197       $                            JA + N - J - JB , JB , - ONE , A , I , J , DESCA ,
198       $                            A , I + JB , J , DESCA )
199                                END IF
200  
201  *                             Compute inverse of current diagonal block
202  
203                                CALL PCTRTI2 ( UPLO , DIAG , JB , A , I , J , DESCA , INFO )
204  
205     50                     CONTINUE
206  
207  *                         Handle the last block of columns separately
208  
209                            JB = JN - JA + 1
210                            IF( JA + JB.LE.JA + N - 1 ) THEN
211  
212  *                             Compute rows ja + jb : ja + n - 1 of current block column
213  
214                                CALL PCTRMM( 'Left' , UPLO , 'No transpose' , DIAG , N - JB , JB ,
215       $                        ONE , A , IA + JB , JA + JB , DESCA , A , IA + JB , JA ,
216       $                        DESCA )
217                                CALL PCTRSM( 'Right' , UPLO , 'No transpose' , DIAG , N - JB , JB ,
218       $                        - ONE , A , IA , JA , DESCA , A , IA + JB , JA , DESCA )
219                            END IF
220  
221  *                         Compute inverse of current diagonal block
222  
223                            CALL PCTRTI2 ( UPLO , DIAG , JB , A , IA , JA , DESCA , INFO )
224  
225                        END IF
226  
227                        RETURN
228  
229  *                     End PCTRTRI
230  
231                    END