1 /* dsterf.f -- translated by f2c (version 20061008).
2 You must link the resulting object file with libf2c:
3 on Microsoft Windows system, link with libf2c.lib;
4 on Linux or Unix systems, link with .../path/to/libf2c.a -lm
5 or, if you install libf2c.a in a standard place, with -lf2c -lm
6 -- in that order, at the end of the command line, as in
8 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
10 http://www.netlib.org/f2c/libf2c.zip
16 /* Table of constant values */
18 static integer c__0 = 0;
19 static integer c__1 = 1;
20 static doublereal c_b32 = 1.;
22 /* Subroutine */ int dsterf_(integer *n, doublereal *d__, doublereal *e,
25 /* System generated locals */
27 doublereal d__1, d__2, d__3;
29 /* Builtin functions */
30 double sqrt(doublereal), d_sign(doublereal *, doublereal *);
37 doublereal bb, rt1, rt2, eps, rte;
39 doublereal eps2, oldc;
41 extern /* Subroutine */ int dlae2_(doublereal *, doublereal *, doublereal
42 *, doublereal *, doublereal *);
43 doublereal gamma, alpha, sigma, anorm;
44 extern doublereal dlapy2_(doublereal *, doublereal *), dlamch_(char *);
46 extern /* Subroutine */ int dlascl_(char *, integer *, integer *,
47 doublereal *, doublereal *, integer *, integer *, doublereal *,
48 integer *, integer *);
49 doublereal oldgam, safmin;
50 extern /* Subroutine */ int xerbla_(char *, integer *);
52 extern doublereal dlanst_(char *, integer *, doublereal *, doublereal *);
53 extern /* Subroutine */ int dlasrt_(char *, integer *, doublereal *,
61 /* -- LAPACK routine (version 3.2) -- */
62 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
65 /* .. Scalar Arguments .. */
67 /* .. Array Arguments .. */
73 /* DSTERF computes all eigenvalues of a symmetric tridiagonal matrix */
74 /* using the Pal-Walker-Kahan variant of the QL or QR algorithm. */
79 /* N (input) INTEGER */
80 /* The order of the matrix. N >= 0. */
82 /* D (input/output) DOUBLE PRECISION array, dimension (N) */
83 /* On entry, the n diagonal elements of the tridiagonal matrix. */
84 /* On exit, if INFO = 0, the eigenvalues in ascending order. */
86 /* E (input/output) DOUBLE PRECISION array, dimension (N-1) */
87 /* On entry, the (n-1) subdiagonal elements of the tridiagonal */
89 /* On exit, E has been destroyed. */
91 /* INFO (output) INTEGER */
92 /* = 0: successful exit */
93 /* < 0: if INFO = -i, the i-th argument had an illegal value */
94 /* > 0: the algorithm failed to find all of the eigenvalues in */
95 /* a total of 30*N iterations; if INFO = i, then i */
96 /* elements of E have not converged to zero. */
98 /* ===================================================================== */
100 /* .. Parameters .. */
102 /* .. Local Scalars .. */
104 /* .. External Functions .. */
106 /* .. External Subroutines .. */
108 /* .. Intrinsic Functions .. */
110 /* .. Executable Statements .. */
112 /* Test the input parameters. */
114 /* Parameter adjustments */
121 /* Quick return if possible */
126 xerbla_("DSTERF", &i__1);
133 /* Determine the unit roundoff for this environment. */
136 /* Computing 2nd power */
139 safmin = dlamch_("S");
140 safmax = 1. / safmin;
141 ssfmax = sqrt(safmax) / 3.;
142 ssfmin = sqrt(safmin) / eps2;
144 /* Compute the eigenvalues of the tridiagonal matrix. */
150 /* Determine where the matrix splits and choose QL or QR iteration */
151 /* for each block, according to whether top or bottom diagonal */
152 /* element is smaller. */
164 for (m = l1; m <= i__1; ++m) {
165 if ((d__3 = e[m], abs(d__3)) <= sqrt((d__1 = d__[m], abs(d__1))) *
166 sqrt((d__2 = d__[m + 1], abs(d__2))) * eps) {
184 /* Scale submatrix in rows and columns L to LEND */
187 anorm = dlanst_("I", &i__1, &d__[l], &e[l]);
189 if (anorm > ssfmax) {
192 dlascl_("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n,
195 dlascl_("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n,
197 } else if (anorm < ssfmin) {
200 dlascl_("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n,
203 dlascl_("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n,
208 for (i__ = l; i__ <= i__1; ++i__) {
209 /* Computing 2nd power */
211 e[i__] = d__1 * d__1;
215 /* Choose between QL and QR iteration */
217 if ((d__1 = d__[lend], abs(d__1)) < (d__2 = d__[l], abs(d__2))) {
226 /* Look for small subdiagonal element. */
231 for (m = l; m <= i__1; ++m) {
232 if ((d__2 = e[m], abs(d__2)) <= eps2 * (d__1 = d__[m] * d__[m
250 /* If remaining matrix is 2 by 2, use DLAE2 to compute its */
255 dlae2_(&d__[l], &rte, &d__[l + 1], &rt1, &rt2);
266 if (jtot == nmaxit) {
274 sigma = (d__[l + 1] - p) / (rte * 2.);
275 r__ = dlapy2_(&sigma, &c_b32);
276 sigma = p - rte / (sigma + d_sign(&r__, &sigma));
280 gamma = d__[m] - sigma;
286 for (i__ = m - 1; i__ >= i__1; --i__) {
290 e[i__ + 1] = s * r__;
297 gamma = c__ * (alpha - sigma) - s * oldgam;
298 d__[i__ + 1] = oldgam + (alpha - gamma);
300 p = gamma * gamma / c__;
308 d__[l] = sigma + gamma;
311 /* Eigenvalue found. */
326 /* Look for small superdiagonal element. */
330 for (m = l; m >= i__1; --m) {
331 if ((d__2 = e[m - 1], abs(d__2)) <= eps2 * (d__1 = d__[m] * d__[m
348 /* If remaining matrix is 2 by 2, use DLAE2 to compute its */
352 rte = sqrt(e[l - 1]);
353 dlae2_(&d__[l], &rte, &d__[l - 1], &rt1, &rt2);
364 if (jtot == nmaxit) {
371 rte = sqrt(e[l - 1]);
372 sigma = (d__[l - 1] - p) / (rte * 2.);
373 r__ = dlapy2_(&sigma, &c_b32);
374 sigma = p - rte / (sigma + d_sign(&r__, &sigma));
378 gamma = d__[m] - sigma;
384 for (i__ = m; i__ <= i__1; ++i__) {
388 e[i__ - 1] = s * r__;
394 alpha = d__[i__ + 1];
395 gamma = c__ * (alpha - sigma) - s * oldgam;
396 d__[i__] = oldgam + (alpha - gamma);
398 p = gamma * gamma / c__;
406 d__[l] = sigma + gamma;
409 /* Eigenvalue found. */
422 /* Undo scaling if necessary */
426 i__1 = lendsv - lsv + 1;
427 dlascl_("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv],
431 i__1 = lendsv - lsv + 1;
432 dlascl_("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv],
436 /* Check for no convergence to an eigenvalue after a total */
437 /* of N*MAXIT iterations. */
443 for (i__ = 1; i__ <= i__1; ++i__) {
451 /* Sort eigenvalues in increasing order. */
454 dlasrt_("I", n, &d__[1], info);