LAPACK 3.3.0

ztrsna.f

Go to the documentation of this file.
00001       SUBROUTINE ZTRSNA( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
00002      $                   LDVR, S, SEP, MM, M, WORK, LDWORK, RWORK,
00003      $                   INFO )
00004 *
00005 *  -- LAPACK routine (version 3.2) --
00006 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00007 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00008 *     November 2006
00009 *
00010 *     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH.
00011 *
00012 *     .. Scalar Arguments ..
00013       CHARACTER          HOWMNY, JOB
00014       INTEGER            INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N
00015 *     ..
00016 *     .. Array Arguments ..
00017       LOGICAL            SELECT( * )
00018       DOUBLE PRECISION   RWORK( * ), S( * ), SEP( * )
00019       COMPLEX*16         T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
00020      $                   WORK( LDWORK, * )
00021 *     ..
00022 *
00023 *  Purpose
00024 *  =======
00025 *
00026 *  ZTRSNA estimates reciprocal condition numbers for specified
00027 *  eigenvalues and/or right eigenvectors of a complex upper triangular
00028 *  matrix T (or of any matrix Q*T*Q**H with Q unitary).
00029 *
00030 *  Arguments
00031 *  =========
00032 *
00033 *  JOB     (input) CHARACTER*1
00034 *          Specifies whether condition numbers are required for
00035 *          eigenvalues (S) or eigenvectors (SEP):
00036 *          = 'E': for eigenvalues only (S);
00037 *          = 'V': for eigenvectors only (SEP);
00038 *          = 'B': for both eigenvalues and eigenvectors (S and SEP).
00039 *
00040 *  HOWMNY  (input) CHARACTER*1
00041 *          = 'A': compute condition numbers for all eigenpairs;
00042 *          = 'S': compute condition numbers for selected eigenpairs
00043 *                 specified by the array SELECT.
00044 *
00045 *  SELECT  (input) LOGICAL array, dimension (N)
00046 *          If HOWMNY = 'S', SELECT specifies the eigenpairs for which
00047 *          condition numbers are required. To select condition numbers
00048 *          for the j-th eigenpair, SELECT(j) must be set to .TRUE..
00049 *          If HOWMNY = 'A', SELECT is not referenced.
00050 *
00051 *  N       (input) INTEGER
00052 *          The order of the matrix T. N >= 0.
00053 *
00054 *  T       (input) COMPLEX*16 array, dimension (LDT,N)
00055 *          The upper triangular matrix T.
00056 *
00057 *  LDT     (input) INTEGER
00058 *          The leading dimension of the array T. LDT >= max(1,N).
00059 *
00060 *  VL      (input) COMPLEX*16 array, dimension (LDVL,M)
00061 *          If JOB = 'E' or 'B', VL must contain left eigenvectors of T
00062 *          (or of any Q*T*Q**H with Q unitary), corresponding to the
00063 *          eigenpairs specified by HOWMNY and SELECT. The eigenvectors
00064 *          must be stored in consecutive columns of VL, as returned by
00065 *          ZHSEIN or ZTREVC.
00066 *          If JOB = 'V', VL is not referenced.
00067 *
00068 *  LDVL    (input) INTEGER
00069 *          The leading dimension of the array VL.
00070 *          LDVL >= 1; and if JOB = 'E' or 'B', LDVL >= N.
00071 *
00072 *  VR      (input) COMPLEX*16 array, dimension (LDVR,M)
00073 *          If JOB = 'E' or 'B', VR must contain right eigenvectors of T
00074 *          (or of any Q*T*Q**H with Q unitary), corresponding to the
00075 *          eigenpairs specified by HOWMNY and SELECT. The eigenvectors
00076 *          must be stored in consecutive columns of VR, as returned by
00077 *          ZHSEIN or ZTREVC.
00078 *          If JOB = 'V', VR is not referenced.
00079 *
00080 *  LDVR    (input) INTEGER
00081 *          The leading dimension of the array VR.
00082 *          LDVR >= 1; and if JOB = 'E' or 'B', LDVR >= N.
00083 *
00084 *  S       (output) DOUBLE PRECISION array, dimension (MM)
00085 *          If JOB = 'E' or 'B', the reciprocal condition numbers of the
00086 *          selected eigenvalues, stored in consecutive elements of the
00087 *          array. Thus S(j), SEP(j), and the j-th columns of VL and VR
00088 *          all correspond to the same eigenpair (but not in general the
00089 *          j-th eigenpair, unless all eigenpairs are selected).
00090 *          If JOB = 'V', S is not referenced.
00091 *
00092 *  SEP     (output) DOUBLE PRECISION array, dimension (MM)
00093 *          If JOB = 'V' or 'B', the estimated reciprocal condition
00094 *          numbers of the selected eigenvectors, stored in consecutive
00095 *          elements of the array.
00096 *          If JOB = 'E', SEP is not referenced.
00097 *
00098 *  MM      (input) INTEGER
00099 *          The number of elements in the arrays S (if JOB = 'E' or 'B')
00100 *           and/or SEP (if JOB = 'V' or 'B'). MM >= M.
00101 *
00102 *  M       (output) INTEGER
00103 *          The number of elements of the arrays S and/or SEP actually
00104 *          used to store the estimated condition numbers.
00105 *          If HOWMNY = 'A', M is set to N.
00106 *
00107 *  WORK    (workspace) COMPLEX*16 array, dimension (LDWORK,N+6)
00108 *          If JOB = 'E', WORK is not referenced.
00109 *
00110 *  LDWORK  (input) INTEGER
00111 *          The leading dimension of the array WORK.
00112 *          LDWORK >= 1; and if JOB = 'V' or 'B', LDWORK >= N.
00113 *
00114 *  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
00115 *          If JOB = 'E', RWORK is not referenced.
00116 *
00117 *  INFO    (output) INTEGER
00118 *          = 0: successful exit
00119 *          < 0: if INFO = -i, the i-th argument had an illegal value
00120 *
00121 *  Further Details
00122 *  ===============
00123 *
00124 *  The reciprocal of the condition number of an eigenvalue lambda is
00125 *  defined as
00126 *
00127 *          S(lambda) = |v'*u| / (norm(u)*norm(v))
00128 *
00129 *  where u and v are the right and left eigenvectors of T corresponding
00130 *  to lambda; v' denotes the conjugate transpose of v, and norm(u)
00131 *  denotes the Euclidean norm. These reciprocal condition numbers always
00132 *  lie between zero (very badly conditioned) and one (very well
00133 *  conditioned). If n = 1, S(lambda) is defined to be 1.
00134 *
00135 *  An approximate error bound for a computed eigenvalue W(i) is given by
00136 *
00137 *                      EPS * norm(T) / S(i)
00138 *
00139 *  where EPS is the machine precision.
00140 *
00141 *  The reciprocal of the condition number of the right eigenvector u
00142 *  corresponding to lambda is defined as follows. Suppose
00143 *
00144 *              T = ( lambda  c  )
00145 *                  (   0    T22 )
00146 *
00147 *  Then the reciprocal condition number is
00148 *
00149 *          SEP( lambda, T22 ) = sigma-min( T22 - lambda*I )
00150 *
00151 *  where sigma-min denotes the smallest singular value. We approximate
00152 *  the smallest singular value by the reciprocal of an estimate of the
00153 *  one-norm of the inverse of T22 - lambda*I. If n = 1, SEP(1) is
00154 *  defined to be abs(T(1,1)).
00155 *
00156 *  An approximate error bound for a computed right eigenvector VR(i)
00157 *  is given by
00158 *
00159 *                      EPS * norm(T) / SEP(i)
00160 *
00161 *  =====================================================================
00162 *
00163 *     .. Parameters ..
00164       DOUBLE PRECISION   ZERO, ONE
00165       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D0+0 )
00166 *     ..
00167 *     .. Local Scalars ..
00168       LOGICAL            SOMCON, WANTBH, WANTS, WANTSP
00169       CHARACTER          NORMIN
00170       INTEGER            I, IERR, IX, J, K, KASE, KS
00171       DOUBLE PRECISION   BIGNUM, EPS, EST, LNRM, RNRM, SCALE, SMLNUM,
00172      $                   XNORM
00173       COMPLEX*16         CDUM, PROD
00174 *     ..
00175 *     .. Local Arrays ..
00176       INTEGER            ISAVE( 3 )
00177       COMPLEX*16         DUMMY( 1 )
00178 *     ..
00179 *     .. External Functions ..
00180       LOGICAL            LSAME
00181       INTEGER            IZAMAX
00182       DOUBLE PRECISION   DLAMCH, DZNRM2
00183       COMPLEX*16         ZDOTC
00184       EXTERNAL           LSAME, IZAMAX, DLAMCH, DZNRM2, ZDOTC
00185 *     ..
00186 *     .. External Subroutines ..
00187       EXTERNAL           XERBLA, ZDRSCL, ZLACN2, ZLACPY, ZLATRS, ZTREXC
00188 *     ..
00189 *     .. Intrinsic Functions ..
00190       INTRINSIC          ABS, DBLE, DIMAG, MAX
00191 *     ..
00192 *     .. Statement Functions ..
00193       DOUBLE PRECISION   CABS1
00194 *     ..
00195 *     .. Statement Function definitions ..
00196       CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
00197 *     ..
00198 *     .. Executable Statements ..
00199 *
00200 *     Decode and test the input parameters
00201 *
00202       WANTBH = LSAME( JOB, 'B' )
00203       WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
00204       WANTSP = LSAME( JOB, 'V' ) .OR. WANTBH
00205 *
00206       SOMCON = LSAME( HOWMNY, 'S' )
00207 *
00208 *     Set M to the number of eigenpairs for which condition numbers are
00209 *     to be computed.
00210 *
00211       IF( SOMCON ) THEN
00212          M = 0
00213          DO 10 J = 1, N
00214             IF( SELECT( J ) )
00215      $         M = M + 1
00216    10    CONTINUE
00217       ELSE
00218          M = N
00219       END IF
00220 *
00221       INFO = 0
00222       IF( .NOT.WANTS .AND. .NOT.WANTSP ) THEN
00223          INFO = -1
00224       ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THEN
00225          INFO = -2
00226       ELSE IF( N.LT.0 ) THEN
00227          INFO = -4
00228       ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
00229          INFO = -6
00230       ELSE IF( LDVL.LT.1 .OR. ( WANTS .AND. LDVL.LT.N ) ) THEN
00231          INFO = -8
00232       ELSE IF( LDVR.LT.1 .OR. ( WANTS .AND. LDVR.LT.N ) ) THEN
00233          INFO = -10
00234       ELSE IF( MM.LT.M ) THEN
00235          INFO = -13
00236       ELSE IF( LDWORK.LT.1 .OR. ( WANTSP .AND. LDWORK.LT.N ) ) THEN
00237          INFO = -16
00238       END IF
00239       IF( INFO.NE.0 ) THEN
00240          CALL XERBLA( 'ZTRSNA', -INFO )
00241          RETURN
00242       END IF
00243 *
00244 *     Quick return if possible
00245 *
00246       IF( N.EQ.0 )
00247      $   RETURN
00248 *
00249       IF( N.EQ.1 ) THEN
00250          IF( SOMCON ) THEN
00251             IF( .NOT.SELECT( 1 ) )
00252      $         RETURN
00253          END IF
00254          IF( WANTS )
00255      $      S( 1 ) = ONE
00256          IF( WANTSP )
00257      $      SEP( 1 ) = ABS( T( 1, 1 ) )
00258          RETURN
00259       END IF
00260 *
00261 *     Get machine constants
00262 *
00263       EPS = DLAMCH( 'P' )
00264       SMLNUM = DLAMCH( 'S' ) / EPS
00265       BIGNUM = ONE / SMLNUM
00266       CALL DLABAD( SMLNUM, BIGNUM )
00267 *
00268       KS = 1
00269       DO 50 K = 1, N
00270 *
00271          IF( SOMCON ) THEN
00272             IF( .NOT.SELECT( K ) )
00273      $         GO TO 50
00274          END IF
00275 *
00276          IF( WANTS ) THEN
00277 *
00278 *           Compute the reciprocal condition number of the k-th
00279 *           eigenvalue.
00280 *
00281             PROD = ZDOTC( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )
00282             RNRM = DZNRM2( N, VR( 1, KS ), 1 )
00283             LNRM = DZNRM2( N, VL( 1, KS ), 1 )
00284             S( KS ) = ABS( PROD ) / ( RNRM*LNRM )
00285 *
00286          END IF
00287 *
00288          IF( WANTSP ) THEN
00289 *
00290 *           Estimate the reciprocal condition number of the k-th
00291 *           eigenvector.
00292 *
00293 *           Copy the matrix T to the array WORK and swap the k-th
00294 *           diagonal element to the (1,1) position.
00295 *
00296             CALL ZLACPY( 'Full', N, N, T, LDT, WORK, LDWORK )
00297             CALL ZTREXC( 'No Q', N, WORK, LDWORK, DUMMY, 1, K, 1, IERR )
00298 *
00299 *           Form  C = T22 - lambda*I in WORK(2:N,2:N).
00300 *
00301             DO 20 I = 2, N
00302                WORK( I, I ) = WORK( I, I ) - WORK( 1, 1 )
00303    20       CONTINUE
00304 *
00305 *           Estimate a lower bound for the 1-norm of inv(C'). The 1st
00306 *           and (N+1)th columns of WORK are used to store work vectors.
00307 *
00308             SEP( KS ) = ZERO
00309             EST = ZERO
00310             KASE = 0
00311             NORMIN = 'N'
00312    30       CONTINUE
00313             CALL ZLACN2( N-1, WORK( 1, N+1 ), WORK, EST, KASE, ISAVE )
00314 *
00315             IF( KASE.NE.0 ) THEN
00316                IF( KASE.EQ.1 ) THEN
00317 *
00318 *                 Solve C'*x = scale*b
00319 *
00320                   CALL ZLATRS( 'Upper', 'Conjugate transpose',
00321      $                         'Nonunit', NORMIN, N-1, WORK( 2, 2 ),
00322      $                         LDWORK, WORK, SCALE, RWORK, IERR )
00323                ELSE
00324 *
00325 *                 Solve C*x = scale*b
00326 *
00327                   CALL ZLATRS( 'Upper', 'No transpose', 'Nonunit',
00328      $                         NORMIN, N-1, WORK( 2, 2 ), LDWORK, WORK,
00329      $                         SCALE, RWORK, IERR )
00330                END IF
00331                NORMIN = 'Y'
00332                IF( SCALE.NE.ONE ) THEN
00333 *
00334 *                 Multiply by 1/SCALE if doing so will not cause
00335 *                 overflow.
00336 *
00337                   IX = IZAMAX( N-1, WORK, 1 )
00338                   XNORM = CABS1( WORK( IX, 1 ) )
00339                   IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )
00340      $               GO TO 40
00341                   CALL ZDRSCL( N, SCALE, WORK, 1 )
00342                END IF
00343                GO TO 30
00344             END IF
00345 *
00346             SEP( KS ) = ONE / MAX( EST, SMLNUM )
00347          END IF
00348 *
00349    40    CONTINUE
00350          KS = KS + 1
00351    50 CONTINUE
00352       RETURN
00353 *
00354 *     End of ZTRSNA
00355 *
00356       END
 All Files Functions