LAPACK 3.3.0

dlaic1.f

Go to the documentation of this file.
00001       SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
00002 *
00003 *  -- LAPACK auxiliary routine (version 3.2) --
00004 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00005 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       INTEGER            J, JOB
00010       DOUBLE PRECISION   C, GAMMA, S, SEST, SESTPR
00011 *     ..
00012 *     .. Array Arguments ..
00013       DOUBLE PRECISION   W( J ), X( J )
00014 *     ..
00015 *
00016 *  Purpose
00017 *  =======
00018 *
00019 *  DLAIC1 applies one step of incremental condition estimation in
00020 *  its simplest version:
00021 *
00022 *  Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
00023 *  lower triangular matrix L, such that
00024 *           twonorm(L*x) = sest
00025 *  Then DLAIC1 computes sestpr, s, c such that
00026 *  the vector
00027 *                  [ s*x ]
00028 *           xhat = [  c  ]
00029 *  is an approximate singular vector of
00030 *                  [ L     0  ]
00031 *           Lhat = [ w' gamma ]
00032 *  in the sense that
00033 *           twonorm(Lhat*xhat) = sestpr.
00034 *
00035 *  Depending on JOB, an estimate for the largest or smallest singular
00036 *  value is computed.
00037 *
00038 *  Note that [s c]' and sestpr**2 is an eigenpair of the system
00039 *
00040 *      diag(sest*sest, 0) + [alpha  gamma] * [ alpha ]
00041 *                                            [ gamma ]
00042 *
00043 *  where  alpha =  x'*w.
00044 *
00045 *  Arguments
00046 *  =========
00047 *
00048 *  JOB     (input) INTEGER
00049 *          = 1: an estimate for the largest singular value is computed.
00050 *          = 2: an estimate for the smallest singular value is computed.
00051 *
00052 *  J       (input) INTEGER
00053 *          Length of X and W
00054 *
00055 *  X       (input) DOUBLE PRECISION array, dimension (J)
00056 *          The j-vector x.
00057 *
00058 *  SEST    (input) DOUBLE PRECISION
00059 *          Estimated singular value of j by j matrix L
00060 *
00061 *  W       (input) DOUBLE PRECISION array, dimension (J)
00062 *          The j-vector w.
00063 *
00064 *  GAMMA   (input) DOUBLE PRECISION
00065 *          The diagonal element gamma.
00066 *
00067 *  SESTPR  (output) DOUBLE PRECISION
00068 *          Estimated singular value of (j+1) by (j+1) matrix Lhat.
00069 *
00070 *  S       (output) DOUBLE PRECISION
00071 *          Sine needed in forming xhat.
00072 *
00073 *  C       (output) DOUBLE PRECISION
00074 *          Cosine needed in forming xhat.
00075 *
00076 *  =====================================================================
00077 *
00078 *     .. Parameters ..
00079       DOUBLE PRECISION   ZERO, ONE, TWO
00080       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
00081       DOUBLE PRECISION   HALF, FOUR
00082       PARAMETER          ( HALF = 0.5D0, FOUR = 4.0D0 )
00083 *     ..
00084 *     .. Local Scalars ..
00085       DOUBLE PRECISION   ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,
00086      $                   NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2
00087 *     ..
00088 *     .. Intrinsic Functions ..
00089       INTRINSIC          ABS, MAX, SIGN, SQRT
00090 *     ..
00091 *     .. External Functions ..
00092       DOUBLE PRECISION   DDOT, DLAMCH
00093       EXTERNAL           DDOT, DLAMCH
00094 *     ..
00095 *     .. Executable Statements ..
00096 *
00097       EPS = DLAMCH( 'Epsilon' )
00098       ALPHA = DDOT( J, X, 1, W, 1 )
00099 *
00100       ABSALP = ABS( ALPHA )
00101       ABSGAM = ABS( GAMMA )
00102       ABSEST = ABS( SEST )
00103 *
00104       IF( JOB.EQ.1 ) THEN
00105 *
00106 *        Estimating largest singular value
00107 *
00108 *        special cases
00109 *
00110          IF( SEST.EQ.ZERO ) THEN
00111             S1 = MAX( ABSGAM, ABSALP )
00112             IF( S1.EQ.ZERO ) THEN
00113                S = ZERO
00114                C = ONE
00115                SESTPR = ZERO
00116             ELSE
00117                S = ALPHA / S1
00118                C = GAMMA / S1
00119                TMP = SQRT( S*S+C*C )
00120                S = S / TMP
00121                C = C / TMP
00122                SESTPR = S1*TMP
00123             END IF
00124             RETURN
00125          ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
00126             S = ONE
00127             C = ZERO
00128             TMP = MAX( ABSEST, ABSALP )
00129             S1 = ABSEST / TMP
00130             S2 = ABSALP / TMP
00131             SESTPR = TMP*SQRT( S1*S1+S2*S2 )
00132             RETURN
00133          ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
00134             S1 = ABSGAM
00135             S2 = ABSEST
00136             IF( S1.LE.S2 ) THEN
00137                S = ONE
00138                C = ZERO
00139                SESTPR = S2
00140             ELSE
00141                S = ZERO
00142                C = ONE
00143                SESTPR = S1
00144             END IF
00145             RETURN
00146          ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
00147             S1 = ABSGAM
00148             S2 = ABSALP
00149             IF( S1.LE.S2 ) THEN
00150                TMP = S1 / S2
00151                S = SQRT( ONE+TMP*TMP )
00152                SESTPR = S2*S
00153                C = ( GAMMA / S2 ) / S
00154                S = SIGN( ONE, ALPHA ) / S
00155             ELSE
00156                TMP = S2 / S1
00157                C = SQRT( ONE+TMP*TMP )
00158                SESTPR = S1*C
00159                S = ( ALPHA / S1 ) / C
00160                C = SIGN( ONE, GAMMA ) / C
00161             END IF
00162             RETURN
00163          ELSE
00164 *
00165 *           normal case
00166 *
00167             ZETA1 = ALPHA / ABSEST
00168             ZETA2 = GAMMA / ABSEST
00169 *
00170             B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
00171             C = ZETA1*ZETA1
00172             IF( B.GT.ZERO ) THEN
00173                T = C / ( B+SQRT( B*B+C ) )
00174             ELSE
00175                T = SQRT( B*B+C ) - B
00176             END IF
00177 *
00178             SINE = -ZETA1 / T
00179             COSINE = -ZETA2 / ( ONE+T )
00180             TMP = SQRT( SINE*SINE+COSINE*COSINE )
00181             S = SINE / TMP
00182             C = COSINE / TMP
00183             SESTPR = SQRT( T+ONE )*ABSEST
00184             RETURN
00185          END IF
00186 *
00187       ELSE IF( JOB.EQ.2 ) THEN
00188 *
00189 *        Estimating smallest singular value
00190 *
00191 *        special cases
00192 *
00193          IF( SEST.EQ.ZERO ) THEN
00194             SESTPR = ZERO
00195             IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
00196                SINE = ONE
00197                COSINE = ZERO
00198             ELSE
00199                SINE = -GAMMA
00200                COSINE = ALPHA
00201             END IF
00202             S1 = MAX( ABS( SINE ), ABS( COSINE ) )
00203             S = SINE / S1
00204             C = COSINE / S1
00205             TMP = SQRT( S*S+C*C )
00206             S = S / TMP
00207             C = C / TMP
00208             RETURN
00209          ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
00210             S = ZERO
00211             C = ONE
00212             SESTPR = ABSGAM
00213             RETURN
00214          ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
00215             S1 = ABSGAM
00216             S2 = ABSEST
00217             IF( S1.LE.S2 ) THEN
00218                S = ZERO
00219                C = ONE
00220                SESTPR = S1
00221             ELSE
00222                S = ONE
00223                C = ZERO
00224                SESTPR = S2
00225             END IF
00226             RETURN
00227          ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
00228             S1 = ABSGAM
00229             S2 = ABSALP
00230             IF( S1.LE.S2 ) THEN
00231                TMP = S1 / S2
00232                C = SQRT( ONE+TMP*TMP )
00233                SESTPR = ABSEST*( TMP / C )
00234                S = -( GAMMA / S2 ) / C
00235                C = SIGN( ONE, ALPHA ) / C
00236             ELSE
00237                TMP = S2 / S1
00238                S = SQRT( ONE+TMP*TMP )
00239                SESTPR = ABSEST / S
00240                C = ( ALPHA / S1 ) / S
00241                S = -SIGN( ONE, GAMMA ) / S
00242             END IF
00243             RETURN
00244          ELSE
00245 *
00246 *           normal case
00247 *
00248             ZETA1 = ALPHA / ABSEST
00249             ZETA2 = GAMMA / ABSEST
00250 *
00251             NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),
00252      $              ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )
00253 *
00254 *           See if root is closer to zero or to ONE
00255 *
00256             TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
00257             IF( TEST.GE.ZERO ) THEN
00258 *
00259 *              root is close to zero, compute directly
00260 *
00261                B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
00262                C = ZETA2*ZETA2
00263                T = C / ( B+SQRT( ABS( B*B-C ) ) )
00264                SINE = ZETA1 / ( ONE-T )
00265                COSINE = -ZETA2 / T
00266                SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
00267             ELSE
00268 *
00269 *              root is closer to ONE, shift by that amount
00270 *
00271                B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
00272                C = ZETA1*ZETA1
00273                IF( B.GE.ZERO ) THEN
00274                   T = -C / ( B+SQRT( B*B+C ) )
00275                ELSE
00276                   T = B - SQRT( B*B+C )
00277                END IF
00278                SINE = -ZETA1 / T
00279                COSINE = -ZETA2 / ( ONE+T )
00280                SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
00281             END IF
00282             TMP = SQRT( SINE*SINE+COSINE*COSINE )
00283             S = SINE / TMP
00284             C = COSINE / TMP
00285             RETURN
00286 *
00287          END IF
00288       END IF
00289       RETURN
00290 *
00291 *     End of DLAIC1
00292 *
00293       END
 All Files Functions