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