Routine: PCTREVC()  File: SRC\pctrevc.f

 
 
# lines: 567
  # code: 567
  # comment: 0
  # blank:0
# Variables:68
# Callers:0
# Callings:4
# Words:373
# Keywords:239
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PCTREVC computes some or all of the right and/or left eigenvectors of
  a complex upper triangular matrix T in parallel.
  The right eigenvector x and the left eigenvector y of T corresponding
  to an eigenvalue w are defined by:
               T*x = w*x,     y'*T = w*y'
  where y' denotes the conjugate transpose of the vector y.
  If all eigenvectors are requested, the routine may either return the
  matrices X and/or Y of right or left eigenvectors of T, or the
  products Q*X and/or Q*Y, where Q is an input unitary
  matrix. If T was obtained from the Schur factorization of an
  original matrix A = Q*T*Q', then Q*X and Q*Y are the matrices of
  right or left eigenvectors of A.
  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 r x c.
  LOCr( K ) denotes the number of elements of K that a process
  would receive if K were distributed over the r 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 c 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
  =========
  SIDE    (global input) CHARACTER*1
          = 'R':  compute right eigenvectors only;
          = 'L':  compute left eigenvectors only;
          = 'B':  compute both right and left eigenvectors.
  HOWMNY  (global input) CHARACTER*1
          = 'A':  compute all right and/or left eigenvectors;
          = 'B':  compute all right and/or left eigenvectors,
                  and backtransform them using the input matrices
                  supplied in VR and/or VL;
          = 'S':  compute selected right and/or left eigenvectors,
                  specified by the logical array SELECT.
  SELECT  (global input) LOGICAL array, dimension (N)
          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
          computed.
          If HOWMNY = 'A' or 'B', SELECT is not referenced.
          To select the eigenvector corresponding to the j-th
          eigenvalue, SELECT(j) must be set to .TRUE..
  N       (global input) INTEGER
          The order of the matrix T. N >= 0.
  T       (global input/output) COMPLEX array, dimension
          (DESCT(LLD_),*)
          The upper triangular matrix T.  T is modified, but restored
          on exit.
  DESCT   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix T.
  VL      (global input/output) COMPLEX array, dimension
          (DESCVL(LLD_),MM)
          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
          contain an N-by-N matrix Q (usually the unitary matrix Q of
          Schur vectors returned by CHSEQR).
          On exit, if SIDE = 'L' or 'B', VL contains:
          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
          if HOWMNY = 'B', the matrix Q*Y;
          if HOWMNY = 'S', the left eigenvectors of T specified by
                           SELECT, stored consecutively in the columns
                           of VL, in the same order as their
                           eigenvalues.
          If SIDE = 'R', VL is not referenced.
  DESCVL  (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix VL.
  VR      (global input/output) COMPLEX array, dimension
          (DESCVR(LLD_),MM)
          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
          contain an N-by-N matrix Q (usually the unitary matrix Q of
          Schur vectors returned by CHSEQR).
          On exit, if SIDE = 'R' or 'B', VR contains:
          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
          if HOWMNY = 'B', the matrix Q*X;
          if HOWMNY = 'S', the right eigenvectors of T specified by
                           SELECT, stored consecutively in the columns
                           of VR, in the same order as their
                           eigenvalues.
          If SIDE = 'L', VR is not referenced.
  DESCVR  (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix VR.
  MM      (global input) INTEGER
          The number of columns in the arrays VL and/or VR. MM >= M.
  M       (global output) INTEGER
          The number of columns in the arrays VL and/or VR actually
          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
          is set to N.  Each selected eigenvector occupies one
          column.
  WORK    (local workspace) COMPLEX array,
                                         dimension ( 2*DESCT(LLD_) )
          Additional workspace may be required if PCLATTRS is updated
          to use WORK.
  RWORK   (local workspace) REAL array,
                                          dimension ( DESCT(LLD_) )
  INFO    (global output) INTEGER
          = 0:  successful exit
          < 0:  if INFO = -i, the i-th argument had an illegal value
  Further Details
  ===============
  The algorithm used in this program is basically backward (forward)
  substitution.  It is the hope that scaling would be used to make the
  the code robust against possible overflow.  But scaling has not yet
  been implemented in PCLATTRS which is called by this routine to solve
  the triangular systems.  PCLATTRS just calls PCTRSV.
  Each eigenvector is normalized so that the element of largest
  magnitude has magnitude 1; here the magnitude of a complex number
  (x,y) is taken to be |x| + |y|.
  Further Details
  ===============
  Implemented by Mark R. Fahey, June, 2000
  =====================================================================
     .. Parameters ..

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

 
001        SUBROUTINE PCTREVC( SIDE , HOWMNY , SELECT , N , T , DESCT , VL , DESCVL ,
002       $VR , DESCVR , MM , M , WORK , RWORK , INFO )
003  
004  *     -- ScaLAPACK routine(version 1.7) --
005  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006  *     and University of California , Berkeley.
007  *     July 31 , 2001
008  
009  *     .. Scalar Arguments ..
010        CHARACTER HOWMNY , SIDE
011        INTEGER INFO , M , MM , N
012        REAL ZERO , ONE
013        PARAMETER( ZERO = 0.0E + 0 , ONE = 1.0E + 0 )
014        COMPLEX CZERO , CONE
015        PARAMETER( CZERO =( 0.0E + 0 , 0.0E + 0 ) ,
016       $CONE =( 1.0E + 0 , 0.0E + 0 ) )
017        INTEGER BLOCK_CYCLIC_2D , DLEN_ , DTYPE_ , CTXT_ , M_ , N_ ,
018       $MB_ , NB_ , RSRC_ , CSRC_ , LLD_
019        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
020       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
021       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
022  *     ..
023  *     .. Local Scalars ..
024        LOGICAL ALLV , BOTHV , LEFTV , OVER , RIGHTV , SOMEV
025        INTEGER CONTXT , CSRC , I , ICOL , II , IROW , IS , ITMP1 ,
026       $ITMP2 , J , K , KI , LDT , LDVL , LDVR , LDW , MB ,
027       $MYCOL , MYROW , NB , NPCOL , NPROW , RSRC
028        REAL SELF
029        REAL OVFL , REMAXD , SCALE , SMIN , SMLNUM , ULP , UNFL
030        COMPLEX CDUM , REMAXC , SHIFT
031  *     ..
032  *     .. Local Arrays ..
033        INTEGER DESCW( DLEN_ )
034  *     ..
035  *     .. External Functions ..
036        LOGICAL LSAME
037        REAL PSLAMCH
038        EXTERNAL LSAME , PSLAMCH
039  *     ..
040  *     .. External Subroutines ..
041        EXTERNAL BLACS_GRIDINFO , DESCINIT , SGSUM2D , IGAMN2D ,
042       $INFOG2L , PSLABAD , PSCASUM , PXERBLA , PCAMAX ,
043       $PCCOPY , PCSSCAL , PCGEMV , PCLASET , PCLATTRS ,
044       $CGSUM2D
045  *     ..
046  *     .. Intrinsic Functions ..
047        INTRINSIC ABS , REAL , CMPLX , CONJG , AIMAG , MAX
048  *     ..
049  *     .. Statement Functions ..
050        REAL CABS1
051  *     ..
052  *     .. Statement Function definitions ..
053        CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
054  *     ..
055  *     .. Executable Statements ..
056  
057  *     This is just to keep ftnchek happy
058        IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
059       $    RSRC_.LT.0 )RETURN
060  
061            CONTXT = DESCT( CTXT_ )
062            RSRC = DESCT( RSRC_ )
063            CSRC = DESCT( CSRC_ )
064            MB = DESCT( MB_ )
065            NB = DESCT( NB_ )
066            LDT = DESCT( LLD_ )
067            LDW = LDT
068            LDVR = DESCVR( LLD_ )
069            LDVL = DESCVL( LLD_ )
070  
071            CALL BLACS_GRIDINFO( CONTXT , NPROW , NPCOL , MYROW , MYCOL )
072            SELF = MYROW*NPCOL + MYCOL
073  
074  *         Decode and test the input parameters
075  
076            BOTHV = LSAME( SIDE , 'B' )
077            RIGHTV = LSAME( SIDE , 'R' ) .OR. BOTHV
078            LEFTV = LSAME( SIDE , 'L' ) .OR. BOTHV
079  
080            ALLV = LSAME( HOWMNY , 'A' )
081            OVER = LSAME( HOWMNY , 'B' ) .OR. LSAME( HOWMNY , 'O' )
082            SOMEV = LSAME( HOWMNY , 'S' )
083  
084  *         Set M to the number of columns required to store the selected
085  *         eigenvectors.
086  
087            IF( SOMEV ) THEN
088                M = 0
089                DO 10 J = 1 , N
090                    IF( SELECT( J ) )
091       $                M = M + 1
092     10         CONTINUE
093            ELSE
094                M = N
095            END IF
096  
097            INFO = 0
098            IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
099                INFO = - 1
100            ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
101                INFO = - 2
102            ELSE IF( N.LT.0 ) THEN
103                INFO = - 4
104            ELSE IF( MM.LT.M ) THEN
105                INFO = - 11
106            END IF
107            CALL IGAMN2D( CONTXT , 'ALL' , ' ' , 1 , 1 , INFO , 1 , ITMP1 , ITMP2 , - 1 ,
108       $    - 1 , - 1 )
109            IF( INFO.LT.0 ) THEN
110                CALL PXERBLA( CONTXT , 'PCTREVC' , - INFO )
111                RETURN
112            END IF
113  
114  *         Quick return if possible.
115  
116            IF( N.EQ.0 )
117       $        RETURN
118  
119  *             Set the constants to control overflow.
120  
121                UNFL = PSLAMCH( CONTXT , 'Safe minimum' )
122                OVFL = ONE / UNFL
123                CALL PSLABAD ( CONTXT , UNFL , OVFL )
124                ULP = PSLAMCH( CONTXT , 'Precision' )
125                SMLNUM = UNFL*( N / ULP )
126  
127  *             Store the diagonal elements of T in working array WORK( LDW + 1 ).
128  
129                DO 20 I = 1 , N
130                    CALL INFOG2L( I , I , DESCT , NPROW , NPCOL , MYROW , MYCOL , IROW ,
131       $            ICOL , ITMP1 , ITMP2 )
132                    IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
133                        WORK( LDW + IROW ) = T(( ICOL - 1 )*LDT + IROW )
134                    END IF
135     20         CONTINUE
136  
137  *             Compute 1 - norm of each column of strictly upper triangular
138  *             part of T to control overflow in triangular solver. Computed ,
139  *             but not used. For use in PCLATTRS.
140  
141                RWORK( 1 ) = ZERO
142                DO 30 J = 2 , N
143                    CALL PSCASUM( J - 1 , RWORK( J ) , T , 1 , J , DESCT , 1 )
144     30         CONTINUE
145  *             I replicate the norms in RWORK. Should they be distributed
146  *             over the process rows?
147                CALL SGSUM2D( CONTXT , 'Row' , ' ' , N , 1 , RWORK , N , - 1 , - 1 )
148  
149                IF( RIGHTV ) THEN
150  
151  *                 Compute right eigenvectors.
152  
153  *                 Need to set the distribution pattern of WORK
154  
155                    CALL DESCINIT( DESCW , N , 1 , NB , 1 , RSRC , CSRC , CONTXT , LDW ,
156       $            INFO )
157  
158                    IS = M
159                    DO 70 KI = N , 1 , - 1
160  
161                        IF( SOMEV ) THEN
162                            IF( .NOT.SELECT( KI ) )
163       $                        GO TO 70
164                            END IF
165  
166                            SMIN = ZERO
167                            SHIFT = CZERO
168                            CALL INFOG2L( KI , KI , DESCT , NPROW , NPCOL , MYROW , MYCOL ,
169       $                    IROW , ICOL , ITMP1 , ITMP2 )
170                            IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
171                                SHIFT = T(( ICOL - 1 )*LDT + IROW )
172                                SMIN = MAX( ULP*( CABS1( SHIFT ) ) , SMLNUM )
173                            END IF
174                            CALL SGSUM2D( CONTXT , 'ALL' , ' ' , 1 , 1 , SMIN , 1 , - 1 , - 1 )
175                            CALL CGSUM2D( CONTXT , 'ALL' , ' ' , 1 , 1 , SHIFT , 1 , - 1 , - 1 )
176  
177                            CALL INFOG2L( 1 , 1 , DESCW , NPROW , NPCOL , MYROW , MYCOL , IROW ,
178       $                    ICOL , ITMP1 , ITMP2 )
179                            IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
180                                WORK( 1 ) = CONE
181                            END IF
182  
183  *                         Form right - hand side. Distribute rhs onto first column
184  *                         of processor grid.
185  
186                            IF( KI.GT.1 ) THEN
187                                CALL PCCOPY( KI - 1 , T , 1 , KI , DESCT , 1 , WORK , 1 , 1 , DESCW ,
188       $                        1 )
189                            END IF
190                            DO 40 K = 1 , KI - 1
191                                CALL INFOG2L( K , 1 , DESCW , NPROW , NPCOL , MYROW , MYCOL ,
192       $                        IROW , ICOL , ITMP1 , ITMP2 )
193                                IF( MYROW.EQ.ITMP1 .AND. MYCOL.EQ.ITMP2 ) THEN
194                                    WORK( IROW ) = - WORK( IROW )
195                                END IF
196     40                     CONTINUE
197  
198  *                         Solve the triangular system :
199  *                         (T(1 : KI - 1 , 1 : KI - 1) - T(KI , KI))*X = SCALE*WORK.
200  
201                            DO 50 K = 1 , KI - 1
202                                CALL INFOG2L( K , K , DESCT , NPROW , NPCOL , MYROW , MYCOL ,
203       $                        IROW , ICOL , ITMP1 , ITMP2 )
204                                IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
205                                    T(( ICOL - 1 )*LDT + IROW ) = T(( ICOL - 1 )*LDT + IROW ) -
206       $                            SHIFT
207                                    IF( CABS1( T(( ICOL - 1 )*LDT + IROW ) ).LT.SMIN ) THEN
208                                        T(( ICOL - 1 )*LDT + IROW ) = CMPLX( SMIN )
209                                    END IF
210                                END IF
211     50                     CONTINUE
212  
213                            IF( KI.GT.1 ) THEN
214                                CALL PCLATTRS ( 'Upper' , 'No transpose' , 'Non - unit' , 'Y' ,
215       $                        KI - 1 , T , 1 , 1 , DESCT , WORK , 1 , 1 , DESCW ,
216       $                        SCALE , RWORK , INFO )
217                                CALL INFOG2L( KI , 1 , DESCW , NPROW , NPCOL , MYROW , MYCOL ,
218       $                        IROW , ICOL , ITMP1 , ITMP2 )
219                                IF( MYROW.EQ.ITMP1 .AND. MYCOL.EQ.ITMP2 ) THEN
220                                    WORK( IROW ) = CMPLX( SCALE )
221                                END IF
222                            END IF
223  
224  *                         Copy the vector x or Q*x to VR and normalize.
225  
226                            IF( .NOT.OVER ) THEN
227                                CALL PCCOPY( KI , WORK , 1 , 1 , DESCW , 1 , VR , 1 , IS , DESCVR ,
228       $                        1 )
229  
230                                CALL PCAMAX( KI , REMAXC , II , VR , 1 , IS , DESCVR , 1 )
231                                REMAXD = ONE / MAX( CABS1( REMAXC ) , UNFL )
232                                CALL PCSSCAL( KI , REMAXD , VR , 1 , IS , DESCVR , 1 )
233  
234                                CALL PCLASET ( ' ' , N - KI , 1 , CZERO , CZERO , VR , KI + 1 , IS ,
235       $                        DESCVR )
236                            ELSE
237                                IF( KI.GT.1 )
238       $                            CALL PCGEMV( 'N' , N , KI - 1 , CONE , VR , 1 , 1 , DESCVR ,
239       $                            WORK , 1 , 1 , DESCW , 1 , CMPLX( SCALE ) ,
240       $                            VR , 1 , KI , DESCVR , 1 )
241  
242                                    CALL PCAMAX( N , REMAXC , II , VR , 1 , KI , DESCVR , 1 )
243                                    REMAXD = ONE / MAX( CABS1( REMAXC ) , UNFL )
244                                    CALL PCSSCAL( N , REMAXD , VR , 1 , KI , DESCVR , 1 )
245                                END IF
246  
247  *                             Set back the original diagonal elements of T.
248  
249                                DO 60 K = 1 , KI - 1
250                                    CALL INFOG2L( K , K , DESCT , NPROW , NPCOL , MYROW , MYCOL ,
251       $                            IROW , ICOL , ITMP1 , ITMP2 )
252                                    IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
253                                        T(( ICOL - 1 )*LDT + IROW ) = WORK( LDW + IROW )
254                                    END IF
255     60                         CONTINUE
256  
257                                IS = IS - 1
258     70             CONTINUE
259                END IF
260  
261                IF( LEFTV ) THEN
262  
263  *                 Compute left eigenvectors.
264  
265  *                 Need to set the distribution pattern of WORK
266  
267                    CALL DESCINIT( DESCW , N , 1 , MB , 1 , RSRC , CSRC , CONTXT , LDW ,
268       $            INFO )
269  
270                    IS = 1
271                    DO 110 KI = 1 , N
272  
273                        IF( SOMEV ) THEN
274                            IF( .NOT.SELECT( KI ) )
275       $                        GO TO 110
276                            END IF
277  
278                            SMIN = ZERO
279                            SHIFT = CZERO
280                            CALL INFOG2L( KI , KI , DESCT , NPROW , NPCOL , MYROW , MYCOL ,
281       $                    IROW , ICOL , ITMP1 , ITMP2 )
282                            IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
283                                SHIFT = T(( ICOL - 1 )*LDT + IROW )
284                                SMIN = MAX( ULP*( CABS1( SHIFT ) ) , SMLNUM )
285                            END IF
286                            CALL SGSUM2D( CONTXT , 'ALL' , ' ' , 1 , 1 , SMIN , 1 , - 1 , - 1 )
287                            CALL CGSUM2D( CONTXT , 'ALL' , ' ' , 1 , 1 , SHIFT , 1 , - 1 , - 1 )
288  
289                            CALL INFOG2L( N , 1 , DESCW , NPROW , NPCOL , MYROW , MYCOL , IROW ,
290       $                    ICOL , ITMP1 , ITMP2 )
291                            IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
292                                WORK( IROW ) = CONE
293                            END IF
294  
295  *                         Form right - hand side.
296  
297                            IF( KI.LT.N ) THEN
298                                CALL PCCOPY( N - KI , T , KI , KI + 1 , DESCT , N , WORK , KI + 1 , 1 ,
299       $                        DESCW , 1 )
300                            END IF
301                            DO 80 K = KI + 1 , N
302                                CALL INFOG2L( K , 1 , DESCW , NPROW , NPCOL , MYROW , MYCOL ,
303       $                        IROW , ICOL , ITMP1 , ITMP2 )
304                                IF( MYROW.EQ.ITMP1 .AND. MYCOL.EQ.ITMP2 ) THEN
305                                    WORK( IROW ) = - CONJG( WORK( IROW ) )
306                                END IF
307     80                     CONTINUE
308  
309  *                         Solve the triangular system :
310  *                         (T(KI + 1 : N , KI + 1 : N) - T(KI , KI))'*X = SCALE*WORK.
311  
312                            DO 90 K = KI + 1 , N
313                                CALL INFOG2L( K , K , DESCT , NPROW , NPCOL , MYROW , MYCOL ,
314       $                        IROW , ICOL , ITMP1 , ITMP2 )
315                                IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
316                                    T(( ICOL - 1 )*LDT + IROW ) = T(( ICOL - 1 )*LDT + IROW ) -
317       $                            SHIFT
318                                    IF( CABS1( T(( ICOL - 1 )*LDT + IROW ) ).LT.SMIN )
319       $                                T(( ICOL - 1 )*LDT + IROW ) = CMPLX( SMIN )
320                                    END IF
321     90                     CONTINUE
322  
323                            IF( KI.LT.N ) THEN
324                                CALL PCLATTRS ( 'Upper' , 'Conjugate transpose' , 'Nonunit' ,
325       $                        'Y' , N - KI , T , KI + 1 , KI + 1 , DESCT , WORK ,
326       $                        KI + 1 , 1 , DESCW , SCALE , RWORK , INFO )
327                                CALL INFOG2L( KI , 1 , DESCW , NPROW , NPCOL , MYROW , MYCOL ,
328       $                        IROW , ICOL , ITMP1 , ITMP2 )
329                                IF( MYROW.EQ.ITMP1 .AND. MYCOL.EQ.ITMP2 ) THEN
330                                    WORK( IROW ) = CMPLX( SCALE )
331                                END IF
332                            END IF
333  
334  *                         Copy the vector x or Q*x to VL and normalize.
335  
336                            IF( .NOT.OVER ) THEN
337                                CALL PCCOPY( N - KI + 1 , WORK , KI , 1 , DESCW , 1 , VL , KI , IS ,
338       $                        DESCVL , 1 )
339  
340                                CALL PCAMAX( N - KI + 1 , REMAXC , II , VL , KI , IS , DESCVL , 1 )
341                                REMAXD = ONE / MAX( CABS1( REMAXC ) , UNFL )
342                                CALL PCSSCAL( N - KI + 1 , REMAXD , VL , KI , IS , DESCVL , 1 )
343  
344                                CALL PCLASET ( ' ' , KI - 1 , 1 , CZERO , CZERO , VL , 1 , IS ,
345       $                        DESCVL )
346                            ELSE
347                                IF( KI.LT.N )
348       $                            CALL PCGEMV( 'N' , N , N - KI , CONE , VL , 1 , KI + 1 , DESCVL ,
349       $                            WORK , KI + 1 , 1 , DESCW , 1 , CMPLX( SCALE ) ,
350       $                            VL , 1 , KI , DESCVL , 1 )
351  
352                                    CALL PCAMAX( N , REMAXC , II , VL , 1 , KI , DESCVL , 1 )
353                                    REMAXD = ONE / MAX( CABS1( REMAXC ) , UNFL )
354                                    CALL PCSSCAL( N , REMAXD , VL , 1 , KI , DESCVL , 1 )
355                                END IF
356  
357  *                             Set back the original diagonal elements of T.
358  
359                                DO 100 K = KI + 1 , N
360                                    CALL INFOG2L( K , K , DESCT , NPROW , NPCOL , MYROW , MYCOL ,
361       $                            IROW , ICOL , ITMP1 , ITMP2 )
362                                    IF(( MYROW.EQ.ITMP1 ) .AND.( MYCOL.EQ.ITMP2 ) ) THEN
363                                        T(( ICOL - 1 )*LDT + IROW ) = WORK( LDW + IROW )
364                                    END IF
365    100                         CONTINUE
366  
367                                IS = IS + 1
368    110             CONTINUE
369                END IF
370  
371                RETURN
372  
373  *             End of PCTREVC
374  
375            END