00001 /* dlasd5.f -- translated by f2c (version 20061008). 00002 You must link the resulting object file with libf2c: 00003 on Microsoft Windows system, link with libf2c.lib; 00004 on Linux or Unix systems, link with .../path/to/libf2c.a -lm 00005 or, if you install libf2c.a in a standard place, with -lf2c -lm 00006 -- in that order, at the end of the command line, as in 00007 cc *.o -lf2c -lm 00008 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., 00009 00010 http://www.netlib.org/f2c/libf2c.zip 00011 */ 00012 00013 #include "f2c.h" 00014 #include "blaswrap.h" 00015 00016 /* Subroutine */ int dlasd5_(integer *i__, doublereal *d__, doublereal *z__, 00017 doublereal *delta, doublereal *rho, doublereal *dsigma, doublereal * 00018 work) 00019 { 00020 /* System generated locals */ 00021 doublereal d__1; 00022 00023 /* Builtin functions */ 00024 double sqrt(doublereal); 00025 00026 /* Local variables */ 00027 doublereal b, c__, w, del, tau, delsq; 00028 00029 00030 /* -- LAPACK auxiliary routine (version 3.2) -- */ 00031 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00032 /* November 2006 */ 00033 00034 /* .. Scalar Arguments .. */ 00035 /* .. */ 00036 /* .. Array Arguments .. */ 00037 /* .. */ 00038 00039 /* Purpose */ 00040 /* ======= */ 00041 00042 /* This subroutine computes the square root of the I-th eigenvalue */ 00043 /* of a positive symmetric rank-one modification of a 2-by-2 diagonal */ 00044 /* matrix */ 00045 00046 /* diag( D ) * diag( D ) + RHO * Z * transpose(Z) . */ 00047 00048 /* The diagonal entries in the array D are assumed to satisfy */ 00049 00050 /* 0 <= D(i) < D(j) for i < j . */ 00051 00052 /* We also assume RHO > 0 and that the Euclidean norm of the vector */ 00053 /* Z is one. */ 00054 00055 /* Arguments */ 00056 /* ========= */ 00057 00058 /* I (input) INTEGER */ 00059 /* The index of the eigenvalue to be computed. I = 1 or I = 2. */ 00060 00061 /* D (input) DOUBLE PRECISION array, dimension ( 2 ) */ 00062 /* The original eigenvalues. We assume 0 <= D(1) < D(2). */ 00063 00064 /* Z (input) DOUBLE PRECISION array, dimension ( 2 ) */ 00065 /* The components of the updating vector. */ 00066 00067 /* DELTA (output) DOUBLE PRECISION array, dimension ( 2 ) */ 00068 /* Contains (D(j) - sigma_I) in its j-th component. */ 00069 /* The vector DELTA contains the information necessary */ 00070 /* to construct the eigenvectors. */ 00071 00072 /* RHO (input) DOUBLE PRECISION */ 00073 /* The scalar in the symmetric updating formula. */ 00074 00075 /* DSIGMA (output) DOUBLE PRECISION */ 00076 /* The computed sigma_I, the I-th updated eigenvalue. */ 00077 00078 /* WORK (workspace) DOUBLE PRECISION array, dimension ( 2 ) */ 00079 /* WORK contains (D(j) + sigma_I) in its j-th component. */ 00080 00081 /* Further Details */ 00082 /* =============== */ 00083 00084 /* Based on contributions by */ 00085 /* Ren-Cang Li, Computer Science Division, University of California */ 00086 /* at Berkeley, USA */ 00087 00088 /* ===================================================================== */ 00089 00090 /* .. Parameters .. */ 00091 /* .. */ 00092 /* .. Local Scalars .. */ 00093 /* .. */ 00094 /* .. Intrinsic Functions .. */ 00095 /* .. */ 00096 /* .. Executable Statements .. */ 00097 00098 /* Parameter adjustments */ 00099 --work; 00100 --delta; 00101 --z__; 00102 --d__; 00103 00104 /* Function Body */ 00105 del = d__[2] - d__[1]; 00106 delsq = del * (d__[2] + d__[1]); 00107 if (*i__ == 1) { 00108 w = *rho * 4. * (z__[2] * z__[2] / (d__[1] + d__[2] * 3.) - z__[1] * 00109 z__[1] / (d__[1] * 3. + d__[2])) / del + 1.; 00110 if (w > 0.) { 00111 b = delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]); 00112 c__ = *rho * z__[1] * z__[1] * delsq; 00113 00114 /* B > ZERO, always */ 00115 00116 /* The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 ) */ 00117 00118 tau = c__ * 2. / (b + sqrt((d__1 = b * b - c__ * 4., abs(d__1)))); 00119 00120 /* The following TAU is DSIGMA - D( 1 ) */ 00121 00122 tau /= d__[1] + sqrt(d__[1] * d__[1] + tau); 00123 *dsigma = d__[1] + tau; 00124 delta[1] = -tau; 00125 delta[2] = del - tau; 00126 work[1] = d__[1] * 2. + tau; 00127 work[2] = d__[1] + tau + d__[2]; 00128 /* DELTA( 1 ) = -Z( 1 ) / TAU */ 00129 /* DELTA( 2 ) = Z( 2 ) / ( DEL-TAU ) */ 00130 } else { 00131 b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]); 00132 c__ = *rho * z__[2] * z__[2] * delsq; 00133 00134 /* The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 ) */ 00135 00136 if (b > 0.) { 00137 tau = c__ * -2. / (b + sqrt(b * b + c__ * 4.)); 00138 } else { 00139 tau = (b - sqrt(b * b + c__ * 4.)) / 2.; 00140 } 00141 00142 /* The following TAU is DSIGMA - D( 2 ) */ 00143 00144 tau /= d__[2] + sqrt((d__1 = d__[2] * d__[2] + tau, abs(d__1))); 00145 *dsigma = d__[2] + tau; 00146 delta[1] = -(del + tau); 00147 delta[2] = -tau; 00148 work[1] = d__[1] + tau + d__[2]; 00149 work[2] = d__[2] * 2. + tau; 00150 /* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU ) */ 00151 /* DELTA( 2 ) = -Z( 2 ) / TAU */ 00152 } 00153 /* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) ) */ 00154 /* DELTA( 1 ) = DELTA( 1 ) / TEMP */ 00155 /* DELTA( 2 ) = DELTA( 2 ) / TEMP */ 00156 } else { 00157 00158 /* Now I=2 */ 00159 00160 b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]); 00161 c__ = *rho * z__[2] * z__[2] * delsq; 00162 00163 /* The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 ) */ 00164 00165 if (b > 0.) { 00166 tau = (b + sqrt(b * b + c__ * 4.)) / 2.; 00167 } else { 00168 tau = c__ * 2. / (-b + sqrt(b * b + c__ * 4.)); 00169 } 00170 00171 /* The following TAU is DSIGMA - D( 2 ) */ 00172 00173 tau /= d__[2] + sqrt(d__[2] * d__[2] + tau); 00174 *dsigma = d__[2] + tau; 00175 delta[1] = -(del + tau); 00176 delta[2] = -tau; 00177 work[1] = d__[1] + tau + d__[2]; 00178 work[2] = d__[2] * 2. + tau; 00179 /* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU ) */ 00180 /* DELTA( 2 ) = -Z( 2 ) / TAU */ 00181 /* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) ) */ 00182 /* DELTA( 1 ) = DELTA( 1 ) / TEMP */ 00183 /* DELTA( 2 ) = DELTA( 2 ) / TEMP */ 00184 } 00185 return 0; 00186 00187 /* End of DLASD5 */ 00188 00189 } /* dlasd5_ */