File:  [local] / rpl / lapack / lapack / dstein.f
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Sat Aug 7 13:22:26 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Mise à jour globale de Lapack 3.2.2.

    1:       SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK,
    2:      $                   IWORK, IFAIL, INFO )
    3: *
    4: *  -- LAPACK routine (version 3.2) --
    5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
    6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
    7: *     November 2006
    8: *
    9: *     .. Scalar Arguments ..
   10:       INTEGER            INFO, LDZ, M, N
   11: *     ..
   12: *     .. Array Arguments ..
   13:       INTEGER            IBLOCK( * ), IFAIL( * ), ISPLIT( * ),
   14:      $                   IWORK( * )
   15:       DOUBLE PRECISION   D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )
   16: *     ..
   17: *
   18: *  Purpose
   19: *  =======
   20: *
   21: *  DSTEIN computes the eigenvectors of a real symmetric tridiagonal
   22: *  matrix T corresponding to specified eigenvalues, using inverse
   23: *  iteration.
   24: *
   25: *  The maximum number of iterations allowed for each eigenvector is
   26: *  specified by an internal parameter MAXITS (currently set to 5).
   27: *
   28: *  Arguments
   29: *  =========
   30: *
   31: *  N       (input) INTEGER
   32: *          The order of the matrix.  N >= 0.
   33: *
   34: *  D       (input) DOUBLE PRECISION array, dimension (N)
   35: *          The n diagonal elements of the tridiagonal matrix T.
   36: *
   37: *  E       (input) DOUBLE PRECISION array, dimension (N-1)
   38: *          The (n-1) subdiagonal elements of the tridiagonal matrix
   39: *          T, in elements 1 to N-1.
   40: *
   41: *  M       (input) INTEGER
   42: *          The number of eigenvectors to be found.  0 <= M <= N.
   43: *
   44: *  W       (input) DOUBLE PRECISION array, dimension (N)
   45: *          The first M elements of W contain the eigenvalues for
   46: *          which eigenvectors are to be computed.  The eigenvalues
   47: *          should be grouped by split-off block and ordered from
   48: *          smallest to largest within the block.  ( The output array
   49: *          W from DSTEBZ with ORDER = 'B' is expected here. )
   50: *
   51: *  IBLOCK  (input) INTEGER array, dimension (N)
   52: *          The submatrix indices associated with the corresponding
   53: *          eigenvalues in W; IBLOCK(i)=1 if eigenvalue W(i) belongs to
   54: *          the first submatrix from the top, =2 if W(i) belongs to
   55: *          the second submatrix, etc.  ( The output array IBLOCK
   56: *          from DSTEBZ is expected here. )
   57: *
   58: *  ISPLIT  (input) INTEGER array, dimension (N)
   59: *          The splitting points, at which T breaks up into submatrices.
   60: *          The first submatrix consists of rows/columns 1 to
   61: *          ISPLIT( 1 ), the second of rows/columns ISPLIT( 1 )+1
   62: *          through ISPLIT( 2 ), etc.
   63: *          ( The output array ISPLIT from DSTEBZ is expected here. )
   64: *
   65: *  Z       (output) DOUBLE PRECISION array, dimension (LDZ, M)
   66: *          The computed eigenvectors.  The eigenvector associated
   67: *          with the eigenvalue W(i) is stored in the i-th column of
   68: *          Z.  Any vector which fails to converge is set to its current
   69: *          iterate after MAXITS iterations.
   70: *
   71: *  LDZ     (input) INTEGER
   72: *          The leading dimension of the array Z.  LDZ >= max(1,N).
   73: *
   74: *  WORK    (workspace) DOUBLE PRECISION array, dimension (5*N)
   75: *
   76: *  IWORK   (workspace) INTEGER array, dimension (N)
   77: *
   78: *  IFAIL   (output) INTEGER array, dimension (M)
   79: *          On normal exit, all elements of IFAIL are zero.
   80: *          If one or more eigenvectors fail to converge after
   81: *          MAXITS iterations, then their indices are stored in
   82: *          array IFAIL.
   83: *
   84: *  INFO    (output) INTEGER
   85: *          = 0: successful exit.
   86: *          < 0: if INFO = -i, the i-th argument had an illegal value
   87: *          > 0: if INFO = i, then i eigenvectors failed to converge
   88: *               in MAXITS iterations.  Their indices are stored in
   89: *               array IFAIL.
   90: *
   91: *  Internal Parameters
   92: *  ===================
   93: *
   94: *  MAXITS  INTEGER, default = 5
   95: *          The maximum number of iterations performed.
   96: *
   97: *  EXTRA   INTEGER, default = 2
   98: *          The number of iterations performed after norm growth
   99: *          criterion is satisfied, should be at least 1.
  100: *
  101: *  =====================================================================
  102: *
  103: *     .. Parameters ..
  104:       DOUBLE PRECISION   ZERO, ONE, TEN, ODM3, ODM1
  105:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TEN = 1.0D+1,
  106:      $                   ODM3 = 1.0D-3, ODM1 = 1.0D-1 )
  107:       INTEGER            MAXITS, EXTRA
  108:       PARAMETER          ( MAXITS = 5, EXTRA = 2 )
  109: *     ..
  110: *     .. Local Scalars ..
  111:       INTEGER            B1, BLKSIZ, BN, GPIND, I, IINFO, INDRV1,
  112:      $                   INDRV2, INDRV3, INDRV4, INDRV5, ITS, J, J1,
  113:      $                   JBLK, JMAX, NBLK, NRMCHK
  114:       DOUBLE PRECISION   DTPCRT, EPS, EPS1, NRM, ONENRM, ORTOL, PERTOL,
  115:      $                   SCL, SEP, TOL, XJ, XJM, ZTR
  116: *     ..
  117: *     .. Local Arrays ..
  118:       INTEGER            ISEED( 4 )
  119: *     ..
  120: *     .. External Functions ..
  121:       INTEGER            IDAMAX
  122:       DOUBLE PRECISION   DASUM, DDOT, DLAMCH, DNRM2
  123:       EXTERNAL           IDAMAX, DASUM, DDOT, DLAMCH, DNRM2
  124: *     ..
  125: *     .. External Subroutines ..
  126:       EXTERNAL           DAXPY, DCOPY, DLAGTF, DLAGTS, DLARNV, DSCAL,
  127:      $                   XERBLA
  128: *     ..
  129: *     .. Intrinsic Functions ..
  130:       INTRINSIC          ABS, MAX, SQRT
  131: *     ..
  132: *     .. Executable Statements ..
  133: *
  134: *     Test the input parameters.
  135: *
  136:       INFO = 0
  137:       DO 10 I = 1, M
  138:          IFAIL( I ) = 0
  139:    10 CONTINUE
  140: *
  141:       IF( N.LT.0 ) THEN
  142:          INFO = -1
  143:       ELSE IF( M.LT.0 .OR. M.GT.N ) THEN
  144:          INFO = -4
  145:       ELSE IF( LDZ.LT.MAX( 1, N ) ) THEN
  146:          INFO = -9
  147:       ELSE
  148:          DO 20 J = 2, M
  149:             IF( IBLOCK( J ).LT.IBLOCK( J-1 ) ) THEN
  150:                INFO = -6
  151:                GO TO 30
  152:             END IF
  153:             IF( IBLOCK( J ).EQ.IBLOCK( J-1 ) .AND. W( J ).LT.W( J-1 ) )
  154:      $           THEN
  155:                INFO = -5
  156:                GO TO 30
  157:             END IF
  158:    20    CONTINUE
  159:    30    CONTINUE
  160:       END IF
  161: *
  162:       IF( INFO.NE.0 ) THEN
  163:          CALL XERBLA( 'DSTEIN', -INFO )
  164:          RETURN
  165:       END IF
  166: *
  167: *     Quick return if possible
  168: *
  169:       IF( N.EQ.0 .OR. M.EQ.0 ) THEN
  170:          RETURN
  171:       ELSE IF( N.EQ.1 ) THEN
  172:          Z( 1, 1 ) = ONE
  173:          RETURN
  174:       END IF
  175: *
  176: *     Get machine constants.
  177: *
  178:       EPS = DLAMCH( 'Precision' )
  179: *
  180: *     Initialize seed for random number generator DLARNV.
  181: *
  182:       DO 40 I = 1, 4
  183:          ISEED( I ) = 1
  184:    40 CONTINUE
  185: *
  186: *     Initialize pointers.
  187: *
  188:       INDRV1 = 0
  189:       INDRV2 = INDRV1 + N
  190:       INDRV3 = INDRV2 + N
  191:       INDRV4 = INDRV3 + N
  192:       INDRV5 = INDRV4 + N
  193: *
  194: *     Compute eigenvectors of matrix blocks.
  195: *
  196:       J1 = 1
  197:       DO 160 NBLK = 1, IBLOCK( M )
  198: *
  199: *        Find starting and ending indices of block nblk.
  200: *
  201:          IF( NBLK.EQ.1 ) THEN
  202:             B1 = 1
  203:          ELSE
  204:             B1 = ISPLIT( NBLK-1 ) + 1
  205:          END IF
  206:          BN = ISPLIT( NBLK )
  207:          BLKSIZ = BN - B1 + 1
  208:          IF( BLKSIZ.EQ.1 )
  209:      $      GO TO 60
  210:          GPIND = B1
  211: *
  212: *        Compute reorthogonalization criterion and stopping criterion.
  213: *
  214:          ONENRM = ABS( D( B1 ) ) + ABS( E( B1 ) )
  215:          ONENRM = MAX( ONENRM, ABS( D( BN ) )+ABS( E( BN-1 ) ) )
  216:          DO 50 I = B1 + 1, BN - 1
  217:             ONENRM = MAX( ONENRM, ABS( D( I ) )+ABS( E( I-1 ) )+
  218:      $               ABS( E( I ) ) )
  219:    50    CONTINUE
  220:          ORTOL = ODM3*ONENRM
  221: *
  222:          DTPCRT = SQRT( ODM1 / BLKSIZ )
  223: *
  224: *        Loop through eigenvalues of block nblk.
  225: *
  226:    60    CONTINUE
  227:          JBLK = 0
  228:          DO 150 J = J1, M
  229:             IF( IBLOCK( J ).NE.NBLK ) THEN
  230:                J1 = J
  231:                GO TO 160
  232:             END IF
  233:             JBLK = JBLK + 1
  234:             XJ = W( J )
  235: *
  236: *           Skip all the work if the block size is one.
  237: *
  238:             IF( BLKSIZ.EQ.1 ) THEN
  239:                WORK( INDRV1+1 ) = ONE
  240:                GO TO 120
  241:             END IF
  242: *
  243: *           If eigenvalues j and j-1 are too close, add a relatively
  244: *           small perturbation.
  245: *
  246:             IF( JBLK.GT.1 ) THEN
  247:                EPS1 = ABS( EPS*XJ )
  248:                PERTOL = TEN*EPS1
  249:                SEP = XJ - XJM
  250:                IF( SEP.LT.PERTOL )
  251:      $            XJ = XJM + PERTOL
  252:             END IF
  253: *
  254:             ITS = 0
  255:             NRMCHK = 0
  256: *
  257: *           Get random starting vector.
  258: *
  259:             CALL DLARNV( 2, ISEED, BLKSIZ, WORK( INDRV1+1 ) )
  260: *
  261: *           Copy the matrix T so it won't be destroyed in factorization.
  262: *
  263:             CALL DCOPY( BLKSIZ, D( B1 ), 1, WORK( INDRV4+1 ), 1 )
  264:             CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV2+2 ), 1 )
  265:             CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV3+1 ), 1 )
  266: *
  267: *           Compute LU factors with partial pivoting  ( PT = LU )
  268: *
  269:             TOL = ZERO
  270:             CALL DLAGTF( BLKSIZ, WORK( INDRV4+1 ), XJ, WORK( INDRV2+2 ),
  271:      $                   WORK( INDRV3+1 ), TOL, WORK( INDRV5+1 ), IWORK,
  272:      $                   IINFO )
  273: *
  274: *           Update iteration count.
  275: *
  276:    70       CONTINUE
  277:             ITS = ITS + 1
  278:             IF( ITS.GT.MAXITS )
  279:      $         GO TO 100
  280: *
  281: *           Normalize and scale the righthand side vector Pb.
  282: *
  283:             SCL = BLKSIZ*ONENRM*MAX( EPS,
  284:      $            ABS( WORK( INDRV4+BLKSIZ ) ) ) /
  285:      $            DASUM( BLKSIZ, WORK( INDRV1+1 ), 1 )
  286:             CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )
  287: *
  288: *           Solve the system LU = Pb.
  289: *
  290:             CALL DLAGTS( -1, BLKSIZ, WORK( INDRV4+1 ), WORK( INDRV2+2 ),
  291:      $                   WORK( INDRV3+1 ), WORK( INDRV5+1 ), IWORK,
  292:      $                   WORK( INDRV1+1 ), TOL, IINFO )
  293: *
  294: *           Reorthogonalize by modified Gram-Schmidt if eigenvalues are
  295: *           close enough.
  296: *
  297:             IF( JBLK.EQ.1 )
  298:      $         GO TO 90
  299:             IF( ABS( XJ-XJM ).GT.ORTOL )
  300:      $         GPIND = J
  301:             IF( GPIND.NE.J ) THEN
  302:                DO 80 I = GPIND, J - 1
  303:                   ZTR = -DDOT( BLKSIZ, WORK( INDRV1+1 ), 1, Z( B1, I ),
  304:      $                  1 )
  305:                   CALL DAXPY( BLKSIZ, ZTR, Z( B1, I ), 1,
  306:      $                        WORK( INDRV1+1 ), 1 )
  307:    80          CONTINUE
  308:             END IF
  309: *
  310: *           Check the infinity norm of the iterate.
  311: *
  312:    90       CONTINUE
  313:             JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )
  314:             NRM = ABS( WORK( INDRV1+JMAX ) )
  315: *
  316: *           Continue for additional iterations after norm reaches
  317: *           stopping criterion.
  318: *
  319:             IF( NRM.LT.DTPCRT )
  320:      $         GO TO 70
  321:             NRMCHK = NRMCHK + 1
  322:             IF( NRMCHK.LT.EXTRA+1 )
  323:      $         GO TO 70
  324: *
  325:             GO TO 110
  326: *
  327: *           If stopping criterion was not satisfied, update info and
  328: *           store eigenvector number in array ifail.
  329: *
  330:   100       CONTINUE
  331:             INFO = INFO + 1
  332:             IFAIL( INFO ) = J
  333: *
  334: *           Accept iterate as jth eigenvector.
  335: *
  336:   110       CONTINUE
  337:             SCL = ONE / DNRM2( BLKSIZ, WORK( INDRV1+1 ), 1 )
  338:             JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )
  339:             IF( WORK( INDRV1+JMAX ).LT.ZERO )
  340:      $         SCL = -SCL
  341:             CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )
  342:   120       CONTINUE
  343:             DO 130 I = 1, N
  344:                Z( I, J ) = ZERO
  345:   130       CONTINUE
  346:             DO 140 I = 1, BLKSIZ
  347:                Z( B1+I-1, J ) = WORK( INDRV1+I )
  348:   140       CONTINUE
  349: *
  350: *           Save the shift to check eigenvalue spacing at next
  351: *           iteration.
  352: *
  353:             XJM = XJ
  354: *
  355:   150    CONTINUE
  356:   160 CONTINUE
  357: *
  358:       RETURN
  359: *
  360: *     End of DSTEIN
  361: *
  362:       END

CVSweb interface <joel.bertrand@systella.fr>