00001 /* slaed9.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 /* Table of constant values */ 00017 00018 static integer c__1 = 1; 00019 00020 /* Subroutine */ int slaed9_(integer *k, integer *kstart, integer *kstop, 00021 integer *n, real *d__, real *q, integer *ldq, real *rho, real *dlamda, 00022 real *w, real *s, integer *lds, integer *info) 00023 { 00024 /* System generated locals */ 00025 integer q_dim1, q_offset, s_dim1, s_offset, i__1, i__2; 00026 real r__1; 00027 00028 /* Builtin functions */ 00029 double sqrt(doublereal), r_sign(real *, real *); 00030 00031 /* Local variables */ 00032 integer i__, j; 00033 real temp; 00034 extern doublereal snrm2_(integer *, real *, integer *); 00035 extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, 00036 integer *), slaed4_(integer *, integer *, real *, real *, real *, 00037 real *, real *, integer *); 00038 extern doublereal slamc3_(real *, real *); 00039 extern /* Subroutine */ int xerbla_(char *, integer *); 00040 00041 00042 /* -- LAPACK routine (version 3.2) -- */ 00043 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00044 /* November 2006 */ 00045 00046 /* .. Scalar Arguments .. */ 00047 /* .. */ 00048 /* .. Array Arguments .. */ 00049 /* .. */ 00050 00051 /* Purpose */ 00052 /* ======= */ 00053 00054 /* SLAED9 finds the roots of the secular equation, as defined by the */ 00055 /* values in D, Z, and RHO, between KSTART and KSTOP. It makes the */ 00056 /* appropriate calls to SLAED4 and then stores the new matrix of */ 00057 /* eigenvectors for use in calculating the next level of Z vectors. */ 00058 00059 /* Arguments */ 00060 /* ========= */ 00061 00062 /* K (input) INTEGER */ 00063 /* The number of terms in the rational function to be solved by */ 00064 /* SLAED4. K >= 0. */ 00065 00066 /* KSTART (input) INTEGER */ 00067 /* KSTOP (input) INTEGER */ 00068 /* The updated eigenvalues Lambda(I), KSTART <= I <= KSTOP */ 00069 /* are to be computed. 1 <= KSTART <= KSTOP <= K. */ 00070 00071 /* N (input) INTEGER */ 00072 /* The number of rows and columns in the Q matrix. */ 00073 /* N >= K (delation may result in N > K). */ 00074 00075 /* D (output) REAL array, dimension (N) */ 00076 /* D(I) contains the updated eigenvalues */ 00077 /* for KSTART <= I <= KSTOP. */ 00078 00079 /* Q (workspace) REAL array, dimension (LDQ,N) */ 00080 00081 /* LDQ (input) INTEGER */ 00082 /* The leading dimension of the array Q. LDQ >= max( 1, N ). */ 00083 00084 /* RHO (input) REAL */ 00085 /* The value of the parameter in the rank one update equation. */ 00086 /* RHO >= 0 required. */ 00087 00088 /* DLAMDA (input) REAL array, dimension (K) */ 00089 /* The first K elements of this array contain the old roots */ 00090 /* of the deflated updating problem. These are the poles */ 00091 /* of the secular equation. */ 00092 00093 /* W (input) REAL array, dimension (K) */ 00094 /* The first K elements of this array contain the components */ 00095 /* of the deflation-adjusted updating vector. */ 00096 00097 /* S (output) REAL array, dimension (LDS, K) */ 00098 /* Will contain the eigenvectors of the repaired matrix which */ 00099 /* will be stored for subsequent Z vector calculation and */ 00100 /* multiplied by the previously accumulated eigenvectors */ 00101 /* to update the system. */ 00102 00103 /* LDS (input) INTEGER */ 00104 /* The leading dimension of S. LDS >= max( 1, K ). */ 00105 00106 /* INFO (output) INTEGER */ 00107 /* = 0: successful exit. */ 00108 /* < 0: if INFO = -i, the i-th argument had an illegal value. */ 00109 /* > 0: if INFO = 1, an eigenvalue did not converge */ 00110 00111 /* Further Details */ 00112 /* =============== */ 00113 00114 /* Based on contributions by */ 00115 /* Jeff Rutter, Computer Science Division, University of California */ 00116 /* at Berkeley, USA */ 00117 00118 /* ===================================================================== */ 00119 00120 /* .. Local Scalars .. */ 00121 /* .. */ 00122 /* .. External Functions .. */ 00123 /* .. */ 00124 /* .. External Subroutines .. */ 00125 /* .. */ 00126 /* .. Intrinsic Functions .. */ 00127 /* .. */ 00128 /* .. Executable Statements .. */ 00129 00130 /* Test the input parameters. */ 00131 00132 /* Parameter adjustments */ 00133 --d__; 00134 q_dim1 = *ldq; 00135 q_offset = 1 + q_dim1; 00136 q -= q_offset; 00137 --dlamda; 00138 --w; 00139 s_dim1 = *lds; 00140 s_offset = 1 + s_dim1; 00141 s -= s_offset; 00142 00143 /* Function Body */ 00144 *info = 0; 00145 00146 if (*k < 0) { 00147 *info = -1; 00148 } else if (*kstart < 1 || *kstart > max(1,*k)) { 00149 *info = -2; 00150 } else if (max(1,*kstop) < *kstart || *kstop > max(1,*k)) { 00151 *info = -3; 00152 } else if (*n < *k) { 00153 *info = -4; 00154 } else if (*ldq < max(1,*k)) { 00155 *info = -7; 00156 } else if (*lds < max(1,*k)) { 00157 *info = -12; 00158 } 00159 if (*info != 0) { 00160 i__1 = -(*info); 00161 xerbla_("SLAED9", &i__1); 00162 return 0; 00163 } 00164 00165 /* Quick return if possible */ 00166 00167 if (*k == 0) { 00168 return 0; 00169 } 00170 00171 /* Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can */ 00172 /* be computed with high relative accuracy (barring over/underflow). */ 00173 /* This is a problem on machines without a guard digit in */ 00174 /* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2). */ 00175 /* The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I), */ 00176 /* which on any of these machines zeros out the bottommost */ 00177 /* bit of DLAMDA(I) if it is 1; this makes the subsequent */ 00178 /* subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation */ 00179 /* occurs. On binary machines with a guard digit (almost all */ 00180 /* machines) it does not change DLAMDA(I) at all. On hexadecimal */ 00181 /* and decimal machines with a guard digit, it slightly */ 00182 /* changes the bottommost bits of DLAMDA(I). It does not account */ 00183 /* for hexadecimal or decimal machines without guard digits */ 00184 /* (we know of none). We use a subroutine call to compute */ 00185 /* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating */ 00186 /* this code. */ 00187 00188 i__1 = *n; 00189 for (i__ = 1; i__ <= i__1; ++i__) { 00190 dlamda[i__] = slamc3_(&dlamda[i__], &dlamda[i__]) - dlamda[i__]; 00191 /* L10: */ 00192 } 00193 00194 i__1 = *kstop; 00195 for (j = *kstart; j <= i__1; ++j) { 00196 slaed4_(k, &j, &dlamda[1], &w[1], &q[j * q_dim1 + 1], rho, &d__[j], 00197 info); 00198 00199 /* If the zero finder fails, the computation is terminated. */ 00200 00201 if (*info != 0) { 00202 goto L120; 00203 } 00204 /* L20: */ 00205 } 00206 00207 if (*k == 1 || *k == 2) { 00208 i__1 = *k; 00209 for (i__ = 1; i__ <= i__1; ++i__) { 00210 i__2 = *k; 00211 for (j = 1; j <= i__2; ++j) { 00212 s[j + i__ * s_dim1] = q[j + i__ * q_dim1]; 00213 /* L30: */ 00214 } 00215 /* L40: */ 00216 } 00217 goto L120; 00218 } 00219 00220 /* Compute updated W. */ 00221 00222 scopy_(k, &w[1], &c__1, &s[s_offset], &c__1); 00223 00224 /* Initialize W(I) = Q(I,I) */ 00225 00226 i__1 = *ldq + 1; 00227 scopy_(k, &q[q_offset], &i__1, &w[1], &c__1); 00228 i__1 = *k; 00229 for (j = 1; j <= i__1; ++j) { 00230 i__2 = j - 1; 00231 for (i__ = 1; i__ <= i__2; ++i__) { 00232 w[i__] *= q[i__ + j * q_dim1] / (dlamda[i__] - dlamda[j]); 00233 /* L50: */ 00234 } 00235 i__2 = *k; 00236 for (i__ = j + 1; i__ <= i__2; ++i__) { 00237 w[i__] *= q[i__ + j * q_dim1] / (dlamda[i__] - dlamda[j]); 00238 /* L60: */ 00239 } 00240 /* L70: */ 00241 } 00242 i__1 = *k; 00243 for (i__ = 1; i__ <= i__1; ++i__) { 00244 r__1 = sqrt(-w[i__]); 00245 w[i__] = r_sign(&r__1, &s[i__ + s_dim1]); 00246 /* L80: */ 00247 } 00248 00249 /* Compute eigenvectors of the modified rank-1 modification. */ 00250 00251 i__1 = *k; 00252 for (j = 1; j <= i__1; ++j) { 00253 i__2 = *k; 00254 for (i__ = 1; i__ <= i__2; ++i__) { 00255 q[i__ + j * q_dim1] = w[i__] / q[i__ + j * q_dim1]; 00256 /* L90: */ 00257 } 00258 temp = snrm2_(k, &q[j * q_dim1 + 1], &c__1); 00259 i__2 = *k; 00260 for (i__ = 1; i__ <= i__2; ++i__) { 00261 s[i__ + j * s_dim1] = q[i__ + j * q_dim1] / temp; 00262 /* L100: */ 00263 } 00264 /* L110: */ 00265 } 00266 00267 L120: 00268 return 0; 00269 00270 /* End of SLAED9 */ 00271 00272 } /* slaed9_ */