3 /* Table of constant values */
5 static integer c__0 = 0;
6 static integer c__1 = 1;
7 static doublereal c_b32 = 1.;
9 /* Subroutine */ int dsterf_(integer *n, doublereal *d__, doublereal *e,
12 /* System generated locals */
14 doublereal d__1, d__2, d__3;
16 /* Builtin functions */
17 double sqrt(doublereal), d_sign(doublereal *, doublereal *);
24 doublereal bb, rt1, rt2, eps, rte;
26 doublereal eps2, oldc;
28 extern /* Subroutine */ int dlae2_(doublereal *, doublereal *, doublereal
29 *, doublereal *, doublereal *);
30 doublereal gamma, alpha, sigma, anorm;
31 extern doublereal dlapy2_(doublereal *, doublereal *), dlamch_(char *);
33 extern /* Subroutine */ int dlascl_(char *, integer *, integer *,
34 doublereal *, doublereal *, integer *, integer *, doublereal *,
35 integer *, integer *);
36 doublereal oldgam, safmin;
37 extern /* Subroutine */ int xerbla_(char *, integer *);
39 extern doublereal dlanst_(char *, integer *, doublereal *, doublereal *);
40 extern /* Subroutine */ int dlasrt_(char *, integer *, doublereal *,
48 /* -- LAPACK routine (version 3.1) -- */
49 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
52 /* .. Scalar Arguments .. */
54 /* .. Array Arguments .. */
60 /* DSTERF computes all eigenvalues of a symmetric tridiagonal matrix */
61 /* using the Pal-Walker-Kahan variant of the QL or QR algorithm. */
66 /* N (input) INTEGER */
67 /* The order of the matrix. N >= 0. */
69 /* D (input/output) DOUBLE PRECISION array, dimension (N) */
70 /* On entry, the n diagonal elements of the tridiagonal matrix. */
71 /* On exit, if INFO = 0, the eigenvalues in ascending order. */
73 /* E (input/output) DOUBLE PRECISION array, dimension (N-1) */
74 /* On entry, the (n-1) subdiagonal elements of the tridiagonal */
76 /* On exit, E has been destroyed. */
78 /* INFO (output) INTEGER */
79 /* = 0: successful exit */
80 /* < 0: if INFO = -i, the i-th argument had an illegal value */
81 /* > 0: the algorithm failed to find all of the eigenvalues in */
82 /* a total of 30*N iterations; if INFO = i, then i */
83 /* elements of E have not converged to zero. */
85 /* ===================================================================== */
87 /* .. Parameters .. */
89 /* .. Local Scalars .. */
91 /* .. External Functions .. */
93 /* .. External Subroutines .. */
95 /* .. Intrinsic Functions .. */
97 /* .. Executable Statements .. */
99 /* Test the input parameters. */
101 /* Parameter adjustments */
108 /* Quick return if possible */
113 xerbla_("DSTERF", &i__1);
120 /* Determine the unit roundoff for this environment. */
123 /* Computing 2nd power */
126 safmin = dlamch_("S");
127 safmax = 1. / safmin;
128 ssfmax = sqrt(safmax) / 3.;
129 ssfmin = sqrt(safmin) / eps2;
131 /* Compute the eigenvalues of the tridiagonal matrix. */
137 /* Determine where the matrix splits and choose QL or QR iteration */
138 /* for each block, according to whether top or bottom diagonal */
139 /* element is smaller. */
151 for (m = l1; m <= i__1; ++m) {
152 if ((d__3 = e[m], abs(d__3)) <= sqrt((d__1 = d__[m], abs(d__1))) *
153 sqrt((d__2 = d__[m + 1], abs(d__2))) * eps) {
171 /* Scale submatrix in rows and columns L to LEND */
174 anorm = dlanst_("I", &i__1, &d__[l], &e[l]);
176 if (anorm > ssfmax) {
179 dlascl_("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n,
182 dlascl_("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n,
184 } else if (anorm < ssfmin) {
187 dlascl_("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n,
190 dlascl_("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n,
195 for (i__ = l; i__ <= i__1; ++i__) {
196 /* Computing 2nd power */
198 e[i__] = d__1 * d__1;
202 /* Choose between QL and QR iteration */
204 if ((d__1 = d__[lend], abs(d__1)) < (d__2 = d__[l], abs(d__2))) {
213 /* Look for small subdiagonal element. */
218 for (m = l; m <= i__1; ++m) {
219 if ((d__2 = e[m], abs(d__2)) <= eps2 * (d__1 = d__[m] * d__[m
237 /* If remaining matrix is 2 by 2, use DLAE2 to compute its */
242 dlae2_(&d__[l], &rte, &d__[l + 1], &rt1, &rt2);
253 if (jtot == nmaxit) {
261 sigma = (d__[l + 1] - p) / (rte * 2.);
262 r__ = dlapy2_(&sigma, &c_b32);
263 sigma = p - rte / (sigma + d_sign(&r__, &sigma));
267 gamma = d__[m] - sigma;
273 for (i__ = m - 1; i__ >= i__1; --i__) {
277 e[i__ + 1] = s * r__;
284 gamma = c__ * (alpha - sigma) - s * oldgam;
285 d__[i__ + 1] = oldgam + (alpha - gamma);
287 p = gamma * gamma / c__;
295 d__[l] = sigma + gamma;
298 /* Eigenvalue found. */
313 /* Look for small superdiagonal element. */
317 for (m = l; m >= i__1; --m) {
318 if ((d__2 = e[m - 1], abs(d__2)) <= eps2 * (d__1 = d__[m] * d__[m
335 /* If remaining matrix is 2 by 2, use DLAE2 to compute its */
339 rte = sqrt(e[l - 1]);
340 dlae2_(&d__[l], &rte, &d__[l - 1], &rt1, &rt2);
351 if (jtot == nmaxit) {
358 rte = sqrt(e[l - 1]);
359 sigma = (d__[l - 1] - p) / (rte * 2.);
360 r__ = dlapy2_(&sigma, &c_b32);
361 sigma = p - rte / (sigma + d_sign(&r__, &sigma));
365 gamma = d__[m] - sigma;
371 for (i__ = m; i__ <= i__1; ++i__) {
375 e[i__ - 1] = s * r__;
381 alpha = d__[i__ + 1];
382 gamma = c__ * (alpha - sigma) - s * oldgam;
383 d__[i__] = oldgam + (alpha - gamma);
385 p = gamma * gamma / c__;
393 d__[l] = sigma + gamma;
396 /* Eigenvalue found. */
409 /* Undo scaling if necessary */
413 i__1 = lendsv - lsv + 1;
414 dlascl_("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv],
418 i__1 = lendsv - lsv + 1;
419 dlascl_("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv],
423 /* Check for no convergence to an eigenvalue after a total */
424 /* of N*MAXIT iterations. */
430 for (i__ = 1; i__ <= i__1; ++i__) {
438 /* Sort eigenvalues in increasing order. */
441 dlasrt_("I", n, &d__[1], info);