Routine: PZLANSY()  File: SRC\pzlansy.f

 
 
# lines: 836
  # code: 836
  # comment: 0
  # blank:0
# Variables:37
# Callers:0
# Callings:0
# Words:403
# Keywords:164
 

 

..
     .. Local Scalars ..
     ..
     .. Local Arrays ..
     ..
     .. External Subroutines ..
     ..
     .. External Functions ..
     ..
     .. Intrinsic Functions ..
     ..
     .. Executable Statements ..
     Get grid parameters and local indexes.
     If the matrix is symmetric, we address only a triangular portion
     of the matrix.  A sum of row (column) i of the complete matrix
     can be obtained by adding along row i and column i of the the
     triangular matrix, stopping/starting at the diagonal, which is
     the point of reflection.  The pictures below demonstrate this.
     In the following code, the row sums created by --- rows below are
     refered to as ROWSUMS, and the column sums shown by | are refered
     to as COLSUMS. Infinity-norm = 1-norm = ROWSUMS+COLSUMS.
      UPLO = 'U'                        UPLO = 'L'
      ____i______                       ___________
     |\   |      |                     |\          |
     | \  |      |                     | \         |
     |  \ |      |                     |  \        |
     |   \|------| i                  i|---\       |
     |    \      |                     |   |\      |
     |     \     |                     |   | \     |
     |      \    |                     |   |  \    |
     |       \   |                     |   |   \   |
     |        \  |                     |   |    \  |
     |         \ |                     |   |     \ |
     |__________\|                     |___|______\|
                                           i
     II, JJ  : local indices into array A
     ICURROW : process row containing diagonal block
     ICURCOL : process column containing diagonal block
     IRSC0   : pointer to part of work used to store the ROWSUMS while
               they are stored along a process column
     IRSR0   : pointer to part of work used to store the ROWSUMS after
               they have been transposed to be along a process row
        Find max(abs(A(i,j))).
           Handle first block separately
           Find COLMAXS
              Reset local indices so we can find ROWMAXS
           Find ROWMAXS
           Loop over the remaining rows/columns of the matrix.
              Find COLMAXS
                 Reset local indices so we can find ROWMAXS
              Find ROWMAXS
           Handle first block separately
           Find COLMAXS
              Reset local indices so we can find ROWMAXS
           Find ROWMAXS
           Loop over rows/columns of global matrix.
              Find COLMAXS
                 Reset local indices so we can find ROWMAXS
              Find ROWMAXS
        Gather the result on process (IAROW,IACOL).
        Find normI( sub( A ) ) ( = norm1( sub( A ) ), since sub( A ) is
        symmetric).
           Handle first block separately
           Find COLSUMS
              Reset local indices so we can find ROWSUMS
           Find ROWSUMS
           Loop over remaining rows/columns of global matrix.
              Find COLSUMS
                 Reset local indices so we can find ROWSUMS
              Find ROWSUMS
           Handle first block separately

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

 
001        DOUBLE PRECISION FUNCTION PZLANSY( NORM , UPLO , N , A , IA , JA ,
002       $DESCA , WORK )
003  
004  *     -- ScaLAPACK auxiliary routine(version 1.7) --
005  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006  *     and University of California , Berkeley.
007  *     May 1 , 1997
008  
009  *     .. Scalar Arguments ..
010        CHARACTER NORM , UPLO
011        INTEGER IA , JA , N
012  *     ..
013  *     .. Array Arguments ..
014        INTEGER DESCA( * )
015        DOUBLE PRECISION WORK( * )
016        COMPLEX*16 A( * )
017  *     ..
018  
019  *     Purpose
020  *     === ====
021  
022  *     PZLANSY returns the value of the one norm , or the Frobenius norm ,
023  *     or the infinity norm , or the element of largest absolute value of a
024  *     real symmetric distributed matrix sub( A ) = A(IA : IA + N - 1 , JA : JA + N - 1).
025  
026  *     PZLANSY returns the value
027  
028  *     ( max(abs(A(i , j))) , NORM = 'M' or 'm' with IA <= i <= IA + N - 1 ,
029  *     ( and JA <= j <= JA + N - 1 ,
030  *     (
031  *     ( norm1( sub( A ) ) , NORM = '1' , 'O' or 'o'
032  *     (
033  *     ( normI( sub( A ) ) , NORM = 'I' or 'i'
034  *     (
035  *     ( normF( sub( A ) ) , NORM = 'F' , 'f' , 'E' or 'e'
036  
037  *     where norm1 denotes the one norm of a matrix(maximum column sum) ,
038  *     normI denotes the infinity norm of a matrix(maximum row sum) and
039  *     normF denotes the Frobenius norm of a matrix(square root of sum of
040  *     squares). Note that max(abs(A(i , j))) is not a matrix norm.
041  
042  *     Notes
043  *     === ==
044  
045  *     Each global data object is described by an associated description
046  *     vector. This vector stores the information required to establish
047  *     the mapping between an object element and its corresponding process
048  *     and memory location.
049  
050  *     Let A be a generic term for any 2D block cyclicly distributed array.
051  *     Such a global array has an associated description vector DESCA.
052  *     In the following comments , the character _ should be read as
053  *     "of the global array".
054  
055  *     NOTATION STORED IN EXPLANATION
056  *     --- ------------ -------------- --------------------------------------
057  *     DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case ,
058  *     DTYPE_A = 1.
059  *     CTXT_A(global) DESCA( CTXT_ ) The BLACS context handle , indicating
060  *     the BLACS process grid A is distribu -
061  *     ted over. The context itself is glo -
062  *     bal , but the handle(the integer
063  *     value) may vary.
064  *     M_A(global) DESCA( M_ ) The number of rows in the global
065  *     array A.
066  *     N_A(global) DESCA( N_ ) The number of columns in the global
067  *     array A.
068  *     MB_A(global) DESCA( MB_ ) The blocking factor used to distribute
069  *     the rows of the array.
070  *     NB_A(global) DESCA( NB_ ) The blocking factor used to distribute
071  *     the columns of the array.
072  *     RSRC_A(global) DESCA( RSRC_ ) The process row over which the first
073  *     row of the array A is distributed.
074  *     CSRC_A(global) DESCA( CSRC_ ) The process column over which the
075  *     first column of the array A is
076  *     distributed.
077  *     LLD_A(local) DESCA( LLD_ ) The leading dimension of the local
078  *     array. LLD_A >= MAX(1 , LOCr(M_A)).
079  
080  *     Let K be the number of rows or columns of a distributed matrix ,
081  *     and assume that its process grid has dimension p x q.
082  *     LOCr( K ) denotes the number of elements of K that a process
083  *     would receive if K were distributed over the p processes of its
084  *     process column.
085  *     Similarly , LOCc( K ) denotes the number of elements of K that a
086  *     process would receive if K were distributed over the q processes of
087  *     its process row.
088  *     The values of LOCr() and LOCc() may be determined via a call to the
089  *     ScaLAPACK tool function , NUMROC :
090  *     LOCr( M ) = NUMROC( M , MB_A , MYROW , RSRC_A , NPROW ) ,
091  *     LOCc( N ) = NUMROC( N , NB_A , MYCOL , CSRC_A , NPCOL ).
092  *     An upper bound for these quantities may be computed by :
093  *     LOCr( M ) <= ceil( ceil(M / MB_A) / NPROW )*MB_A
094  *     LOCc( N ) <= ceil( ceil(N / NB_A) / NPCOL )*NB_A
095  
096  *     Arguments
097  *     === ======
098  
099  *     NORM(global input) CHARACTER
100  *     Specifies the value to be returned in PZLANSY as described
101  *     above.
102  
103  *     UPLO(global input) CHARACTER
104  *     Specifies whether the upper or lower triangular part of the
105  *     symmetric matrix sub( A ) is to be referenced.
106  *     = 'U' : Upper triangular part of sub( A ) is referenced ,
107  *     = 'L' : Lower triangular part of sub( A ) is referenced.
108  
109  *     N(global input) INTEGER
110  *     The number of rows and columns to be operated on i.e the
111  *     number of rows and columns of the distributed submatrix
112  *     sub( A ). When N = 0 , PZLANSY is set to zero. N >= 0.
113  
114  *     A(local input) COMPLEX*16 pointer into the local memory
115  *     to an array of dimension(LLD_A , LOCc(JA + N - 1)) containing the
116  *     local pieces of the symmetric distributed matrix sub( A ).
117  *     If UPLO = 'U' , the leading N - by - N upper triangular part of
118  *     sub( A ) contains the upper triangular matrix which norm is
119  *     to be computed , and the strictly lower triangular part of
120  *     this matrix is not referenced. If UPLO = 'L' , the leading
121  *     N - by - N lower triangular part of sub( A ) contains the lower
122  *     triangular matrix which norm is to be computed , and the
123  *     strictly upper triangular part of sub( A ) is not referenced.
124  
125  *     IA(global input) INTEGER
126  *     The row index in the global array A indicating the first
127  *     row of sub( A ).
128  
129  *     JA(global input) INTEGER
130  *     The column index in the global array A indicating the
131  *     first column of sub( A ).
132  
133  *     DESCA(global and local input) INTEGER array of dimension DLEN_.
134  *     The array descriptor for the distributed matrix A.
135  
136  *     WORK(local workspace) DOUBLE PRECISION array dimension(LWORK)
137  *     LWORK >= 0 if NORM = 'M' or 'm'(not referenced) ,
138  *     2*Nq0 + Np0 + LDW if NORM = '1' , 'O' , 'o' , 'I' or 'i' ,
139  *     where LDW is given by :
140  *     IF( NPROW.NE.NPCOL ) THEN
141  *     LDW = MB_A*CEIL(CEIL(Np0 / MB_A) / (LCM / NPROW))
142  *     ELSE
143  *     LDW = 0
144  *     END IF
145  *     0 if NORM = 'F' , 'f' , 'E' or 'e'(not referenced) ,
146  
147  *     where LCM is the least common multiple of NPROW and NPCOL
148  *     LCM = ILCM( NPROW , NPCOL ) and CEIL denotes the ceiling
149  *     operation(ICEIL).
150  
151  *     IROFFA = MOD( IA - 1 , MB_A ) , ICOFFA = MOD( JA - 1 , NB_A ) ,
152  *     IAROW = INDXG2P( IA , MB_A , MYROW , RSRC_A , NPROW ) ,
153  *     IACOL = INDXG2P( JA , NB_A , MYCOL , CSRC_A , NPCOL ) ,
154  *     Np0 = NUMROC( N + IROFFA , MB_A , MYROW , IAROW , NPROW ) ,
155  *     Nq0 = NUMROC( N + ICOFFA , NB_A , MYCOL , IACOL , NPCOL ) ,
156  
157  *     ICEIL , ILCM , INDXG2P and NUMROC are ScaLAPACK tool functions ;
158  *     MYROW , MYCOL , NPROW and NPCOL can be determined by calling
159  *     the subroutine BLACS_GRIDINFO.
160  
161  *     === ==================================================================
162  
163  *     .. Parameters ..
164        INTEGER BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ ,
165       $LLD_ , MB_ , M_ , NB_ , N_ , RSRC_
166        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
167       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
168       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
169        DOUBLE PRECISION ONE , ZERO
170        PARAMETER( ONE = 1.0D + 0 , ZERO = 0.0D + 0 )
171        IB = IN - IA + 1
172  
173  *     Find COLSUMS
174  
175        IF( MYCOL.EQ.IACOL ) THEN
176            IOFFA =(JJ - 1)*LDA
177            DO 290 K = 0 , IB - 1
178                SUM = ZERO
179                IF( IIA + NP.GT.II ) THEN
180                    DO 280 LL = II , IIA + NP - 1
181                        SUM = SUM + ABS( A( IOFFA + LL ) )
182    280             CONTINUE
183                END IF
184                IOFFA = IOFFA + LDA
185                WORK( JJ + K - JJA + ICSR0 ) = SUM
186                IF( MYROW.EQ.IAROW )
187       $            II = II + 1
188    290     CONTINUE
189  
190  *         Reset local indices so we can find ROWSUMS
191  
192            IF( MYROW.EQ.IAROW )
193       $        II = II - IB
194  
195            END IF
196  
197  *         Find ROWSUMS
198  
199            IF( MYROW.EQ.IAROW ) THEN
200                DO 310 K = II , II + IB - 1
201                    SUM = ZERO
202                    IF( JJ.GT.JJA ) THEN
203                        DO 300 LL =(JJA - 1)*LDA ,(JJ - 2)*LDA , LDA
204                            SUM = SUM + ABS( A( K + LL ) )
205    300                 CONTINUE
206                    END IF
207                    WORK( K - IIA + IRSC0 ) = SUM
208                    IF( MYCOL.EQ.IACOL )
209       $                JJ = JJ + 1
210    310         CONTINUE
211                II = II + IB
212            ELSE IF( MYCOL.EQ.IACOL ) THEN
213                JJ = JJ + IB
214            END IF
215  
216            ICURROW = MOD( IAROW + 1 , NPROW )
217            ICURCOL = MOD( IACOL + 1 , NPCOL )
218  
219  *         Loop over rows / columns of global matrix.
220  
221            DO 360 I = IN + 1 , IA + N - 1 , DESCA( MB_ )
222                IB = MIN( DESCA( MB_ ) , IA + N - I )
223  
224  *             Find COLSUMS
225  
226                IF( MYCOL.EQ.ICURCOL ) THEN
227                    IOFFA =( JJ - 1 ) * LDA
228                    DO 330 K = 0 , IB - 1
229                        SUM = ZERO
230                        IF( IIA + NP.GT.II ) THEN
231                            DO 320 LL = II , IIA + NP - 1
232                                SUM = SUM + ABS( A( LL + IOFFA ) )
233    320                     CONTINUE
234                        END IF
235                        IOFFA = IOFFA + LDA
236                        WORK( JJ + K - JJA + ICSR0 ) = SUM
237                        IF( MYROW.EQ.ICURROW )
238       $                    II = II + 1
239    330             CONTINUE
240  
241  *                 Reset local indices so we can find ROWSUMS
242  
243                    IF( MYROW.EQ.ICURROW )
244       $                II = II - IB
245  
246                    END IF
247  
248  *                 Find ROWSUMS
249  
250                    IF( MYROW.EQ.ICURROW ) THEN
251                        DO 350 K = II , II + IB - 1
252                            SUM = ZERO
253                            IF( JJ.GT.JJA ) THEN
254                                DO 340 LL =(JJA - 1)*LDA ,(JJ - 2)*LDA , LDA
255                                    SUM = SUM + ABS( A( K + LL ) )
256    340                         CONTINUE
257                            END IF
258                            WORK(K - IIA + IRSC0) = SUM
259                            IF( MYCOL.EQ.ICURCOL )
260       $                        JJ = JJ + 1
261    350                 CONTINUE
262                        II = II + IB
263                    ELSE IF( MYCOL.EQ.ICURCOL ) THEN
264                        JJ = JJ + IB
265                    END IF
266  
267                    ICURROW = MOD( ICURROW + 1 , NPROW )
268                    ICURCOL = MOD( ICURCOL + 1 , NPCOL )
269  
270    360     CONTINUE
271        END IF
272  
273  *     After calls to DGSUM2D , process row 0 will have global
274  *     COLSUMS and process column 0 will have global ROWSUMS.
275  *     Transpose ROWSUMS and add to COLSUMS to get global row / column
276  *     sum , the max of which is the infinity or 1 norm.
277  
278        IF( MYCOL.EQ.IACOL )
279       $    NQ = NQ + ICOFF
280            CALL DGSUM2D( ICTXT , 'Columnwise' , ' ' , 1 , NQ , WORK( ICSR ) , 1 ,
281       $    IAROW , MYCOL )
282            IF( MYROW.EQ.IAROW )
283       $        NP = NP + IROFF
284                CALL DGSUM2D( ICTXT , 'Rowwise' , ' ' , NP , 1 , WORK( IRSC ) ,
285       $        MAX( 1 , NP ) , MYROW , IACOL )
286  
287                CALL PDCOL2ROW( ICTXT , N , 1 , DESCA( MB_ ) , WORK( IRSC ) ,
288       $        MAX( 1 , NP ) , WORK( IRSR ) , MAX( 1 , NQ ) ,
289       $        IAROW , IACOL , IAROW , IACOL , WORK( IRSC + NP ) )
290  
291                IF( MYROW.EQ.IAROW ) THEN
292                    IF( MYCOL.EQ.IACOL )
293       $                NQ = NQ - ICOFF
294                        CALL DAXPY( NQ , ONE , WORK( IRSR0 ) , 1 , WORK( ICSR0 ) , 1 )
295                        IF( NQ.LT.1 ) THEN
296                            VALUE = ZERO
297                        ELSE
298                            VALUE = WORK( IDAMAX( NQ , WORK( ICSR0 ) , 1 ) )
299                        END IF
300                        CALL DGAMX2D( ICTXT , 'Rowwise' , ' ' , 1 , 1 , VALUE , 1 , I , K ,
301       $                - 1 , IAROW , IACOL )
302                    END IF
303  
304                ELSE IF( LSAME( NORM , 'F' ) .OR. LSAME( NORM , 'E' ) ) THEN
305  
306  *                 Find normF( sub( A ) ).
307  
308                    SCALE = ZERO
309                    SUM = ONE
310  
311  *                 Add off - diagonal entries , first
312  
313                    IF( LSAME( UPLO , 'U' ) ) THEN
314  
315  *                     Handle first block separately
316  
317                        IB = IN - IA + 1
318  
319                        IF( MYCOL.EQ.IACOL ) THEN
320                            DO 370 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
321                                CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
322                                IF( MYROW.EQ.IAROW )
323       $                            II = II + 1
324                                    CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
325    370                     CONTINUE
326  
327                            JJ = JJ + IB
328                        ELSE IF( MYROW.EQ.IAROW ) THEN
329                            II = II + IB
330                        END IF
331  
332                        ICURROW = MOD( IAROW + 1 , NPROW )
333                        ICURCOL = MOD( IACOL + 1 , NPCOL )
334  
335  *                     Loop over rows / columns of global matrix.
336  
337                        DO 390 I = IN + 1 , IA + N - 1 , DESCA( MB_ )
338                            IB = MIN( DESCA( MB_ ) , IA + N - I )
339  
340                            IF( MYCOL.EQ.ICURCOL ) THEN
341                                DO 380 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
342                                    CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
343                                    IF( MYROW.EQ.ICURROW )
344       $                                II = II + 1
345                                        CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
346    380                         CONTINUE
347  
348                                JJ = JJ + IB
349                            ELSE IF( MYROW.EQ.ICURROW ) THEN
350                                II = II + IB
351                            END IF
352  
353                            ICURROW = MOD( ICURROW + 1 , NPROW )
354                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
355  
356    390                 CONTINUE
357  
358                    ELSE
359  
360  *                     Handle first block separately
361  
362                        IB = IN - IA + 1
363  
364                        IF( MYCOL.EQ.IACOL ) THEN
365                            DO 400 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
366                                CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
367                                IF( MYROW.EQ.IAROW )
368       $                            II = II + 1
369                                    CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
370    400                     CONTINUE
371  
372                            JJ = JJ + IB
373                        ELSE IF( MYROW.EQ.IAROW ) THEN
374                            II = II + IB
375                        END IF
376  
377                        ICURROW = MOD( IAROW + 1 , NPROW )
378                        ICURCOL = MOD( IACOL + 1 , NPCOL )
379  
380  *                     Loop over rows / columns of global matrix.
381  
382                        DO 420 I = IN + 1 , IA + N - 1 , DESCA( MB_ )
383                            IB = MIN( DESCA( MB_ ) , IA + N - I )
384  
385                            IF( MYCOL.EQ.ICURCOL ) THEN
386                                DO 410 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
387                                    CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
388                                    IF( MYROW.EQ.ICURROW )
389       $                                II = II + 1
390                                        CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
391    410                         CONTINUE
392  
393                                JJ = JJ + IB
394                            ELSE IF( MYROW.EQ.ICURROW ) THEN
395                                II = II + IB
396                            END IF
397  
398                            ICURROW = MOD( ICURROW + 1 , NPROW )
399                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
400  
401    420                 CONTINUE
402  
403                    END IF
404  
405  *                 Perform the global scaled sum
406  
407                    RWORK( 1 ) = SCALE
408                    RWORK( 2 ) = SUM
409  
410                    CALL PDTREECOMB( ICTXT , 'All' , 2 , RWORK , IAROW , IACOL ,
411       $            DCOMBSSQ )
412                    VALUE = RWORK( 1 ) * SQRT( RWORK( 2 ) )
413  
414                END IF
415  
416  *             Broadcast the result to the other processes
417  
418                IF( MYROW.EQ.IAROW .AND. MYCOL.EQ.IACOL ) THEN
419                    CALL DGEBS2D( ICTXT , 'All' , ' ' , 1 , 1 , VALUE , 1 )
420                ELSE
421                    CALL DGEBR2D( ICTXT , 'All' , ' ' , 1 , 1 , VALUE , 1 , IAROW ,
422       $            IACOL )
423                END IF
424  
425                PZLANSY = VALUE
426  
427                RETURN
428  
429  *             End of PZLANSY
430  
431            END