ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
sstegr2b.f
Go to the documentation of this file.
00001       SUBROUTINE SSTEGR2B( JOBZ, N, D, E, 
00002      $                   M, W, Z, LDZ, NZC, ISUPPZ, WORK, LWORK, IWORK,
00003      $                   LIWORK, DOL, DOU, NEEDIL, NEEDIU,
00004      $                   INDWLC, PIVMIN, SCALE, WL, WU,
00005      $                   VSTART, FINISH, MAXCLS,
00006      $                   NDEPTH, PARITY, ZOFFSET, INFO )
00007 *
00008 *  -- ScaLAPACK auxiliary routine (version 2.0) --
00009 *     Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver
00010 *     July 4, 2010
00011 *
00012       IMPLICIT NONE
00013 *
00014 *     .. Scalar Arguments ..
00015       CHARACTER          JOBZ
00016       INTEGER            DOL, DOU, INDWLC, INFO, LDZ, LIWORK, LWORK, M,
00017      $                   MAXCLS, N, NDEPTH, NEEDIL, NEEDIU, NZC, PARITY,
00018      $                   ZOFFSET
00019 
00020       REAL             PIVMIN, SCALE, WL, WU
00021       LOGICAL VSTART, FINISH
00022 
00023 *     ..
00024 *     .. Array Arguments ..
00025       INTEGER            ISUPPZ( * ), IWORK( * )
00026       REAL               D( * ), E( * ), W( * ), WORK( * )
00027       REAL               Z( LDZ, * )
00028 *     ..
00029 *
00030 *  Purpose
00031 *  =======
00032 *
00033 *  SSTEGR2B should only be called after a call to SSTEGR2A.
00034 *  From eigenvalues and initial representations computed by SSTEGR2A,
00035 *  SSTEGR2B computes the selected eigenvalues and eigenvectors
00036 *  of the real symmetric tridiagonal matrix in parallel 
00037 *  on multiple processors. It is potentially invoked multiple times
00038 *  on a given processor because the locally relevant representation tree 
00039 *  might depend on spectral information that is "owned" by other processors
00040 *  and might need to be communicated. 
00041 * 
00042 *  Please note:
00043 *  1. The calling sequence has two additional INTEGER parameters, 
00044 *     DOL and DOU, that should satisfy M>=DOU>=DOL>=1. 
00045 *     These parameters are only relevant for the case JOBZ = 'V'.
00046 *     SSTEGR2B  ONLY computes the eigenVECTORS 
00047 *     corresponding to eigenvalues DOL through DOU in W. (That is,
00048 *     instead of computing the eigenvectors belonging to W(1) 
00049 *     through W(M), only the eigenvectors belonging to eigenvalues
00050 *     W(DOL) through W(DOU) are computed. In this case, only the
00051 *     eigenvalues DOL:DOU are guaranteed to be accurately refined
00052 *     to all figures by Rayleigh-Quotient iteration.
00053 *
00054 *  2. The additional arguments VSTART, FINISH, NDEPTH, PARITY, ZOFFSET 
00055 *     are included as a thread-safe implementation equivalent to SAVE variables.
00056 *     These variables store details about the local representation tree which is
00057 *     computed layerwise. For scalability reasons, eigenvalues belonging to the 
00058 *     locally relevant representation tree might be computed on other processors.
00059 *     These need to be communicated before the inspection of the RRRs can proceed
00060 *     on any given layer.           
00061 *     Note that only when the variable FINISH is true, the computation has ended
00062 *     All eigenpairs between DOL and DOU have been computed. M is set = DOU - DOL + 1.
00063 *
00064 *  3. SSTEGR2B needs more workspace in Z than the sequential SSTEGR. 
00065 *     It is used to store the conformal embedding of the local representation tree.  
00066 *  
00067 *  Arguments
00068 *  =========
00069 *
00070 *  JOBZ    (input) CHARACTER*1
00071 *          = 'N':  Compute eigenvalues only;
00072 *          = 'V':  Compute eigenvalues and eigenvectors.
00073 *
00074 *  N       (input) INTEGER
00075 *          The order of the matrix.  N >= 0.
00076 *
00077 *  D       (input/output) REAL array, dimension (N)
00078 *          On entry, the N diagonal elements of the tridiagonal matrix
00079 *          T. On exit, D is overwritten.
00080 *
00081 *  E       (input/output) REAL array, dimension (N)
00082 *          On entry, the (N-1) subdiagonal elements of the tridiagonal
00083 *          matrix T in elements 1 to N-1 of E. E(N) need not be set on
00084 *          input, but is used internally as workspace.
00085 *          On exit, E is overwritten.
00086 *
00087 *  M       (input) INTEGER
00088 *          The total number of eigenvalues found
00089 *          in SSTEGR2A.  0 <= M <= N.
00090 *
00091 *  W       (input) REAL array, dimension (N)
00092 *          The first M elements contain approximations to the selected 
00093 *          eigenvalues in ascending order. Note that only the eigenvalues from
00094 *          the locally relevant part of the representation tree, that is
00095 *          all the clusters that include eigenvalues from DOL:DOU, are reliable 
00096 *          on this processor. (It does not need to know about any others anyway.)
00097 *
00098 *  Z       (output) REAL array, dimension (LDZ, max(1,M) )
00099 *          If JOBZ = 'V', and if INFO = 0, then 
00100 *          a subset of the first M columns of Z
00101 *          contain the orthonormal eigenvectors of the matrix T
00102 *          corresponding to the selected eigenvalues, with the i-th
00103 *          column of Z holding the eigenvector associated with W(i).
00104 *          See DOL, DOU for more information.
00105 *
00106 *  LDZ     (input) INTEGER
00107 *          The leading dimension of the array Z.  LDZ >= 1, and if
00108 *          JOBZ = 'V', then LDZ >= max(1,N).
00109 *
00110 *  NZC     (input) INTEGER
00111 *          The number of eigenvectors to be held in the array Z.  
00112 *
00113 *  ISUPPZ  (output) INTEGER ARRAY, dimension ( 2*max(1,M) )
00114 *          The support of the eigenvectors in Z, i.e., the indices
00115 *          indicating the nonzero elements in Z. The i-th computed eigenvector
00116 *          is nonzero only in elements ISUPPZ( 2*i-1 ) through
00117 *          ISUPPZ( 2*i ). This is relevant in the case when the matrix 
00118 *          is split. ISUPPZ is only set if N>2.
00119 *
00120 *  WORK    (workspace/output) REAL array, dimension (LWORK)
00121 *          On exit, if INFO = 0, WORK(1) returns the optimal
00122 *          (and minimal) LWORK.
00123 *
00124 *  LWORK   (input) INTEGER
00125 *          The dimension of the array WORK. LWORK >= max(1,18*N)
00126 *          if JOBZ = 'V', and LWORK >= max(1,12*N) if JOBZ = 'N'.
00127 *          If LWORK = -1, then a workspace query is assumed; the routine
00128 *          only calculates the optimal size of the WORK array, returns
00129 *          this value as the first entry of the WORK array, and no error
00130 *          message related to LWORK is issued.
00131 *
00132 *  IWORK   (workspace/output) INTEGER array, dimension (LIWORK)
00133 *          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
00134 *
00135 *  LIWORK  (input) INTEGER
00136 *          The dimension of the array IWORK.  LIWORK >= max(1,10*N)
00137 *          if the eigenvectors are desired, and LIWORK >= max(1,8*N)
00138 *          if only the eigenvalues are to be computed.
00139 *          If LIWORK = -1, then a workspace query is assumed; the
00140 *          routine only calculates the optimal size of the IWORK array,
00141 *          returns this value as the first entry of the IWORK array, and
00142 *          no error message related to LIWORK is issued.
00143 *
00144 *  DOL     (input) INTEGER
00145 *  DOU     (input) INTEGER
00146 *          From the eigenvalues W(1:M), only eigenvectors 
00147 *          Z(:,DOL) to Z(:,DOU) are computed.
00148 *          If DOL > 1, then Z(:,DOL-1-ZOFFSET) is used and overwritten.
00149 *          If DOU < M, then Z(:,DOU+1-ZOFFSET) is used and overwritten.
00150 *
00151 *  NEEDIL  (input/output) INTEGER 
00152 *  NEEDIU  (input/output) INTEGER
00153 *          Describes which are the left and right outermost eigenvalues 
00154 *          still to be computed. Initially computed by SLARRE2A,
00155 *          modified in the course of the algorithm.
00156 *
00157 *  INDWLC  (output) REAL
00158 *          Pointer into the workspace, location where the local
00159 *          eigenvalue representations are stored. ("Local eigenvalues"
00160 *          are those relative to the individual shifts of the RRRs.)
00161 *
00162 *  PIVMIN  (input) REAL
00163 *          The minimum pivot in the sturm sequence for T.
00164 *
00165 *  SCALE   (input) REAL 
00166 *          The scaling factor for T. Used for unscaling the eigenvalues
00167 *          at the very end of the algorithm.
00168 *
00169 *  WL      (input) REAL
00170 *  WU      (input) REAL
00171 *          The interval (WL, WU] contains all the wanted eigenvalues.         
00172 *
00173 *  VSTART  (input/output) LOGICAL 
00174 *          .TRUE. on initialization, set to .FALSE. afterwards.
00175 *
00176 *  FINISH  (input/output) LOGICAL
00177 *          indicates whether all eigenpairs have been computed
00178 *
00179 *  MAXCLS  (input/output) INTEGER
00180 *          The largest cluster worked on by this processor in the
00181 *          representation tree.
00182 *
00183 *  NDEPTH  (input/output) INTEGER
00184 *          The current depth of the representation tree. Set to
00185 *          zero on initial pass, changed when the deeper levels of
00186 *          the representation tree are generated. 
00187 *
00188 *  PARITY  (input/output) INTEGER
00189 *          An internal parameter needed for the storage of the
00190 *          clusters on the current level of the representation tree.
00191 *
00192 *  ZOFFSET (input) INTEGER
00193 *          Offset for storing the eigenpairs when Z is distributed
00194 *          in 1D-cyclic fashion
00195 *
00196 *  INFO    (output) INTEGER
00197 *          On exit, INFO
00198 *          = 0:  successful exit
00199 *          other:if INFO = -i, the i-th argument had an illegal value
00200 *                if INFO = 20X, internal error in SLARRV2.
00201 *                Here, the digit X = ABS( IINFO ) < 10, where IINFO is 
00202 *                the nonzero error code returned by SLARRV2.
00203 *
00204 *     .. Parameters ..
00205       REAL               ONE, FOUR, MINRGP
00206       PARAMETER          ( ONE = 1.0E0,
00207      $                     FOUR = 4.0E0,
00208      $                     MINRGP = 3.0E-3 )
00209 *     ..
00210 *     .. Local Scalars ..
00211       LOGICAL            LQUERY, WANTZ, ZQUERY
00212       INTEGER            IINDBL, IINDW, IINDWK, IINFO, IINSPL, INDERR,
00213      $                   INDGP, INDGRS, INDSDM, INDWRK, ITMP, J, LIWMIN,
00214      $                   LWMIN
00215       REAL               EPS, RTOL1, RTOL2
00216 *     ..
00217 *     .. External Functions ..
00218       LOGICAL            LSAME
00219       REAL               SLAMCH, SLANST
00220       EXTERNAL           LSAME, SLAMCH, SLANST
00221 *     ..
00222 *     .. External Subroutines ..
00223       EXTERNAL           SLARRV2, SSCAL
00224 *     ..
00225 *     .. Intrinsic Functions ..
00226       INTRINSIC          MAX, MIN, REAL, SQRT
00227 *     ..
00228 *     .. Executable Statements ..
00229 *
00230 *     Test the input parameters.
00231 *
00232       WANTZ = LSAME( JOBZ, 'V' )
00233 *
00234       LQUERY = ( ( LWORK.EQ.-1 ).OR.( LIWORK.EQ.-1 ) )
00235       ZQUERY = ( NZC.EQ.-1 )
00236 
00237 *     SSTEGR2B needs WORK of size 6*N, IWORK of size 3*N.
00238 *     In addition, SLARRE2A needed WORK of size 6*N, IWORK of size 5*N.
00239 *     Workspace is kept consistent even though SLARRE2A is not called here.
00240 *     Furthermore, SLARRV2 needs WORK of size 12*N, IWORK of size 7*N.
00241       IF( WANTZ ) THEN
00242          LWMIN = 18*N
00243          LIWMIN = 10*N
00244       ELSE
00245 *        need less workspace if only the eigenvalues are wanted         
00246          LWMIN = 12*N
00247          LIWMIN = 8*N
00248       ENDIF
00249 *
00250       INFO = 0
00251 *
00252 *     Get machine constants.
00253 *
00254       EPS = SLAMCH( 'Precision' )
00255 *
00256       IF( (N.EQ.0).OR.(N.EQ.1) ) THEN 
00257          FINISH = .TRUE.       
00258          RETURN
00259       ENDIF
00260 
00261       IF(ZQUERY.OR.LQUERY)
00262      $   RETURN
00263 *
00264       INDGRS = 1
00265       INDERR = 2*N + 1
00266       INDGP = 3*N + 1
00267       INDSDM = 4*N + 1
00268       INDWRK = 6*N + 1
00269       INDWLC = INDWRK
00270 *
00271       IINSPL = 1
00272       IINDBL = N + 1
00273       IINDW = 2*N + 1
00274       IINDWK = 3*N + 1
00275 
00276 *     Set the tolerance parameters for bisection
00277       RTOL1 = FOUR*SQRT(EPS)
00278       RTOL2 = MAX( SQRT(EPS)*5.0E-3, FOUR * EPS )
00279 
00280 
00281       IF( WANTZ ) THEN
00282 *
00283 *        Compute the desired eigenvectors corresponding to the computed
00284 *        eigenvalues
00285 *
00286          CALL SLARRV2( N, WL, WU, D, E,
00287      $                PIVMIN, IWORK( IINSPL ), M, 
00288      $                DOL, DOU, NEEDIL, NEEDIU, MINRGP, RTOL1, RTOL2, 
00289      $                W, WORK( INDERR ), WORK( INDGP ), IWORK( IINDBL ),
00290      $                IWORK( IINDW ), WORK( INDGRS ), 
00291      $                WORK( INDSDM ), Z, LDZ,
00292      $                ISUPPZ, WORK( INDWRK ), IWORK( IINDWK ), 
00293      $                VSTART, FINISH, 
00294      $                MAXCLS, NDEPTH, PARITY, ZOFFSET, IINFO )
00295          IF( IINFO.NE.0 ) THEN
00296             INFO = 200 + ABS( IINFO )
00297             RETURN
00298          END IF
00299 *
00300       ELSE
00301 *        SLARRE2A computed eigenvalues of the (shifted) root representation
00302 *        SLARRV2 returns the eigenvalues of the unshifted matrix.
00303 *        However, if the eigenvectors are not desired by the user, we need
00304 *        to apply the corresponding shifts from SLARRE2A to obtain the 
00305 *        eigenvalues of the original matrix. 
00306          DO 30 J = 1, M
00307             ITMP = IWORK( IINDBL+J-1 )
00308             W( J ) = W( J ) + E( IWORK( IINSPL+ITMP-1 ) )
00309  30      CONTINUE
00310 *
00311          FINISH = .TRUE.
00312 *
00313       END IF
00314 *
00315 
00316       IF(FINISH) THEN        
00317 *        All eigenpairs have been computed       
00318 
00319 *
00320 *        If matrix was scaled, then rescale eigenvalues appropriately.
00321 *
00322          IF( SCALE.NE.ONE ) THEN
00323             CALL SSCAL( M, ONE / SCALE, W, 1 )
00324          END IF
00325 *
00326 *        Correct M if needed 
00327 *
00328          IF ( WANTZ ) THEN
00329             IF( DOL.NE.1 .OR. DOU.NE.M ) THEN
00330                M = DOU - DOL +1
00331             ENDIF
00332          ENDIF
00333 *
00334 *        No sorting of eigenpairs is done here, done later in the
00335 *        calling subroutine
00336 *
00337          WORK( 1 ) = LWMIN
00338          IWORK( 1 ) = LIWMIN
00339       ENDIF
00340 
00341       RETURN
00342 *
00343 *     End of SSTEGR2B
00344 *
00345       END