Routine: PSSYEVD()  File: SRC\pssyevd.f

 
 
# lines: 351
  # code: 351
  # comment: 0
  # blank:0
# Variables:70
# Callers:0
# Callings:8
# Words:208
# Keywords:129
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PSSYEVD computes  all the eigenvalues and eigenvectors
  of a real symmetric matrix A by calling the recommended sequence
  of ScaLAPACK routines.
  In its present form, PSSYEVD assumes a homogeneous system and makes
  no checks for consistency of the eigenvalues or eigenvectors across
  the different processes.  Because of this, it is possible that a
  heterogeneous system may return incorrect results without any error
  messages.
  Arguments
  =========
     NP = the number of rows local to a given process.
     NQ = the number of columns local to a given process.
  JOBZ    (input) CHARACTER*1
          = 'N':  Compute eigenvalues only;     (NOT IMPLEMENTED YET)
          = 'V':  Compute eigenvalues and eigenvectors.
  UPLO    (global input) CHARACTER*1
          Specifies whether the upper or lower triangular part of the
          symmetric matrix A is stored:
          = 'U':  Upper triangular
          = 'L':  Lower triangular
  N       (global input) INTEGER
          The number of rows and columns to be operated on, i.e. the
          order of the distributed submatrix sub( A ). N >= 0.
  A       (local input/workspace) block cyclic REAL array,
          global dimension (N, N), local dimension ( LLD_A,
          LOCc(JA+N-1) )
          On entry, the symmetric matrix A.  If UPLO = 'U', only the
          upper triangular part of A is used to define the elements of
          the symmetric matrix.  If UPLO = 'L', only the lower
          triangular part of A is used to define the elements of the
          symmetric matrix.
          On exit, the lower triangle (if UPLO='L') or the upper
          triangle (if UPLO='U') of A, including the diagonal, is
          destroyed.
  IA      (global input) INTEGER
          A's global row index, which points to the beginning of the
          submatrix which is to be operated on.
  JA      (global input) INTEGER
          A's global column index, which points to the beginning of
          the submatrix which is to be operated on.
  DESCA   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix A.
  W       (global output) REAL array, dimension (N)
          If INFO=0, the eigenvalues in ascending order.
  Z       (local output) REAL array,
          global dimension (N, N),
          local dimension ( LLD_Z, LOCc(JZ+N-1) )
          Z contains the orthonormal eigenvectors
          of the symmetric matrix A.
  IZ      (global input) INTEGER
          Z's global row index, which points to the beginning of the
          submatrix which is to be operated on.
  JZ      (global input) INTEGER
          Z's global column index, which points to the beginning of
          the submatrix which is to be operated on.
  DESCZ   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix Z.
          DESCZ( CTXT_ ) must equal DESCA( CTXT_ )
  WORK    (local workspace/output) REAL array,
          dimension (LWORK)
          On output, WORK(1) returns the workspace required.
  LWORK   (local input) INTEGER
          LWORK >= MAX( 1+6*N+2*NP*NQ, TRILWMIN ) + 2*N
          TRILWMIN = 3*N + MAX( NB*( NP+1 ), 3*NB )
          NP = NUMROC( N, NB, MYROW, IAROW, NPROW )
          NQ = NUMROC( N, NB, MYCOL, IACOL, NPCOL )
          If LWORK = -1, the LWORK is global input and a workspace
          query is assumed; the routine only calculates the minimum
          size for the WORK array.  The required workspace is returned
          as the first element of WORK and no error message is issued
          by PXERBLA.
  IWORK   (local workspace/output) INTEGER array, dimension (LIWORK)
          On exit, if LIWORK > 0, IWORK(1) returns the optimal LIWORK.
  LIWORK  (input) INTEGER
          The dimension of the array IWORK.
          LIWORK = 7*N + 8*NPCOL + 2
  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).
  Alignment requirements
  ======================
  The distributed submatrices sub( A ), sub( Z ) must verify
  some alignment properties, namely the following expression
  should be true:
  ( MB_A.EQ.NB_A.EQ.MB_Z.EQ.NB_Z .AND. IROFFA.EQ.ICOFFA .AND.
    IROFFA.EQ.0 .AND.IROFFA.EQ.IROFFZ. AND. IAROW.EQ.IZROW)
    with IROFFA = MOD( IA-1, MB_A )
     and ICOFFA = MOD( JA-1, NB_A ).
  Further Details
  ======= =======
  Contributed by Francoise Tisseur, University of Manchester.
  Reference:  F. Tisseur and J. Dongarra, "A Parallel Divide and
              Conquer Algorithm for the Symmetric Eigenvalue Problem
              on Distributed Memory Architectures",
              SIAM J. Sci. Comput., 6:20 (1999), pp. 2223--2236.
              (see also LAPACK Working Note 132)
                http://www.netlib.org/lapack/lawns/lawn132.ps
  =====================================================================
     .. Parameters ..

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

 
001        SUBROUTINE PSSYEVD( JOBZ , UPLO , N , A , IA , JA , DESCA , W , Z , IZ , JZ ,
002       $DESCZ , WORK , LWORK , IWORK , LIWORK , INFO )
003  
004  *     -- ScaLAPACK routine(version 1.7) --
005  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006  *     and University of California , Berkeley.
007  *     March 14 , 2000
008  
009  *     .. Scalar Arguments ..
010        CHARACTER JOBZ , UPLO
011        INTEGER IA , INFO , IZ , JA , JZ , LIWORK , LWORK , N
012        INTEGER BLOCK_CYCLIC_2D , DLEN_ , DTYPE_ , CTXT_ , M_ , N_ ,
013       $MB_ , NB_ , RSRC_ , CSRC_ , LLD_
014        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
015       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
016       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
017        REAL ZERO , ONE
018        PARAMETER( ZERO = 0.0E + 0 , ONE = 1.0E + 0 )
019  *     ..
020  *     .. Local Scalars ..
021        LOGICAL LQUERY , UPPER
022        INTEGER IACOL , IAROW , ICOFFA , ICOFFZ , ICTXT , IINFO ,
023       $INDD , INDE , INDE2 , INDTAU , INDWORK , INDWORK2 ,
024       $IROFFA , IROFFZ , ISCALE , LIWMIN , LLWORK ,
025       $LLWORK2 , LWMIN , MYCOL , MYROW , NB , NP , NPCOL ,
026       $NPROW , NQ , OFFSET , TRILWMIN
027        REAL ANRM , BIGNUM , EPS , RMAX , RMIN , SAFMIN , SIGMA ,
028       $SMLNUM
029  *     ..
030  *     .. Local Arrays ..
031        INTEGER IDUM1( 2 ) , IDUM2( 2 )
032  *     ..
033  *     .. External Functions ..
034        LOGICAL LSAME
035        INTEGER INDXG2P , NUMROC
036        REAL PSLAMCH , PSLANSY
037        EXTERNAL LSAME , INDXG2P , NUMROC , PSLAMCH , PSLANSY
038  *     ..
039  *     .. External Subroutines ..
040        EXTERNAL BLACS_GRIDINFO , CHK1MAT , PCHK1MAT , PSLARED1D ,
041       $PSLASCL , PSLASET , PSORMTR , PSSTEDC , PSSYTRD ,
042       $PXERBLA , SSCAL
043  *     ..
044  *     .. Intrinsic Functions ..
045        INTRINSIC ICHAR , MAX , MIN , MOD , REAL , SQRT
046  *     ..
047  *     .. Executable Statements ..
048  *     This is just to keep ftnchek and toolpack / 1 happy
049        IF( BLOCK_CYCLIC_2D*CSRC_*CTXT_*DLEN_*DTYPE_*LLD_*MB_*M_*NB_*N_*
050       $    RSRC_.LT.0 )RETURN
051  
052  *         Quick return
053  
054            IF( N.EQ.0 )
055       $        RETURN
056  
057  *             Test the input arguments.
058  
059                CALL BLACS_GRIDINFO( DESCZ( CTXT_ ) , NPROW , NPCOL , MYROW , MYCOL )
060  
061                INFO = 0
062                IF( NPROW.EQ. - 1 ) THEN
063                    INFO = - ( 600 + CTXT_ )
064                ELSE
065                    CALL CHK1MAT( N , 3 , N , 3 , IA , JA , DESCA , 7 , INFO )
066                    CALL CHK1MAT( N , 3 , N , 3 , IZ , JZ , DESCZ , 12 , INFO )
067                    IF( INFO.EQ.0 ) THEN
068                        UPPER = LSAME( UPLO , 'U' )
069                        NB = DESCA( NB_ )
070                        IROFFA = MOD( IA - 1 , DESCA( MB_ ) )
071                        ICOFFA = MOD( JA - 1 , DESCA( NB_ ) )
072                        IROFFZ = MOD( IZ - 1 , DESCZ( MB_ ) )
073                        ICOFFZ = MOD( JZ - 1 , DESCZ( NB_ ) )
074                        IAROW = INDXG2P( IA , NB , MYROW , DESCA( RSRC_ ) , NPROW )
075                        IACOL = INDXG2P( JA , NB , MYCOL , DESCA( CSRC_ ) , NPCOL )
076                        NP = NUMROC( N , NB , MYROW , IAROW , NPROW )
077                        NQ = NUMROC( N , NB , MYCOL , IACOL , NPCOL )
078  
079                        LQUERY =( LWORK.EQ. - 1 .OR. LIWORK.EQ. - 1 )
080                        TRILWMIN = 3*N + MAX( NB*( NP + 1 ) , 3*NB )
081                        LWMIN = MAX( 1 + 6*N + 2*NP*NQ , TRILWMIN ) + 2*N
082                        LIWMIN = 7*N + 8*NPCOL + 2
083                        WORK( 1 ) = REAL( LWMIN )
084                        IWORK( 1 ) = LIWMIN
085                        IF( .NOT.LSAME( JOBZ , 'V' ) ) THEN
086                            INFO = - 1
087                        ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO , 'L' ) ) THEN
088                            INFO = - 2
089                        ELSE IF( IROFFA.NE.ICOFFA .OR. ICOFFA.NE.0 ) THEN
090                            INFO = - 6
091                        ELSE IF( IROFFA.NE.IROFFZ .OR. ICOFFA.NE.ICOFFZ ) THEN
092                            INFO = - 10
093                        ELSE IF( DESCA( M_ ).NE.DESCZ( M_ ) ) THEN
094                            INFO = - ( 1200 + M_ )
095                        ELSE IF( DESCA( MB_ ).NE.DESCA( NB_ ) ) THEN
096                            INFO = - ( 700 + NB_ )
097                        ELSE IF( DESCZ( MB_ ).NE.DESCZ( NB_ ) ) THEN
098                            INFO = - ( 1200 + NB_ )
099                        ELSE IF( DESCA( MB_ ).NE.DESCZ( MB_ ) ) THEN
100                            INFO = - ( 1200 + MB_ )
101                        ELSE IF( DESCA( CTXT_ ).NE.DESCZ( CTXT_ ) ) THEN
102                            INFO = - ( 1200 + CTXT_ )
103                        ELSE IF( DESCA( RSRC_ ).NE.DESCZ( RSRC_ ) ) THEN
104                            INFO = - ( 1200 + RSRC_ )
105                        ELSE IF( DESCA( CSRC_ ).NE.DESCZ( CSRC_ ) ) THEN
106                            INFO = - ( 1200 + CSRC_ )
107                        ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
108                            INFO = - 14
109                        ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
110                            INFO = - 16
111                        END IF
112                    END IF
113                    IF( UPPER ) THEN
114                        IDUM1( 1 ) = ICHAR( 'U' )
115                    ELSE
116                        IDUM1( 1 ) = ICHAR( 'L' )
117                    END IF
118                    IDUM2( 1 ) = 2
119                    IF( LWORK.EQ. - 1 ) THEN
120                        IDUM1( 2 ) = - 1
121                    ELSE
122                        IDUM1( 2 ) = 1
123                    END IF
124                    IDUM2( 2 ) = 14
125                    CALL PCHK1MAT( N , 3 , N , 3 , IA , JA , DESCA , 7 , 2 , IDUM1 , IDUM2 ,
126       $            INFO )
127                END IF
128                IF( INFO.NE.0 ) THEN
129                    CALL PXERBLA( ICTXT , 'PSSYEVD' , - INFO )
130                    RETURN
131                ELSE IF( LQUERY ) THEN
132                    RETURN
133                END IF
134  
135  *             Set up pointers into the WORK array
136  
137                INDTAU = 1
138                INDE = INDTAU + N
139                INDD = INDE + N
140                INDE2 = INDD + N
141                INDWORK = INDE2 + N
142                LLWORK = LWORK - INDWORK + 1
143                INDWORK2 = INDD
144                LLWORK2 = LWORK - INDWORK2 + 1
145  
146  *             Scale matrix to allowable range , if necessary.
147  
148                ISCALE = 0
149                SAFMIN = PSLAMCH( DESCA( CTXT_ ) , 'Safe minimum' )
150                EPS = PSLAMCH( DESCA( CTXT_ ) , 'Precision' )
151                SMLNUM = SAFMIN / EPS
152                BIGNUM = ONE / SMLNUM
153                RMIN = SQRT( SMLNUM )
154                RMAX = MIN( SQRT( BIGNUM ) , ONE / SQRT( SQRT( SAFMIN ) ) )
155                ANRM = PSLANSY( 'M' , UPLO , N , A , IA , JA , DESCA , WORK( INDWORK ) )
156  
157                IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
158                    ISCALE = 1
159                    SIGMA = RMIN / ANRM
160                ELSE IF( ANRM.GT.RMAX ) THEN
161                    ISCALE = 1
162                    SIGMA = RMAX / ANRM
163                END IF
164  
165                IF( ISCALE.EQ.1 ) THEN
166                    CALL PSLASCL ( UPLO , ONE , SIGMA , N , N , A , IA , JA , DESCA , IINFO )
167                END IF
168  
169  *             Reduce symmetric matrix to tridiagonal form.
170  
171                CALL PSSYTRD ( UPLO , N , A , IA , JA , DESCA , WORK( INDD ) ,
172       $        WORK( INDE2 ) , WORK( INDTAU ) , WORK( INDWORK ) ,
173       $        LLWORK , IINFO )
174  
175  *             Copy the values of D , E to all processes.
176  
177                CALL PSLARED1D ( N , IA , JA , DESCA , WORK( INDD ) , W ,
178       $        WORK( INDWORK ) , LLWORK )
179  
180                CALL PSLARED1D ( N , IA , JA , DESCA , WORK( INDE2 ) , WORK( INDE ) ,
181       $        WORK( INDWORK ) , LLWORK )
182  
183                CALL PSLASET ( 'Full' , N , N , ZERO , ONE , Z , 1 , 1 , DESCZ )
184  
185                IF( UPPER ) THEN
186                    OFFSET = 1
187                ELSE
188                    OFFSET = 0
189                END IF
190                CALL PSSTEDC ( 'I' , N , W , WORK( INDE + OFFSET ) , Z , IZ , JZ , DESCZ ,
191       $        WORK( INDWORK2 ) , LLWORK2 , IWORK , LIWORK , INFO )
192  
193                CALL PSORMTR ( 'L' , UPLO , 'N' , N , N , A , IA , JA , DESCA ,
194       $        WORK( INDTAU ) , Z , IZ , JZ , DESCZ , WORK( INDWORK2 ) ,
195       $        LLWORK2 , IINFO )
196  
197  *             If matrix was scaled , then rescale eigenvalues appropriately.
198  
199                IF( ISCALE.EQ.1 ) THEN
200                    CALL SSCAL( N , ONE / SIGMA , W , 1 )
201                END IF
202  
203                RETURN
204  
205  *             End of PSSYEVD
206  
207            END