3 /* Subroutine */ int slazq4_(integer *i0, integer *n0, real *z__, integer *pp,
4 integer *n0in, real *dmin__, real *dmin1, real *dmin2, real *dn,
5 real *dn1, real *dn2, real *tau, integer *ttype, real *g)
7 /* System generated locals */
11 /* Builtin functions */
12 double sqrt(doublereal);
20 /* -- LAPACK auxiliary routine (version 3.1) -- */
21 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
24 /* .. Scalar Arguments .. */
26 /* .. Array Arguments .. */
32 /* SLAZQ4 computes an approximation TAU to the smallest eigenvalue */
33 /* using values of d from the previous transform. */
35 /* I0 (input) INTEGER */
38 /* N0 (input) INTEGER */
41 /* Z (input) REAL array, dimension ( 4*N ) */
42 /* Z holds the qd array. */
44 /* PP (input) INTEGER */
45 /* PP=0 for ping, PP=1 for pong. */
47 /* N0IN (input) INTEGER */
48 /* The value of N0 at start of EIGTEST. */
50 /* DMIN (input) REAL */
51 /* Minimum value of d. */
53 /* DMIN1 (input) REAL */
54 /* Minimum value of d, excluding D( N0 ). */
56 /* DMIN2 (input) REAL */
57 /* Minimum value of d, excluding D( N0 ) and D( N0-1 ). */
62 /* DN1 (input) REAL */
65 /* DN2 (input) REAL */
68 /* TAU (output) REAL */
69 /* This is the shift. */
71 /* TTYPE (output) INTEGER */
74 /* G (input/output) REAL */
75 /* G is passed as an argument in order to save its value between */
82 /* This is a thread safe version of SLASQ4, which passes G through the */
83 /* argument list in place of declaring G in a SAVE statment. */
85 /* ===================================================================== */
87 /* .. Parameters .. */
89 /* .. Local Scalars .. */
91 /* .. Intrinsic Functions .. */
93 /* .. Executable Statements .. */
95 /* A negative DMIN forces the shift to take that absolute value */
96 /* TTYPE records the type of shift. */
98 /* Parameter adjustments */
102 if (*dmin__ <= 0.f) {
108 nn = (*n0 << 2) + *pp;
111 /* No eigenvalues deflated. */
113 if (*dmin__ == *dn || *dmin__ == *dn1) {
115 b1 = sqrt(z__[nn - 3]) * sqrt(z__[nn - 5]);
116 b2 = sqrt(z__[nn - 7]) * sqrt(z__[nn - 9]);
117 a2 = z__[nn - 7] + z__[nn - 5];
121 if (*dmin__ == *dn && *dmin1 == *dn1) {
122 gap2 = *dmin2 - a2 - *dmin2 * .25f;
123 if (gap2 > 0.f && gap2 > b2) {
124 gap1 = a2 - *dn - b2 / gap2 * b2;
126 gap1 = a2 - *dn - (b1 + b2);
128 if (gap1 > 0.f && gap1 > b1) {
130 r__1 = *dn - b1 / gap1 * b1, r__2 = *dmin__ * .5f;
140 r__1 = s, r__2 = a2 - (b1 + b2);
144 r__1 = s, r__2 = *dmin__ * .333f;
154 if (*dmin__ == *dn) {
157 if (z__[nn - 5] > z__[nn - 7]) {
160 b2 = z__[nn - 5] / z__[nn - 7];
163 np = nn - (*pp << 1);
166 if (z__[np - 4] > z__[np - 2]) {
169 a2 = z__[np - 4] / z__[np - 2];
170 if (z__[nn - 9] > z__[nn - 11]) {
173 b2 = z__[nn - 9] / z__[nn - 11];
177 /* Approximate contribution to norm squared from I < NN-1. */
180 i__1 = (*i0 << 2) - 1 + *pp;
181 for (i4 = np; i4 >= i__1; i4 += -4) {
186 if (z__[i4] > z__[i4 - 2]) {
189 b2 *= z__[i4] / z__[i4 - 2];
191 if (dmax(b2,b1) * 100.f < a2 || .563f < a2) {
199 /* Rayleigh quotient residual bound. */
202 s = gam * (1.f - sqrt(a2)) / (a2 + 1.f);
205 } else if (*dmin__ == *dn2) {
212 /* Compute contribution to norm squared from I > NN-2. */
214 np = nn - (*pp << 1);
218 if (z__[np - 8] > b2 || z__[np - 4] > b1) {
221 a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.f);
223 /* Approximate contribution to norm squared from I < NN-2. */
226 b2 = z__[nn - 13] / z__[nn - 15];
228 i__1 = (*i0 << 2) - 1 + *pp;
229 for (i4 = nn - 17; i4 >= i__1; i4 += -4) {
234 if (z__[i4] > z__[i4 - 2]) {
237 b2 *= z__[i4] / z__[i4 - 2];
239 if (dmax(b2,b1) * 100.f < a2 || .563f < a2) {
249 s = gam * (1.f - sqrt(a2)) / (a2 + 1.f);
253 /* Case 6, no information to guide us. */
256 *g += (1.f - *g) * .333f;
257 } else if (*ttype == -18) {
258 *g = .083250000000000005f;
266 } else if (*n0in == *n0 + 1) {
268 /* One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN. */
270 if (*dmin1 == *dn1 && *dmin2 == *dn2) {
276 if (z__[nn - 5] > z__[nn - 7]) {
279 b1 = z__[nn - 5] / z__[nn - 7];
284 i__1 = (*i0 << 2) - 1 + *pp;
285 for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
287 if (z__[i4] > z__[i4 - 2]) {
290 b1 *= z__[i4] / z__[i4 - 2];
292 if (dmax(b1,a2) * 100.f < b2) {
298 b2 = sqrt(b2 * 1.05f);
299 /* Computing 2nd power */
301 a2 = *dmin1 / (r__1 * r__1 + 1.f);
302 gap2 = *dmin2 * .5f - a2;
303 if (gap2 > 0.f && gap2 > b2 * a2) {
305 r__1 = s, r__2 = a2 * (1.f - a2 * 1.01f * (b2 / gap2) * b2);
309 r__1 = s, r__2 = a2 * (1.f - b2 * 1.01f);
318 if (*dmin1 == *dn1) {
324 } else if (*n0in == *n0 + 2) {
326 /* Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN. */
328 /* Cases 10 and 11. */
330 if (*dmin2 == *dn2 && z__[nn - 5] * 2.f < z__[nn - 7]) {
333 if (z__[nn - 5] > z__[nn - 7]) {
336 b1 = z__[nn - 5] / z__[nn - 7];
341 i__1 = (*i0 << 2) - 1 + *pp;
342 for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
343 if (z__[i4] > z__[i4 - 2]) {
346 b1 *= z__[i4] / z__[i4 - 2];
348 if (b1 * 100.f < b2) {
354 b2 = sqrt(b2 * 1.05f);
355 /* Computing 2nd power */
357 a2 = *dmin2 / (r__1 * r__1 + 1.f);
358 gap2 = z__[nn - 7] + z__[nn - 9] - sqrt(z__[nn - 11]) * sqrt(z__[
360 if (gap2 > 0.f && gap2 > b2 * a2) {
362 r__1 = s, r__2 = a2 * (1.f - a2 * 1.01f * (b2 / gap2) * b2);
366 r__1 = s, r__2 = a2 * (1.f - b2 * 1.01f);
373 } else if (*n0in > *n0 + 2) {
375 /* Case 12, more than two eigenvalues deflated. No information. */