Annotation of rpl/lapack/lapack/dhsein.f, revision 1.1

1.1     ! bertrand    1:       SUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI,
        !             2:      $                   VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL,
        !             3:      $                   IFAILR, INFO )
        !             4: *
        !             5: *  -- LAPACK routine (version 3.2) --
        !             6: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
        !             7: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
        !             8: *     November 2006
        !             9: *
        !            10: *     .. Scalar Arguments ..
        !            11:       CHARACTER          EIGSRC, INITV, SIDE
        !            12:       INTEGER            INFO, LDH, LDVL, LDVR, M, MM, N
        !            13: *     ..
        !            14: *     .. Array Arguments ..
        !            15:       LOGICAL            SELECT( * )
        !            16:       INTEGER            IFAILL( * ), IFAILR( * )
        !            17:       DOUBLE PRECISION   H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ),
        !            18:      $                   WI( * ), WORK( * ), WR( * )
        !            19: *     ..
        !            20: *
        !            21: *  Purpose
        !            22: *  =======
        !            23: *
        !            24: *  DHSEIN uses inverse iteration to find specified right and/or left
        !            25: *  eigenvectors of a real upper Hessenberg matrix H.
        !            26: *
        !            27: *  The right eigenvector x and the left eigenvector y of the matrix H
        !            28: *  corresponding to an eigenvalue w are defined by:
        !            29: *
        !            30: *               H * x = w * x,     y**h * H = w * y**h
        !            31: *
        !            32: *  where y**h denotes the conjugate transpose of the vector y.
        !            33: *
        !            34: *  Arguments
        !            35: *  =========
        !            36: *
        !            37: *  SIDE    (input) CHARACTER*1
        !            38: *          = 'R': compute right eigenvectors only;
        !            39: *          = 'L': compute left eigenvectors only;
        !            40: *          = 'B': compute both right and left eigenvectors.
        !            41: *
        !            42: *  EIGSRC  (input) CHARACTER*1
        !            43: *          Specifies the source of eigenvalues supplied in (WR,WI):
        !            44: *          = 'Q': the eigenvalues were found using DHSEQR; thus, if
        !            45: *                 H has zero subdiagonal elements, and so is
        !            46: *                 block-triangular, then the j-th eigenvalue can be
        !            47: *                 assumed to be an eigenvalue of the block containing
        !            48: *                 the j-th row/column.  This property allows DHSEIN to
        !            49: *                 perform inverse iteration on just one diagonal block.
        !            50: *          = 'N': no assumptions are made on the correspondence
        !            51: *                 between eigenvalues and diagonal blocks.  In this
        !            52: *                 case, DHSEIN must always perform inverse iteration
        !            53: *                 using the whole matrix H.
        !            54: *
        !            55: *  INITV   (input) CHARACTER*1
        !            56: *          = 'N': no initial vectors are supplied;
        !            57: *          = 'U': user-supplied initial vectors are stored in the arrays
        !            58: *                 VL and/or VR.
        !            59: *
        !            60: *  SELECT  (input/output) LOGICAL array, dimension (N)
        !            61: *          Specifies the eigenvectors to be computed. To select the
        !            62: *          real eigenvector corresponding to a real eigenvalue WR(j),
        !            63: *          SELECT(j) must be set to .TRUE.. To select the complex
        !            64: *          eigenvector corresponding to a complex eigenvalue
        !            65: *          (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)),
        !            66: *          either SELECT(j) or SELECT(j+1) or both must be set to
        !            67: *          .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is
        !            68: *          .FALSE..
        !            69: *
        !            70: *  N       (input) INTEGER
        !            71: *          The order of the matrix H.  N >= 0.
        !            72: *
        !            73: *  H       (input) DOUBLE PRECISION array, dimension (LDH,N)
        !            74: *          The upper Hessenberg matrix H.
        !            75: *
        !            76: *  LDH     (input) INTEGER
        !            77: *          The leading dimension of the array H.  LDH >= max(1,N).
        !            78: *
        !            79: *  WR      (input/output) DOUBLE PRECISION array, dimension (N)
        !            80: *  WI      (input) DOUBLE PRECISION array, dimension (N)
        !            81: *          On entry, the real and imaginary parts of the eigenvalues of
        !            82: *          H; a complex conjugate pair of eigenvalues must be stored in
        !            83: *          consecutive elements of WR and WI.
        !            84: *          On exit, WR may have been altered since close eigenvalues
        !            85: *          are perturbed slightly in searching for independent
        !            86: *          eigenvectors.
        !            87: *
        !            88: *  VL      (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)
        !            89: *          On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must
        !            90: *          contain starting vectors for the inverse iteration for the
        !            91: *          left eigenvectors; the starting vector for each eigenvector
        !            92: *          must be in the same column(s) in which the eigenvector will
        !            93: *          be stored.
        !            94: *          On exit, if SIDE = 'L' or 'B', the left eigenvectors
        !            95: *          specified by SELECT will be stored consecutively in the
        !            96: *          columns of VL, in the same order as their eigenvalues. A
        !            97: *          complex eigenvector corresponding to a complex eigenvalue is
        !            98: *          stored in two consecutive columns, the first holding the real
        !            99: *          part and the second the imaginary part.
        !           100: *          If SIDE = 'R', VL is not referenced.
        !           101: *
        !           102: *  LDVL    (input) INTEGER
        !           103: *          The leading dimension of the array VL.
        !           104: *          LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.
        !           105: *
        !           106: *  VR      (input/output) DOUBLE PRECISION array, dimension (LDVR,MM)
        !           107: *          On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must
        !           108: *          contain starting vectors for the inverse iteration for the
        !           109: *          right eigenvectors; the starting vector for each eigenvector
        !           110: *          must be in the same column(s) in which the eigenvector will
        !           111: *          be stored.
        !           112: *          On exit, if SIDE = 'R' or 'B', the right eigenvectors
        !           113: *          specified by SELECT will be stored consecutively in the
        !           114: *          columns of VR, in the same order as their eigenvalues. A
        !           115: *          complex eigenvector corresponding to a complex eigenvalue is
        !           116: *          stored in two consecutive columns, the first holding the real
        !           117: *          part and the second the imaginary part.
        !           118: *          If SIDE = 'L', VR is not referenced.
        !           119: *
        !           120: *  LDVR    (input) INTEGER
        !           121: *          The leading dimension of the array VR.
        !           122: *          LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.
        !           123: *
        !           124: *  MM      (input) INTEGER
        !           125: *          The number of columns in the arrays VL and/or VR. MM >= M.
        !           126: *
        !           127: *  M       (output) INTEGER
        !           128: *          The number of columns in the arrays VL and/or VR required to
        !           129: *          store the eigenvectors; each selected real eigenvector
        !           130: *          occupies one column and each selected complex eigenvector
        !           131: *          occupies two columns.
        !           132: *
        !           133: *  WORK    (workspace) DOUBLE PRECISION array, dimension ((N+2)*N)
        !           134: *
        !           135: *  IFAILL  (output) INTEGER array, dimension (MM)
        !           136: *          If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left
        !           137: *          eigenvector in the i-th column of VL (corresponding to the
        !           138: *          eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the
        !           139: *          eigenvector converged satisfactorily. If the i-th and (i+1)th
        !           140: *          columns of VL hold a complex eigenvector, then IFAILL(i) and
        !           141: *          IFAILL(i+1) are set to the same value.
        !           142: *          If SIDE = 'R', IFAILL is not referenced.
        !           143: *
        !           144: *  IFAILR  (output) INTEGER array, dimension (MM)
        !           145: *          If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right
        !           146: *          eigenvector in the i-th column of VR (corresponding to the
        !           147: *          eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the
        !           148: *          eigenvector converged satisfactorily. If the i-th and (i+1)th
        !           149: *          columns of VR hold a complex eigenvector, then IFAILR(i) and
        !           150: *          IFAILR(i+1) are set to the same value.
        !           151: *          If SIDE = 'L', IFAILR is not referenced.
        !           152: *
        !           153: *  INFO    (output) INTEGER
        !           154: *          = 0:  successful exit
        !           155: *          < 0:  if INFO = -i, the i-th argument had an illegal value
        !           156: *          > 0:  if INFO = i, i is the number of eigenvectors which
        !           157: *                failed to converge; see IFAILL and IFAILR for further
        !           158: *                details.
        !           159: *
        !           160: *  Further Details
        !           161: *  ===============
        !           162: *
        !           163: *  Each eigenvector is normalized so that the element of largest
        !           164: *  magnitude has magnitude 1; here the magnitude of a complex number
        !           165: *  (x,y) is taken to be |x|+|y|.
        !           166: *
        !           167: *  =====================================================================
        !           168: *
        !           169: *     .. Parameters ..
        !           170:       DOUBLE PRECISION   ZERO, ONE
        !           171:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
        !           172: *     ..
        !           173: *     .. Local Scalars ..
        !           174:       LOGICAL            BOTHV, FROMQR, LEFTV, NOINIT, PAIR, RIGHTV
        !           175:       INTEGER            I, IINFO, K, KL, KLN, KR, KSI, KSR, LDWORK
        !           176:       DOUBLE PRECISION   BIGNUM, EPS3, HNORM, SMLNUM, ULP, UNFL, WKI,
        !           177:      $                   WKR
        !           178: *     ..
        !           179: *     .. External Functions ..
        !           180:       LOGICAL            LSAME
        !           181:       DOUBLE PRECISION   DLAMCH, DLANHS
        !           182:       EXTERNAL           LSAME, DLAMCH, DLANHS
        !           183: *     ..
        !           184: *     .. External Subroutines ..
        !           185:       EXTERNAL           DLAEIN, XERBLA
        !           186: *     ..
        !           187: *     .. Intrinsic Functions ..
        !           188:       INTRINSIC          ABS, MAX
        !           189: *     ..
        !           190: *     .. Executable Statements ..
        !           191: *
        !           192: *     Decode and test the input parameters.
        !           193: *
        !           194:       BOTHV = LSAME( SIDE, 'B' )
        !           195:       RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
        !           196:       LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
        !           197: *
        !           198:       FROMQR = LSAME( EIGSRC, 'Q' )
        !           199: *
        !           200:       NOINIT = LSAME( INITV, 'N' )
        !           201: *
        !           202: *     Set M to the number of columns required to store the selected
        !           203: *     eigenvectors, and standardize the array SELECT.
        !           204: *
        !           205:       M = 0
        !           206:       PAIR = .FALSE.
        !           207:       DO 10 K = 1, N
        !           208:          IF( PAIR ) THEN
        !           209:             PAIR = .FALSE.
        !           210:             SELECT( K ) = .FALSE.
        !           211:          ELSE
        !           212:             IF( WI( K ).EQ.ZERO ) THEN
        !           213:                IF( SELECT( K ) )
        !           214:      $            M = M + 1
        !           215:             ELSE
        !           216:                PAIR = .TRUE.
        !           217:                IF( SELECT( K ) .OR. SELECT( K+1 ) ) THEN
        !           218:                   SELECT( K ) = .TRUE.
        !           219:                   M = M + 2
        !           220:                END IF
        !           221:             END IF
        !           222:          END IF
        !           223:    10 CONTINUE
        !           224: *
        !           225:       INFO = 0
        !           226:       IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
        !           227:          INFO = -1
        !           228:       ELSE IF( .NOT.FROMQR .AND. .NOT.LSAME( EIGSRC, 'N' ) ) THEN
        !           229:          INFO = -2
        !           230:       ELSE IF( .NOT.NOINIT .AND. .NOT.LSAME( INITV, 'U' ) ) THEN
        !           231:          INFO = -3
        !           232:       ELSE IF( N.LT.0 ) THEN
        !           233:          INFO = -5
        !           234:       ELSE IF( LDH.LT.MAX( 1, N ) ) THEN
        !           235:          INFO = -7
        !           236:       ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
        !           237:          INFO = -11
        !           238:       ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
        !           239:          INFO = -13
        !           240:       ELSE IF( MM.LT.M ) THEN
        !           241:          INFO = -14
        !           242:       END IF
        !           243:       IF( INFO.NE.0 ) THEN
        !           244:          CALL XERBLA( 'DHSEIN', -INFO )
        !           245:          RETURN
        !           246:       END IF
        !           247: *
        !           248: *     Quick return if possible.
        !           249: *
        !           250:       IF( N.EQ.0 )
        !           251:      $   RETURN
        !           252: *
        !           253: *     Set machine-dependent constants.
        !           254: *
        !           255:       UNFL = DLAMCH( 'Safe minimum' )
        !           256:       ULP = DLAMCH( 'Precision' )
        !           257:       SMLNUM = UNFL*( N / ULP )
        !           258:       BIGNUM = ( ONE-ULP ) / SMLNUM
        !           259: *
        !           260:       LDWORK = N + 1
        !           261: *
        !           262:       KL = 1
        !           263:       KLN = 0
        !           264:       IF( FROMQR ) THEN
        !           265:          KR = 0
        !           266:       ELSE
        !           267:          KR = N
        !           268:       END IF
        !           269:       KSR = 1
        !           270: *
        !           271:       DO 120 K = 1, N
        !           272:          IF( SELECT( K ) ) THEN
        !           273: *
        !           274: *           Compute eigenvector(s) corresponding to W(K).
        !           275: *
        !           276:             IF( FROMQR ) THEN
        !           277: *
        !           278: *              If affiliation of eigenvalues is known, check whether
        !           279: *              the matrix splits.
        !           280: *
        !           281: *              Determine KL and KR such that 1 <= KL <= K <= KR <= N
        !           282: *              and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or
        !           283: *              KR = N).
        !           284: *
        !           285: *              Then inverse iteration can be performed with the
        !           286: *              submatrix H(KL:N,KL:N) for a left eigenvector, and with
        !           287: *              the submatrix H(1:KR,1:KR) for a right eigenvector.
        !           288: *
        !           289:                DO 20 I = K, KL + 1, -1
        !           290:                   IF( H( I, I-1 ).EQ.ZERO )
        !           291:      $               GO TO 30
        !           292:    20          CONTINUE
        !           293:    30          CONTINUE
        !           294:                KL = I
        !           295:                IF( K.GT.KR ) THEN
        !           296:                   DO 40 I = K, N - 1
        !           297:                      IF( H( I+1, I ).EQ.ZERO )
        !           298:      $                  GO TO 50
        !           299:    40             CONTINUE
        !           300:    50             CONTINUE
        !           301:                   KR = I
        !           302:                END IF
        !           303:             END IF
        !           304: *
        !           305:             IF( KL.NE.KLN ) THEN
        !           306:                KLN = KL
        !           307: *
        !           308: *              Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it
        !           309: *              has not ben computed before.
        !           310: *
        !           311:                HNORM = DLANHS( 'I', KR-KL+1, H( KL, KL ), LDH, WORK )
        !           312:                IF( HNORM.GT.ZERO ) THEN
        !           313:                   EPS3 = HNORM*ULP
        !           314:                ELSE
        !           315:                   EPS3 = SMLNUM
        !           316:                END IF
        !           317:             END IF
        !           318: *
        !           319: *           Perturb eigenvalue if it is close to any previous
        !           320: *           selected eigenvalues affiliated to the submatrix
        !           321: *           H(KL:KR,KL:KR). Close roots are modified by EPS3.
        !           322: *
        !           323:             WKR = WR( K )
        !           324:             WKI = WI( K )
        !           325:    60       CONTINUE
        !           326:             DO 70 I = K - 1, KL, -1
        !           327:                IF( SELECT( I ) .AND. ABS( WR( I )-WKR )+
        !           328:      $             ABS( WI( I )-WKI ).LT.EPS3 ) THEN
        !           329:                   WKR = WKR + EPS3
        !           330:                   GO TO 60
        !           331:                END IF
        !           332:    70       CONTINUE
        !           333:             WR( K ) = WKR
        !           334: *
        !           335:             PAIR = WKI.NE.ZERO
        !           336:             IF( PAIR ) THEN
        !           337:                KSI = KSR + 1
        !           338:             ELSE
        !           339:                KSI = KSR
        !           340:             END IF
        !           341:             IF( LEFTV ) THEN
        !           342: *
        !           343: *              Compute left eigenvector.
        !           344: *
        !           345:                CALL DLAEIN( .FALSE., NOINIT, N-KL+1, H( KL, KL ), LDH,
        !           346:      $                      WKR, WKI, VL( KL, KSR ), VL( KL, KSI ),
        !           347:      $                      WORK, LDWORK, WORK( N*N+N+1 ), EPS3, SMLNUM,
        !           348:      $                      BIGNUM, IINFO )
        !           349:                IF( IINFO.GT.0 ) THEN
        !           350:                   IF( PAIR ) THEN
        !           351:                      INFO = INFO + 2
        !           352:                   ELSE
        !           353:                      INFO = INFO + 1
        !           354:                   END IF
        !           355:                   IFAILL( KSR ) = K
        !           356:                   IFAILL( KSI ) = K
        !           357:                ELSE
        !           358:                   IFAILL( KSR ) = 0
        !           359:                   IFAILL( KSI ) = 0
        !           360:                END IF
        !           361:                DO 80 I = 1, KL - 1
        !           362:                   VL( I, KSR ) = ZERO
        !           363:    80          CONTINUE
        !           364:                IF( PAIR ) THEN
        !           365:                   DO 90 I = 1, KL - 1
        !           366:                      VL( I, KSI ) = ZERO
        !           367:    90             CONTINUE
        !           368:                END IF
        !           369:             END IF
        !           370:             IF( RIGHTV ) THEN
        !           371: *
        !           372: *              Compute right eigenvector.
        !           373: *
        !           374:                CALL DLAEIN( .TRUE., NOINIT, KR, H, LDH, WKR, WKI,
        !           375:      $                      VR( 1, KSR ), VR( 1, KSI ), WORK, LDWORK,
        !           376:      $                      WORK( N*N+N+1 ), EPS3, SMLNUM, BIGNUM,
        !           377:      $                      IINFO )
        !           378:                IF( IINFO.GT.0 ) THEN
        !           379:                   IF( PAIR ) THEN
        !           380:                      INFO = INFO + 2
        !           381:                   ELSE
        !           382:                      INFO = INFO + 1
        !           383:                   END IF
        !           384:                   IFAILR( KSR ) = K
        !           385:                   IFAILR( KSI ) = K
        !           386:                ELSE
        !           387:                   IFAILR( KSR ) = 0
        !           388:                   IFAILR( KSI ) = 0
        !           389:                END IF
        !           390:                DO 100 I = KR + 1, N
        !           391:                   VR( I, KSR ) = ZERO
        !           392:   100          CONTINUE
        !           393:                IF( PAIR ) THEN
        !           394:                   DO 110 I = KR + 1, N
        !           395:                      VR( I, KSI ) = ZERO
        !           396:   110             CONTINUE
        !           397:                END IF
        !           398:             END IF
        !           399: *
        !           400:             IF( PAIR ) THEN
        !           401:                KSR = KSR + 2
        !           402:             ELSE
        !           403:                KSR = KSR + 1
        !           404:             END IF
        !           405:          END IF
        !           406:   120 CONTINUE
        !           407: *
        !           408:       RETURN
        !           409: *
        !           410: *     End of DHSEIN
        !           411: *
        !           412:       END

CVSweb interface <joel.bertrand@systella.fr>