Routine: PDLAED0()  File: SRC\pdlaed0.f

 
 
# lines: 235
  # code: 235
  # comment: 0
  # blank:0
# Variables:44
# Callers:1
# Callings:1
# Words:143
# Keywords:95
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PDLAED0 computes all eigenvalues and corresponding eigenvectors of a
  symmetric tridiagonal matrix using the divide and conquer method.
  Arguments
  =========
  N       (global input) INTEGER
          The order of the tridiagonal matrix T.  N >= 0.
  D       (global input/output) DOUBLE PRECISION array, dimension (N)
          On entry, the diagonal elements of the tridiagonal matrix.
          On exit, if INFO = 0, the eigenvalues in descending order.
  E       (global input/output) DOUBLE PRECISION array, dimension (N-1)
          On entry, the subdiagonal elements of the tridiagonal matrix.
          On exit, E has been destroyed.
  Q       (local output) DOUBLE PRECISION array,
          global dimension (N, N),
          local dimension ( LLD_Q, LOCc(JQ+N-1))
          Q  contains the orthonormal eigenvectors of the symmetric
          tridiagonal matrix.
          On output, Q is distributed across the P processes in block
          cyclic format.
  IQ      (global input) INTEGER
          Q's global row index, which points to the beginning of the
          submatrix which is to be operated on.
  JQ      (global input) INTEGER
          Q's global column index, which points to the beginning of
          the submatrix which is to be operated on.
  DESCQ   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix Z.
  WORK    (local workspace ) DOUBLE PRECISION array, dimension (LWORK)
          LWORK = 6*N + 2*NP*NQ, with
          NP = NUMROC( N, MB_Q, MYROW, IQROW, NPROW )
          NQ = NUMROC( N, NB_Q, MYCOL, IQCOL, NPCOL )
          IQROW = INDXG2P( IQ, NB_Q, MYROW, RSRC_Q, NPROW )
          IQCOL = INDXG2P( JQ, MB_Q, MYCOL, CSRC_Q, NPCOL )
  IWORK   (local workspace/output) INTEGER array, dimension (LIWORK)
          LIWORK = 2 + 7*N + 8*NPCOL
  INFO    (global output) INTEGER
          = 0:  successful exit
          < 0:  If the i-th argument is an array and the j-entry had
                an illegal value, then INFO = -(i*100+j), if the i-th
                argument is a scalar and had an illegal value, then
                INFO = -i.
          > 0:  The algorithm failed to compute the INFO/(N+1) th
                eigenvalue while working on the submatrix lying in
                global rows and columns mod(INFO,N+1).
  =====================================================================
     .. Parameters ..

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

 
001        SUBROUTINE PDLAED0( N , D , E , Q , IQ , JQ , DESCQ , WORK , IWORK , INFO )
002  
003  *     -- ScaLAPACK auxiliary routine(version 1.7) --
004  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
005  *     and University of California , Berkeley.
006  *     December 31 , 1998
007  
008  *     .. Scalar Arguments ..
009        INTEGER INFO , IQ , JQ , N
010        INTEGER BLOCK_CYCLIC_2D , DLEN_ , DTYPE_ , CTXT_ , M_ , N_ ,
011       $MB_ , NB_ , RSRC_ , CSRC_ , LLD_
012        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
013       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
014       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
015  *     ..
016  *     .. Local Scalars ..
017        INTEGER I , ID , IDCOL , IDROW , IID , IINFO , IIQ , IM1 , IM2 ,
018       $IPQ , IQCOL , IQROW , J , JJD , JJQ , LDQ , MATSIZ ,
019       $MYCOL , MYROW , N1 , NB , NBL , NBL1 , NPCOL , NPROW ,
020       $SUBPBS , TSUBPBS
021  *     ..
022  *     .. External Subroutines ..
023        EXTERNAL BLACS_GRIDINFO , DGEBR2D , DGEBS2D , DGERV2D ,
024       $DGESD2D , DSTEQR , INFOG2L , PDLAED1 , PXERBLA
025  *     ..
026  *     .. External Functions ..
027  *     ..
028  *     .. Intrinsic Functions ..
029        INTRINSIC ABS , MIN
030  *     ..
031  *     .. Executable Statements ..
032  
033  *     This is just to keep ftnchek and toolpack / 1 happy
034        IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
035       $    RSRC_.LT.0 )RETURN
036  
037  *         Test the input parameters.
038  
039            CALL BLACS_GRIDINFO( DESCQ( CTXT_ ) , NPROW , NPCOL , MYROW , MYCOL )
040            INFO = 0
041            IF( DESCQ( NB_ ).GT.N .OR. N.LT.2 )
042       $        INFO = - 1
043                IF( INFO.NE.0 ) THEN
044                    CALL PXERBLA( DESCQ( CTXT_ ) , 'PDLAED0' , - INFO )
045                    RETURN
046                END IF
047  
048                NB = DESCQ( NB_ )
049                LDQ = DESCQ( LLD_ )
050                CALL INFOG2L( IQ , JQ , DESCQ , NPROW , NPCOL , MYROW , MYCOL , IIQ , JJQ ,
051       $        IQROW , IQCOL )
052  
053  *             Determine the size and placement of the submatrices , and save in
054  *             the leading elements of IWORK.
055  
056                TSUBPBS =( N - 1 ) / NB + 1
057                IWORK( 1 ) = TSUBPBS
058                SUBPBS = 1
059     10 CONTINUE
060        IF( IWORK( SUBPBS ).GT.1 ) THEN
061            DO 20 J = SUBPBS , 1 , - 1
062                IWORK( 2*J ) =( IWORK( J ) + 1 ) / 2
063                IWORK( 2*J - 1 ) = IWORK( J ) / 2
064     20     CONTINUE
065            SUBPBS = 2*SUBPBS
066            GO TO 10
067        END IF
068        DO 30 J = 2 , SUBPBS
069            IWORK( J ) = IWORK( J ) + IWORK( J - 1 )
070     30 CONTINUE
071  
072  *     Divide the matrix into TSUBPBS submatrices of size at most NB
073  *     using rank - 1 modifications(cuts).
074  
075        DO 40 I = NB + 1 , N , NB
076            IM1 = I - 1
077            D( IM1 ) = D( IM1 ) - ABS( E( IM1 ) )
078            D( I ) = D( I ) - ABS( E( IM1 ) )
079     40 CONTINUE
080  
081  *     Solve each submatrix eigenproblem at the bottom of the divide and
082  *     conquer tree. D is the same on each process.
083  
084        DO 50 ID = 1 , N , NB
085            CALL INFOG2L( IQ - 1 + ID , JQ - 1 + ID , DESCQ , NPROW , NPCOL , MYROW ,
086       $    MYCOL , IID , JJD , IDROW , IDCOL )
087            MATSIZ = MIN( NB , N - ID + 1 )
088            IF( MYROW.EQ.IDROW .AND. MYCOL.EQ.IDCOL ) THEN
089                IPQ = IID + ( JJD - 1 )*LDQ
090                CALL DSTEQR( 'I' , MATSIZ , D( ID ) , E( ID ) , Q( IPQ ) , LDQ ,
091       $        WORK , INFO )
092                IF( INFO.NE.0 ) THEN
093                    CALL PXERBLA( DESCQ( CTXT_ ) , 'DSTEQR' , - INFO )
094                    RETURN
095                END IF
096                IF( MYROW.NE.IQROW .OR. MYCOL.NE.IQCOL ) THEN
097                    CALL DGESD2D( DESCQ( CTXT_ ) , MATSIZ , 1 , D( ID ) , MATSIZ ,
098       $            IQROW , IQCOL )
099                END IF
100            ELSE IF( MYROW.EQ.IQROW .AND. MYCOL.EQ.IQCOL ) THEN
101                CALL DGERV2D( DESCQ( CTXT_ ) , MATSIZ , 1 , D( ID ) , MATSIZ ,
102       $        IDROW , IDCOL )
103            END IF
104     50 CONTINUE
105  
106        IF( MYROW.EQ.IQROW .AND. MYCOL.EQ.IQCOL ) THEN
107            CALL DGEBS2D( DESCQ( CTXT_ ) , 'A' , ' ' , N , 1 , D , N )
108        ELSE
109            CALL DGEBR2D( DESCQ( CTXT_ ) , 'A' , ' ' , N , 1 , D , N , IQROW ,
110       $    IQCOL )
111        END IF
112  
113  *     Successively merge eigensystems of adjacent submatrices
114  *     into eigensystem for the corresponding larger matrix.
115  
116  *     while( SUBPBS > 1 )
117  
118     60 CONTINUE
119        IF( SUBPBS.GT.1 ) THEN
120            IM2 = SUBPBS - 2
121            DO 80 I = 0 , IM2 , 2
122                IF( I.EQ.0 ) THEN
123                    NBL = IWORK( 2 )
124                    NBL1 = IWORK( 1 )
125                    IF( NBL1.EQ.0 )
126       $                GO TO 70
127                        ID = 1
128                        MATSIZ = MIN( N , NBL*NB )
129                        N1 = NBL1*NB
130                    ELSE
131                        NBL = IWORK( I + 2 ) - IWORK( I )
132                        NBL1 = NBL / 2
133                        IF( NBL1.EQ.0 )
134       $                    GO TO 70
135                            ID = IWORK( I )*NB + 1
136                            MATSIZ = MIN( NB*NBL , N - ID + 1 )
137                            N1 = NBL1*NB
138                        END IF
139  
140  *                     Merge lower order eigensystems(of size N1 and MATSIZ - N1)
141  *                     into an eigensystem of size MATSIZ.
142  
143                        CALL PDLAED1 ( MATSIZ , N1 , D( ID ) , ID , Q , IQ , JQ , DESCQ ,
144       $                E( ID + N1 - 1 ) , WORK , IWORK( SUBPBS + 1 ) , IINFO )
145                        IF( IINFO.NE.0 ) THEN
146                            INFO = IINFO*( N + 1 ) + ID
147                        END IF
148  
149     70 CONTINUE
150        IWORK( I / 2 + 1 ) = IWORK( I + 2 )
151     80 CONTINUE
152        SUBPBS = SUBPBS / 2
153  
154        GO TO 60
155        END IF
156  
157  *     end while
158  
159     90 CONTINUE
160        RETURN
161  
162  *     End of PDLAED0
163  
164        END