Routine: PZLANHE()  File: SRC\pzlanhe.f

 
 
# lines: 949
  # code: 949
  # comment: 0
  # blank:0
# Variables:38
# Callers:4
# Callings:0
# Words:505
# Keywords:225
 

 

..
     .. Local Scalars ..
     ..
     .. Local Arrays ..
     ..
     .. External Subroutines ..
     ..
     .. External Functions ..
     ..
     .. Intrinsic Functions ..
     ..
     .. Executable Statements ..
     Get grid parameters and local indexes.
     If the matrix is Hermitian, 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
        hermitian).
           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 PZLANHE( 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  *     PZLANHE 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  *     complex hermitian distributed matrix sub(A) = A(IA : IA + N - 1 , JA : JA + N - 1).
025  
026  *     PZLANHE 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 PZLANHE as described
101  *     above.
102  
103  *     UPLO(global input) CHARACTER
104  *     Specifies whether the upper or lower triangular part of the
105  *     hermitian 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 , PZLANHE 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 hermitian 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( MYROW.EQ.IAROW ) THEN
180                    IF( IIA + NP.GT.II ) THEN
181                        SUM = ABS( DBLE( A( IOFFA + II ) ) )
182                        DO 280 LL = II + 1 , IIA + NP - 1
183                            SUM = SUM + ABS( A( IOFFA + LL ) )
184    280                 CONTINUE
185                    END IF
186                ELSE
187                    DO 285 LL = II , IIA + NP - 1
188                        SUM = SUM + ABS( A( IOFFA + LL ) )
189    285             CONTINUE
190                END IF
191                IOFFA = IOFFA + LDA
192                WORK( JJ + K - JJA + ICSR0 ) = SUM
193                IF( MYROW.EQ.IAROW )
194       $            II = II + 1
195    290     CONTINUE
196  
197  *         Reset local indices so we can find ROWSUMS
198  
199            IF( MYROW.EQ.IAROW )
200       $        II = II - IB
201  
202            END IF
203  
204  *         Find ROWSUMS
205  
206            IF( MYROW.EQ.IAROW ) THEN
207                DO 310 K = II , II + IB - 1
208                    SUM = ZERO
209                    IF( JJ.GT.JJA ) THEN
210                        DO 300 LL =(JJA - 1)*LDA ,(JJ - 2)*LDA , LDA
211                            SUM = SUM + ABS( A( K + LL ) )
212    300                 CONTINUE
213                    END IF
214                    WORK( K - IIA + IRSC0 ) = SUM
215                    IF( MYCOL.EQ.IACOL )
216       $                JJ = JJ + 1
217    310         CONTINUE
218                II = II + IB
219            ELSE IF( MYCOL.EQ.IACOL ) THEN
220                JJ = JJ + IB
221            END IF
222  
223            ICURROW = MOD( IAROW + 1 , NPROW )
224            ICURCOL = MOD( IACOL + 1 , NPCOL )
225  
226  *         Loop over rows / columns of global matrix.
227  
228            DO 360 I = IN + 1 , IA + N - 1 , DESCA( MB_ )
229                IB = MIN( DESCA( MB_ ) , IA + N - I )
230  
231  *             Find COLSUMS
232  
233                IF( MYCOL.EQ.ICURCOL ) THEN
234                    IOFFA =( JJ - 1 ) * LDA
235                    DO 330 K = 0 , IB - 1
236                        SUM = ZERO
237                        IF( MYROW.EQ.ICURROW ) THEN
238                            IF( IIA + NP.GT.II ) THEN
239                                SUM = ABS( DBLE( A( II + IOFFA ) ) )
240                                DO 320 LL = II + 1 , IIA + NP - 1
241                                    SUM = SUM + ABS( A( LL + IOFFA ) )
242    320                         CONTINUE
243                            ELSE IF( II.EQ.IIA + NP - 1 ) THEN
244                                SUM = ABS( DBLE( A( II + IOFFA ) ) )
245                            END IF
246                        ELSE
247                            DO 325 LL = II , IIA + NP - 1
248                                SUM = SUM + ABS( A( LL + IOFFA ) )
249    325                     CONTINUE
250                        END IF
251                        IOFFA = IOFFA + LDA
252                        WORK( JJ + K - JJA + ICSR0 ) = SUM
253                        IF( MYROW.EQ.ICURROW )
254       $                    II = II + 1
255    330             CONTINUE
256  
257  *                 Reset local indices so we can find ROWSUMS
258  
259                    IF( MYROW.EQ.ICURROW )
260       $                II = II - IB
261  
262                    END IF
263  
264  *                 Find ROWSUMS
265  
266                    IF( MYROW.EQ.ICURROW ) THEN
267                        DO 350 K = II , II + IB - 1
268                            SUM = ZERO
269                            IF( JJ.GT.JJA ) THEN
270                                DO 340 LL =(JJA - 1)*LDA ,(JJ - 2)*LDA , LDA
271                                    SUM = SUM + ABS( A( K + LL ) )
272    340                         CONTINUE
273                            END IF
274                            WORK(K - IIA + IRSC0) = SUM
275                            IF( MYCOL.EQ.ICURCOL )
276       $                        JJ = JJ + 1
277    350                 CONTINUE
278                        II = II + IB
279                    ELSE IF( MYCOL.EQ.ICURCOL ) THEN
280                        JJ = JJ + IB
281                    END IF
282  
283                    ICURROW = MOD( ICURROW + 1 , NPROW )
284                    ICURCOL = MOD( ICURCOL + 1 , NPCOL )
285  
286    360     CONTINUE
287        END IF
288  
289  *     After calls to DGSUM2D , process row 0 will have global
290  *     COLSUMS and process column 0 will have global ROWSUMS.
291  *     Transpose ROWSUMS and add to COLSUMS to get global row / column
292  *     sum , the max of which is the infinity or 1 norm.
293  
294        IF( MYCOL.EQ.IACOL )
295       $    NQ = NQ + ICOFF
296            CALL DGSUM2D( ICTXT , 'Columnwise' , ' ' , 1 , NQ , WORK( ICSR ) , 1 ,
297       $    IAROW , MYCOL )
298            IF( MYROW.EQ.IAROW )
299       $        NP = NP + IROFF
300                CALL DGSUM2D( ICTXT , 'Rowwise' , ' ' , NP , 1 , WORK( IRSC ) ,
301       $        MAX( 1 , NP ) , MYROW , IACOL )
302  
303                CALL PDCOL2ROW( ICTXT , N , 1 , DESCA( MB_ ) , WORK( IRSC ) ,
304       $        MAX( 1 , NP ) , WORK( IRSR ) , MAX( 1 , NQ ) ,
305       $        IAROW , IACOL , IAROW , IACOL , WORK( IRSC + NP ) )
306  
307                IF( MYROW.EQ.IAROW ) THEN
308                    IF( MYCOL.EQ.IACOL )
309       $                NQ = NQ - ICOFF
310                        CALL DAXPY( NQ , ONE , WORK( IRSR0 ) , 1 , WORK( ICSR0 ) , 1 )
311                        IF( NQ.LT.1 ) THEN
312                            VALUE = ZERO
313                        ELSE
314                            VALUE = WORK( IDAMAX( NQ , WORK( ICSR0 ) , 1 ) )
315                        END IF
316                        CALL DGAMX2D( ICTXT , 'Rowwise' , ' ' , 1 , 1 , VALUE , 1 , I , K ,
317       $                - 1 , IAROW , IACOL )
318                    END IF
319  
320                ELSE IF( LSAME( NORM , 'F' ) .OR. LSAME( NORM , 'E' ) ) THEN
321  
322  *                 Find normF( sub( A ) ).
323  
324                    SCALE = ZERO
325                    SUM = ONE
326  
327  *                 Add off - diagonal entries , first
328  
329                    IF( LSAME( UPLO , 'U' ) ) THEN
330  
331  *                     Handle first block separately
332  
333                        IB = IN - IA + 1
334  
335                        IF( MYCOL.EQ.IACOL ) THEN
336                            DO 370 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
337                                CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
338                                CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
339                                IF( MYROW.EQ.IAROW ) THEN
340                                    IF( DBLE( A( II + K ) ).NE.ZERO ) THEN
341                                        ABSA = ABS( DBLE( A( II + K ) ) )
342                                        IF( SCALE.LT.ABSA ) THEN
343                                            SUM = ONE + SUM * ( SCALE / ABSA )**2
344                                            SCALE = ABSA
345                                        ELSE
346                                            SUM = SUM + ( ABSA / SCALE )**2
347                                        END IF
348                                    END IF
349                                    II = II + 1
350                                END IF
351    370                     CONTINUE
352  
353                            JJ = JJ + IB
354                        ELSE IF( MYROW.EQ.IAROW ) THEN
355                            II = II + IB
356                        END IF
357  
358                        ICURROW = MOD( IAROW + 1 , NPROW )
359                        ICURCOL = MOD( IACOL + 1 , NPCOL )
360  
361  *                     Loop over rows / columns of global matrix.
362  
363                        DO 390 I = IN + 1 , IA + N - 1 , DESCA( MB_ )
364                            IB = MIN( DESCA( MB_ ) , IA + N - I )
365  
366                            IF( MYCOL.EQ.ICURCOL ) THEN
367                                DO 380 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
368                                    CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
369                                    CALL ZLASSQ( II - IIA , A( IIA + K ) , 1 , SCALE , SUM )
370                                    IF( MYROW.EQ.ICURROW ) THEN
371                                        IF( DBLE( A( II + K ) ).NE.ZERO ) THEN
372                                            ABSA = ABS( DBLE( A( II + K ) ) )
373                                            IF( SCALE.LT.ABSA ) THEN
374                                                SUM = ONE + SUM * ( SCALE / ABSA )**2
375                                                SCALE = ABSA
376                                            ELSE
377                                                SUM = SUM + ( ABSA / SCALE )**2
378                                            END IF
379                                        END IF
380                                        II = II + 1
381                                    END IF
382    380                         CONTINUE
383  
384                                JJ = JJ + IB
385                            ELSE IF( MYROW.EQ.ICURROW ) THEN
386                                II = II + IB
387                            END IF
388  
389                            ICURROW = MOD( ICURROW + 1 , NPROW )
390                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
391  
392    390                 CONTINUE
393  
394                    ELSE
395  
396  *                     Handle first block separately
397  
398                        IB = IN - IA + 1
399  
400                        IF( MYCOL.EQ.IACOL ) THEN
401                            DO 400 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
402                                IF( MYROW.EQ.IAROW ) THEN
403                                    IF( DBLE( A( II + K ) ).NE.ZERO ) THEN
404                                        ABSA = ABS( DBLE( A( II + K ) ) )
405                                        IF( SCALE.LT.ABSA ) THEN
406                                            SUM = ONE + SUM * ( SCALE / ABSA )**2
407                                            SCALE = ABSA
408                                        ELSE
409                                            SUM = SUM + ( ABSA / SCALE )**2
410                                        END IF
411                                    END IF
412                                    II = II + 1
413                                END IF
414                                CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
415                                CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
416    400                     CONTINUE
417  
418                            JJ = JJ + IB
419                        ELSE IF( MYROW.EQ.IAROW ) THEN
420                            II = II + IB
421                        END IF
422  
423                        ICURROW = MOD( IAROW + 1 , NPROW )
424                        ICURCOL = MOD( IACOL + 1 , NPCOL )
425  
426  *                     Loop over rows / columns of global matrix.
427  
428                        DO 420 I = IN + 1 , IA + N - 1 , DESCA( MB_ )
429                            IB = MIN( DESCA( MB_ ) , IA + N - I )
430  
431                            IF( MYCOL.EQ.ICURCOL ) THEN
432                                DO 410 K =(JJ - 1)*LDA ,(JJ + IB - 2)*LDA , LDA
433                                    IF( MYROW.EQ.ICURROW ) THEN
434                                        IF( DBLE( A( II + K ) ).NE.ZERO ) THEN
435                                            ABSA = ABS( DBLE( A( II + K ) ) )
436                                            IF( SCALE.LT.ABSA ) THEN
437                                                SUM = ONE + SUM * ( SCALE / ABSA )**2
438                                                SCALE = ABSA
439                                            ELSE
440                                                SUM = SUM + ( ABSA / SCALE )**2
441                                            END IF
442                                        END IF
443                                        II = II + 1
444                                    END IF
445                                    CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
446                                    CALL ZLASSQ( IIA + NP - II , A( II + K ) , 1 , SCALE , SUM )
447    410                         CONTINUE
448  
449                                JJ = JJ + IB
450                            ELSE IF( MYROW.EQ.ICURROW ) THEN
451                                II = II + IB
452                            END IF
453  
454                            ICURROW = MOD( ICURROW + 1 , NPROW )
455                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
456  
457    420                 CONTINUE
458  
459                    END IF
460  
461  *                 Perform the global scaled sum
462  
463                    RWORK( 1 ) = SCALE
464                    RWORK( 2 ) = SUM
465  
466                    CALL PDTREECOMB( ICTXT , 'All' , 2 , RWORK , IAROW , IACOL ,
467       $            DCOMBSSQ )
468                    VALUE = RWORK( 1 ) * SQRT( RWORK( 2 ) )
469  
470                END IF
471  
472  *             Broadcast the result to the other processes
473  
474                IF( MYROW.EQ.IAROW .AND. MYCOL.EQ.IACOL ) THEN
475                    CALL DGEBS2D( ICTXT , 'All' , ' ' , 1 , 1 , VALUE , 1 )
476                ELSE
477                    CALL DGEBR2D( ICTXT , 'All' , ' ' , 1 , 1 , VALUE , 1 , IAROW ,
478       $            IACOL )
479                END IF
480  
481                PZLANHE = VALUE
482  
483                RETURN
484  
485  *             End of PZLANHE
486  
487            END