LAPACK 3.3.1
Linear Algebra PACKage

dlar1v.f

Go to the documentation of this file.
00001       SUBROUTINE DLAR1V( N, B1, BN, LAMBDA, D, L, LD, LLD,
00002      $           PIVMIN, GAPTOL, Z, WANTNC, NEGCNT, ZTZ, MINGMA,
00003      $           R, ISUPPZ, NRMINV, RESID, RQCORR, WORK )
00004 *
00005 *  -- LAPACK auxiliary routine (version 3.3.1) --
00006 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00007 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00008 *  -- April 2011                                                      --
00009 *
00010 *     .. Scalar Arguments ..
00011       LOGICAL            WANTNC
00012       INTEGER   B1, BN, N, NEGCNT, R
00013       DOUBLE PRECISION   GAPTOL, LAMBDA, MINGMA, NRMINV, PIVMIN, RESID,
00014      $                   RQCORR, ZTZ
00015 *     ..
00016 *     .. Array Arguments ..
00017       INTEGER            ISUPPZ( * )
00018       DOUBLE PRECISION   D( * ), L( * ), LD( * ), LLD( * ),
00019      $                  WORK( * )
00020       DOUBLE PRECISION Z( * )
00021 *     ..
00022 *
00023 *  Purpose
00024 *  =======
00025 *
00026 *  DLAR1V computes the (scaled) r-th column of the inverse of
00027 *  the sumbmatrix in rows B1 through BN of the tridiagonal matrix
00028 *  L D L**T - sigma I. When sigma is close to an eigenvalue, the
00029 *  computed vector is an accurate eigenvector. Usually, r corresponds
00030 *  to the index where the eigenvector is largest in magnitude.
00031 *  The following steps accomplish this computation :
00032 *  (a) Stationary qd transform,  L D L**T - sigma I = L(+) D(+) L(+)**T,
00033 *  (b) Progressive qd transform, L D L**T - sigma I = U(-) D(-) U(-)**T,
00034 *  (c) Computation of the diagonal elements of the inverse of
00035 *      L D L**T - sigma I by combining the above transforms, and choosing
00036 *      r as the index where the diagonal of the inverse is (one of the)
00037 *      largest in magnitude.
00038 *  (d) Computation of the (scaled) r-th column of the inverse using the
00039 *      twisted factorization obtained by combining the top part of the
00040 *      the stationary and the bottom part of the progressive transform.
00041 *
00042 *  Arguments
00043 *  =========
00044 *
00045 *  N        (input) INTEGER
00046 *           The order of the matrix L D L**T.
00047 *
00048 *  B1       (input) INTEGER
00049 *           First index of the submatrix of L D L**T.
00050 *
00051 *  BN       (input) INTEGER
00052 *           Last index of the submatrix of L D L**T.
00053 *
00054 *  LAMBDA    (input) DOUBLE PRECISION
00055 *           The shift. In order to compute an accurate eigenvector,
00056 *           LAMBDA should be a good approximation to an eigenvalue
00057 *           of L D L**T.
00058 *
00059 *  L        (input) DOUBLE PRECISION array, dimension (N-1)
00060 *           The (n-1) subdiagonal elements of the unit bidiagonal matrix
00061 *           L, in elements 1 to N-1.
00062 *
00063 *  D        (input) DOUBLE PRECISION array, dimension (N)
00064 *           The n diagonal elements of the diagonal matrix D.
00065 *
00066 *  LD       (input) DOUBLE PRECISION array, dimension (N-1)
00067 *           The n-1 elements L(i)*D(i).
00068 *
00069 *  LLD      (input) DOUBLE PRECISION array, dimension (N-1)
00070 *           The n-1 elements L(i)*L(i)*D(i).
00071 *
00072 *  PIVMIN   (input) DOUBLE PRECISION
00073 *           The minimum pivot in the Sturm sequence.
00074 *
00075 *  GAPTOL   (input) DOUBLE PRECISION
00076 *           Tolerance that indicates when eigenvector entries are negligible
00077 *           w.r.t. their contribution to the residual.
00078 *
00079 *  Z        (input/output) DOUBLE PRECISION array, dimension (N)
00080 *           On input, all entries of Z must be set to 0.
00081 *           On output, Z contains the (scaled) r-th column of the
00082 *           inverse. The scaling is such that Z(R) equals 1.
00083 *
00084 *  WANTNC   (input) LOGICAL
00085 *           Specifies whether NEGCNT has to be computed.
00086 *
00087 *  NEGCNT   (output) INTEGER
00088 *           If WANTNC is .TRUE. then NEGCNT = the number of pivots < pivmin
00089 *           in the  matrix factorization L D L**T, and NEGCNT = -1 otherwise.
00090 *
00091 *  ZTZ      (output) DOUBLE PRECISION
00092 *           The square of the 2-norm of Z.
00093 *
00094 *  MINGMA   (output) DOUBLE PRECISION
00095 *           The reciprocal of the largest (in magnitude) diagonal
00096 *           element of the inverse of L D L**T - sigma I.
00097 *
00098 *  R        (input/output) INTEGER
00099 *           The twist index for the twisted factorization used to
00100 *           compute Z.
00101 *           On input, 0 <= R <= N. If R is input as 0, R is set to
00102 *           the index where (L D L**T - sigma I)^{-1} is largest
00103 *           in magnitude. If 1 <= R <= N, R is unchanged.
00104 *           On output, R contains the twist index used to compute Z.
00105 *           Ideally, R designates the position of the maximum entry in the
00106 *           eigenvector.
00107 *
00108 *  ISUPPZ   (output) INTEGER array, dimension (2)
00109 *           The support of the vector in Z, i.e., the vector Z is
00110 *           nonzero only in elements ISUPPZ(1) through ISUPPZ( 2 ).
00111 *
00112 *  NRMINV   (output) DOUBLE PRECISION
00113 *           NRMINV = 1/SQRT( ZTZ )
00114 *
00115 *  RESID    (output) DOUBLE PRECISION
00116 *           The residual of the FP vector.
00117 *           RESID = ABS( MINGMA )/SQRT( ZTZ )
00118 *
00119 *  RQCORR   (output) DOUBLE PRECISION
00120 *           The Rayleigh Quotient correction to LAMBDA.
00121 *           RQCORR = MINGMA*TMP
00122 *
00123 *  WORK     (workspace) DOUBLE PRECISION array, dimension (4*N)
00124 *
00125 *  Further Details
00126 *  ===============
00127 *
00128 *  Based on contributions by
00129 *     Beresford Parlett, University of California, Berkeley, USA
00130 *     Jim Demmel, University of California, Berkeley, USA
00131 *     Inderjit Dhillon, University of Texas, Austin, USA
00132 *     Osni Marques, LBNL/NERSC, USA
00133 *     Christof Voemel, University of California, Berkeley, USA
00134 *
00135 *  =====================================================================
00136 *
00137 *     .. Parameters ..
00138       DOUBLE PRECISION   ZERO, ONE
00139       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00140 
00141 *     ..
00142 *     .. Local Scalars ..
00143       LOGICAL            SAWNAN1, SAWNAN2
00144       INTEGER            I, INDLPL, INDP, INDS, INDUMN, NEG1, NEG2, R1,
00145      $                   R2
00146       DOUBLE PRECISION   DMINUS, DPLUS, EPS, S, TMP
00147 *     ..
00148 *     .. External Functions ..
00149       LOGICAL DISNAN
00150       DOUBLE PRECISION   DLAMCH
00151       EXTERNAL           DISNAN, DLAMCH
00152 *     ..
00153 *     .. Intrinsic Functions ..
00154       INTRINSIC          ABS
00155 *     ..
00156 *     .. Executable Statements ..
00157 *
00158       EPS = DLAMCH( 'Precision' )
00159 
00160 
00161       IF( R.EQ.0 ) THEN
00162          R1 = B1
00163          R2 = BN
00164       ELSE
00165          R1 = R
00166          R2 = R
00167       END IF
00168 
00169 *     Storage for LPLUS
00170       INDLPL = 0
00171 *     Storage for UMINUS
00172       INDUMN = N
00173       INDS = 2*N + 1
00174       INDP = 3*N + 1
00175 
00176       IF( B1.EQ.1 ) THEN
00177          WORK( INDS ) = ZERO
00178       ELSE
00179          WORK( INDS+B1-1 ) = LLD( B1-1 )
00180       END IF
00181 
00182 *
00183 *     Compute the stationary transform (using the differential form)
00184 *     until the index R2.
00185 *
00186       SAWNAN1 = .FALSE.
00187       NEG1 = 0
00188       S = WORK( INDS+B1-1 ) - LAMBDA
00189       DO 50 I = B1, R1 - 1
00190          DPLUS = D( I ) + S
00191          WORK( INDLPL+I ) = LD( I ) / DPLUS
00192          IF(DPLUS.LT.ZERO) NEG1 = NEG1 + 1
00193          WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
00194          S = WORK( INDS+I ) - LAMBDA
00195  50   CONTINUE
00196       SAWNAN1 = DISNAN( S )
00197       IF( SAWNAN1 ) GOTO 60
00198       DO 51 I = R1, R2 - 1
00199          DPLUS = D( I ) + S
00200          WORK( INDLPL+I ) = LD( I ) / DPLUS
00201          WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
00202          S = WORK( INDS+I ) - LAMBDA
00203  51   CONTINUE
00204       SAWNAN1 = DISNAN( S )
00205 *
00206  60   CONTINUE
00207       IF( SAWNAN1 ) THEN
00208 *        Runs a slower version of the above loop if a NaN is detected
00209          NEG1 = 0
00210          S = WORK( INDS+B1-1 ) - LAMBDA
00211          DO 70 I = B1, R1 - 1
00212             DPLUS = D( I ) + S
00213             IF(ABS(DPLUS).LT.PIVMIN) DPLUS = -PIVMIN
00214             WORK( INDLPL+I ) = LD( I ) / DPLUS
00215             IF(DPLUS.LT.ZERO) NEG1 = NEG1 + 1
00216             WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
00217             IF( WORK( INDLPL+I ).EQ.ZERO )
00218      $                      WORK( INDS+I ) = LLD( I )
00219             S = WORK( INDS+I ) - LAMBDA
00220  70      CONTINUE
00221          DO 71 I = R1, R2 - 1
00222             DPLUS = D( I ) + S
00223             IF(ABS(DPLUS).LT.PIVMIN) DPLUS = -PIVMIN
00224             WORK( INDLPL+I ) = LD( I ) / DPLUS
00225             WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
00226             IF( WORK( INDLPL+I ).EQ.ZERO )
00227      $                      WORK( INDS+I ) = LLD( I )
00228             S = WORK( INDS+I ) - LAMBDA
00229  71      CONTINUE
00230       END IF
00231 *
00232 *     Compute the progressive transform (using the differential form)
00233 *     until the index R1
00234 *
00235       SAWNAN2 = .FALSE.
00236       NEG2 = 0
00237       WORK( INDP+BN-1 ) = D( BN ) - LAMBDA
00238       DO 80 I = BN - 1, R1, -1
00239          DMINUS = LLD( I ) + WORK( INDP+I )
00240          TMP = D( I ) / DMINUS
00241          IF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1
00242          WORK( INDUMN+I ) = L( I )*TMP
00243          WORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDA
00244  80   CONTINUE
00245       TMP = WORK( INDP+R1-1 )
00246       SAWNAN2 = DISNAN( TMP )
00247 
00248       IF( SAWNAN2 ) THEN
00249 *        Runs a slower version of the above loop if a NaN is detected
00250          NEG2 = 0
00251          DO 100 I = BN-1, R1, -1
00252             DMINUS = LLD( I ) + WORK( INDP+I )
00253             IF(ABS(DMINUS).LT.PIVMIN) DMINUS = -PIVMIN
00254             TMP = D( I ) / DMINUS
00255             IF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1
00256             WORK( INDUMN+I ) = L( I )*TMP
00257             WORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDA
00258             IF( TMP.EQ.ZERO )
00259      $          WORK( INDP+I-1 ) = D( I ) - LAMBDA
00260  100     CONTINUE
00261       END IF
00262 *
00263 *     Find the index (from R1 to R2) of the largest (in magnitude)
00264 *     diagonal element of the inverse
00265 *
00266       MINGMA = WORK( INDS+R1-1 ) + WORK( INDP+R1-1 )
00267       IF( MINGMA.LT.ZERO ) NEG1 = NEG1 + 1
00268       IF( WANTNC ) THEN
00269          NEGCNT = NEG1 + NEG2
00270       ELSE
00271          NEGCNT = -1
00272       ENDIF
00273       IF( ABS(MINGMA).EQ.ZERO )
00274      $   MINGMA = EPS*WORK( INDS+R1-1 )
00275       R = R1
00276       DO 110 I = R1, R2 - 1
00277          TMP = WORK( INDS+I ) + WORK( INDP+I )
00278          IF( TMP.EQ.ZERO )
00279      $      TMP = EPS*WORK( INDS+I )
00280          IF( ABS( TMP ).LE.ABS( MINGMA ) ) THEN
00281             MINGMA = TMP
00282             R = I + 1
00283          END IF
00284  110  CONTINUE
00285 *
00286 *     Compute the FP vector: solve N^T v = e_r
00287 *
00288       ISUPPZ( 1 ) = B1
00289       ISUPPZ( 2 ) = BN
00290       Z( R ) = ONE
00291       ZTZ = ONE
00292 *
00293 *     Compute the FP vector upwards from R
00294 *
00295       IF( .NOT.SAWNAN1 .AND. .NOT.SAWNAN2 ) THEN
00296          DO 210 I = R-1, B1, -1
00297             Z( I ) = -( WORK( INDLPL+I )*Z( I+1 ) )
00298             IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
00299      $           THEN
00300                Z( I ) = ZERO
00301                ISUPPZ( 1 ) = I + 1
00302                GOTO 220
00303             ENDIF
00304             ZTZ = ZTZ + Z( I )*Z( I )
00305  210     CONTINUE
00306  220     CONTINUE
00307       ELSE
00308 *        Run slower loop if NaN occurred.
00309          DO 230 I = R - 1, B1, -1
00310             IF( Z( I+1 ).EQ.ZERO ) THEN
00311                Z( I ) = -( LD( I+1 ) / LD( I ) )*Z( I+2 )
00312             ELSE
00313                Z( I ) = -( WORK( INDLPL+I )*Z( I+1 ) )
00314             END IF
00315             IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
00316      $           THEN
00317                Z( I ) = ZERO
00318                ISUPPZ( 1 ) = I + 1
00319                GO TO 240
00320             END IF
00321             ZTZ = ZTZ + Z( I )*Z( I )
00322  230     CONTINUE
00323  240     CONTINUE
00324       ENDIF
00325 
00326 *     Compute the FP vector downwards from R in blocks of size BLKSIZ
00327       IF( .NOT.SAWNAN1 .AND. .NOT.SAWNAN2 ) THEN
00328          DO 250 I = R, BN-1
00329             Z( I+1 ) = -( WORK( INDUMN+I )*Z( I ) )
00330             IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
00331      $         THEN
00332                Z( I+1 ) = ZERO
00333                ISUPPZ( 2 ) = I
00334                GO TO 260
00335             END IF
00336             ZTZ = ZTZ + Z( I+1 )*Z( I+1 )
00337  250     CONTINUE
00338  260     CONTINUE
00339       ELSE
00340 *        Run slower loop if NaN occurred.
00341          DO 270 I = R, BN - 1
00342             IF( Z( I ).EQ.ZERO ) THEN
00343                Z( I+1 ) = -( LD( I-1 ) / LD( I ) )*Z( I-1 )
00344             ELSE
00345                Z( I+1 ) = -( WORK( INDUMN+I )*Z( I ) )
00346             END IF
00347             IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )
00348      $           THEN
00349                Z( I+1 ) = ZERO
00350                ISUPPZ( 2 ) = I
00351                GO TO 280
00352             END IF
00353             ZTZ = ZTZ + Z( I+1 )*Z( I+1 )
00354  270     CONTINUE
00355  280     CONTINUE
00356       END IF
00357 *
00358 *     Compute quantities for convergence test
00359 *
00360       TMP = ONE / ZTZ
00361       NRMINV = SQRT( TMP )
00362       RESID = ABS( MINGMA )*NRMINV
00363       RQCORR = MINGMA*TMP
00364 *
00365 *
00366       RETURN
00367 *
00368 *     End of DLAR1V
00369 *
00370       END
 All Files Functions