Routine: PSLANSY()  File: SRC\pslansy.f

 
 
# lines: 834
  # code: 834
  # comment: 0
  # blank:0
# Variables:37
# Callers:4
# Callings:0
# Words:399
# Keywords:163
 

 

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