00001 /* slasd5.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 slasd5_(integer *i__, real *d__, real *z__, real *delta, 00017 real *rho, real *dsigma, real *work) 00018 { 00019 /* System generated locals */ 00020 real r__1; 00021 00022 /* Builtin functions */ 00023 double sqrt(doublereal); 00024 00025 /* Local variables */ 00026 real b, c__, w, del, tau, delsq; 00027 00028 00029 /* -- LAPACK auxiliary routine (version 3.2) -- */ 00030 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00031 /* November 2006 */ 00032 00033 /* .. Scalar Arguments .. */ 00034 /* .. */ 00035 /* .. Array Arguments .. */ 00036 /* .. */ 00037 00038 /* Purpose */ 00039 /* ======= */ 00040 00041 /* This subroutine computes the square root of the I-th eigenvalue */ 00042 /* of a positive symmetric rank-one modification of a 2-by-2 diagonal */ 00043 /* matrix */ 00044 00045 /* diag( D ) * diag( D ) + RHO * Z * transpose(Z) . */ 00046 00047 /* The diagonal entries in the array D are assumed to satisfy */ 00048 00049 /* 0 <= D(i) < D(j) for i < j . */ 00050 00051 /* We also assume RHO > 0 and that the Euclidean norm of the vector */ 00052 /* Z is one. */ 00053 00054 /* Arguments */ 00055 /* ========= */ 00056 00057 /* I (input) INTEGER */ 00058 /* The index of the eigenvalue to be computed. I = 1 or I = 2. */ 00059 00060 /* D (input) REAL array, dimension (2) */ 00061 /* The original eigenvalues. We assume 0 <= D(1) < D(2). */ 00062 00063 /* Z (input) REAL array, dimension (2) */ 00064 /* The components of the updating vector. */ 00065 00066 /* DELTA (output) REAL array, dimension (2) */ 00067 /* Contains (D(j) - sigma_I) in its j-th component. */ 00068 /* The vector DELTA contains the information necessary */ 00069 /* to construct the eigenvectors. */ 00070 00071 /* RHO (input) REAL */ 00072 /* The scalar in the symmetric updating formula. */ 00073 00074 /* DSIGMA (output) REAL */ 00075 /* The computed sigma_I, the I-th updated eigenvalue. */ 00076 00077 /* WORK (workspace) REAL array, dimension (2) */ 00078 /* WORK contains (D(j) + sigma_I) in its j-th component. */ 00079 00080 /* Further Details */ 00081 /* =============== */ 00082 00083 /* Based on contributions by */ 00084 /* Ren-Cang Li, Computer Science Division, University of California */ 00085 /* at Berkeley, USA */ 00086 00087 /* ===================================================================== */ 00088 00089 /* .. Parameters .. */ 00090 /* .. */ 00091 /* .. Local Scalars .. */ 00092 /* .. */ 00093 /* .. Intrinsic Functions .. */ 00094 /* .. */ 00095 /* .. Executable Statements .. */ 00096 00097 /* Parameter adjustments */ 00098 --work; 00099 --delta; 00100 --z__; 00101 --d__; 00102 00103 /* Function Body */ 00104 del = d__[2] - d__[1]; 00105 delsq = del * (d__[2] + d__[1]); 00106 if (*i__ == 1) { 00107 w = *rho * 4.f * (z__[2] * z__[2] / (d__[1] + d__[2] * 3.f) - z__[1] * 00108 z__[1] / (d__[1] * 3.f + d__[2])) / del + 1.f; 00109 if (w > 0.f) { 00110 b = delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]); 00111 c__ = *rho * z__[1] * z__[1] * delsq; 00112 00113 /* B > ZERO, always */ 00114 00115 /* The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 ) */ 00116 00117 tau = c__ * 2.f / (b + sqrt((r__1 = b * b - c__ * 4.f, dabs(r__1)) 00118 )); 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.f + 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.f) { 00137 tau = c__ * -2.f / (b + sqrt(b * b + c__ * 4.f)); 00138 } else { 00139 tau = (b - sqrt(b * b + c__ * 4.f)) / 2.f; 00140 } 00141 00142 /* The following TAU is DSIGMA - D( 2 ) */ 00143 00144 tau /= d__[2] + sqrt((r__1 = d__[2] * d__[2] + tau, dabs(r__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.f + 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.f) { 00166 tau = (b + sqrt(b * b + c__ * 4.f)) / 2.f; 00167 } else { 00168 tau = c__ * 2.f / (-b + sqrt(b * b + c__ * 4.f)); 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.f + 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 SLASD5 */ 00188 00189 } /* slasd5_ */