3 /* Table of constant values */
5 static real c_b3 = -1.f;
6 static integer c__1 = 1;
8 /* Subroutine */ int slaed8_(integer *icompq, integer *k, integer *n, integer
9 *qsiz, real *d__, real *q, integer *ldq, integer *indxq, real *rho,
10 integer *cutpnt, real *z__, real *dlamda, real *q2, integer *ldq2,
11 real *w, integer *perm, integer *givptr, integer *givcol, real *
12 givnum, integer *indxp, integer *indx, integer *info)
14 /* System generated locals */
15 integer q_dim1, q_offset, q2_dim1, q2_offset, i__1;
18 /* Builtin functions */
19 double sqrt(doublereal);
25 integer k2, n1, n2, jp, n1p1;
27 integer jlam, imax, jmax;
28 extern /* Subroutine */ int srot_(integer *, real *, integer *, real *,
29 integer *, real *, real *), sscal_(integer *, real *, real *,
30 integer *), scopy_(integer *, real *, integer *, real *, integer *
32 extern doublereal slapy2_(real *, real *), slamch_(char *);
33 extern /* Subroutine */ int xerbla_(char *, integer *);
34 extern integer isamax_(integer *, real *, integer *);
35 extern /* Subroutine */ int slamrg_(integer *, integer *, real *, integer
36 *, integer *, integer *), slacpy_(char *, integer *, integer *,
37 real *, integer *, real *, integer *);
40 /* -- LAPACK routine (version 3.1) -- */
41 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
44 /* .. Scalar Arguments .. */
46 /* .. Array Arguments .. */
52 /* SLAED8 merges the two sets of eigenvalues together into a single */
53 /* sorted set. Then it tries to deflate the size of the problem. */
54 /* There are two ways in which deflation can occur: when two or more */
55 /* eigenvalues are close together or if there is a tiny element in the */
56 /* Z vector. For each such occurrence the order of the related secular */
57 /* equation problem is reduced by one. */
62 /* ICOMPQ (input) INTEGER */
63 /* = 0: Compute eigenvalues only. */
64 /* = 1: Compute eigenvectors of original dense symmetric matrix */
65 /* also. On entry, Q contains the orthogonal matrix used */
66 /* to reduce the original matrix to tridiagonal form. */
68 /* K (output) INTEGER */
69 /* The number of non-deflated eigenvalues, and the order of the */
70 /* related secular equation. */
72 /* N (input) INTEGER */
73 /* The dimension of the symmetric tridiagonal matrix. N >= 0. */
75 /* QSIZ (input) INTEGER */
76 /* The dimension of the orthogonal matrix used to reduce */
77 /* the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1. */
79 /* D (input/output) REAL array, dimension (N) */
80 /* On entry, the eigenvalues of the two submatrices to be */
81 /* combined. On exit, the trailing (N-K) updated eigenvalues */
82 /* (those which were deflated) sorted into increasing order. */
84 /* Q (input/output) REAL array, dimension (LDQ,N) */
85 /* If ICOMPQ = 0, Q is not referenced. Otherwise, */
86 /* on entry, Q contains the eigenvectors of the partially solved */
87 /* system which has been previously updated in matrix */
88 /* multiplies with other partially solved eigensystems. */
89 /* On exit, Q contains the trailing (N-K) updated eigenvectors */
90 /* (those which were deflated) in its last N-K columns. */
92 /* LDQ (input) INTEGER */
93 /* The leading dimension of the array Q. LDQ >= max(1,N). */
95 /* INDXQ (input) INTEGER array, dimension (N) */
96 /* The permutation which separately sorts the two sub-problems */
97 /* in D into ascending order. Note that elements in the second */
98 /* half of this permutation must first have CUTPNT added to */
99 /* their values in order to be accurate. */
101 /* RHO (input/output) REAL */
102 /* On entry, the off-diagonal element associated with the rank-1 */
103 /* cut which originally split the two submatrices which are now */
104 /* being recombined. */
105 /* On exit, RHO has been modified to the value required by */
108 /* CUTPNT (input) INTEGER */
109 /* The location of the last eigenvalue in the leading */
110 /* sub-matrix. min(1,N) <= CUTPNT <= N. */
112 /* Z (input) REAL array, dimension (N) */
113 /* On entry, Z contains the updating vector (the last row of */
114 /* the first sub-eigenvector matrix and the first row of the */
115 /* second sub-eigenvector matrix). */
116 /* On exit, the contents of Z are destroyed by the updating */
119 /* DLAMDA (output) REAL array, dimension (N) */
120 /* A copy of the first K eigenvalues which will be used by */
121 /* SLAED3 to form the secular equation. */
123 /* Q2 (output) REAL array, dimension (LDQ2,N) */
124 /* If ICOMPQ = 0, Q2 is not referenced. Otherwise, */
125 /* a copy of the first K eigenvectors which will be used by */
126 /* SLAED7 in a matrix multiply (SGEMM) to update the new */
129 /* LDQ2 (input) INTEGER */
130 /* The leading dimension of the array Q2. LDQ2 >= max(1,N). */
132 /* W (output) REAL array, dimension (N) */
133 /* The first k values of the final deflation-altered z-vector and */
134 /* will be passed to SLAED3. */
136 /* PERM (output) INTEGER array, dimension (N) */
137 /* The permutations (from deflation and sorting) to be applied */
138 /* to each eigenblock. */
140 /* GIVPTR (output) INTEGER */
141 /* The number of Givens rotations which took place in this */
144 /* GIVCOL (output) INTEGER array, dimension (2, N) */
145 /* Each pair of numbers indicates a pair of columns to take place */
146 /* in a Givens rotation. */
148 /* GIVNUM (output) REAL array, dimension (2, N) */
149 /* Each number indicates the S value to be used in the */
150 /* corresponding Givens rotation. */
152 /* INDXP (workspace) INTEGER array, dimension (N) */
153 /* The permutation used to place deflated values of D at the end */
154 /* of the array. INDXP(1:K) points to the nondeflated D-values */
155 /* and INDXP(K+1:N) points to the deflated eigenvalues. */
157 /* INDX (workspace) INTEGER array, dimension (N) */
158 /* The permutation used to sort the contents of D into ascending */
161 /* INFO (output) INTEGER */
162 /* = 0: successful exit. */
163 /* < 0: if INFO = -i, the i-th argument had an illegal value. */
165 /* Further Details */
166 /* =============== */
168 /* Based on contributions by */
169 /* Jeff Rutter, Computer Science Division, University of California */
170 /* at Berkeley, USA */
172 /* ===================================================================== */
174 /* .. Parameters .. */
176 /* .. Local Scalars .. */
179 /* .. External Functions .. */
181 /* .. External Subroutines .. */
183 /* .. Intrinsic Functions .. */
185 /* .. Executable Statements .. */
187 /* Test the input parameters. */
189 /* Parameter adjustments */
192 q_offset = 1 + q_dim1;
198 q2_offset = 1 + q2_dim1;
210 if (*icompq < 0 || *icompq > 1) {
214 } else if (*icompq == 1 && *qsiz < *n) {
216 } else if (*ldq < max(1,*n)) {
218 } else if (*cutpnt < min(1,*n) || *cutpnt > *n) {
220 } else if (*ldq2 < max(1,*n)) {
225 xerbla_("SLAED8", &i__1);
229 /* Quick return if possible */
240 sscal_(&n2, &c_b3, &z__[n1p1], &c__1);
243 /* Normalize z so that norm(z) = 1 */
247 for (j = 1; j <= i__1; ++j) {
251 sscal_(n, &t, &z__[1], &c__1);
252 *rho = (r__1 = *rho * 2.f, dabs(r__1));
254 /* Sort the eigenvalues into increasing order */
257 for (i__ = *cutpnt + 1; i__ <= i__1; ++i__) {
258 indxq[i__] += *cutpnt;
262 for (i__ = 1; i__ <= i__1; ++i__) {
263 dlamda[i__] = d__[indxq[i__]];
264 w[i__] = z__[indxq[i__]];
269 slamrg_(&n1, &n2, &dlamda[1], &c__1, &c__1, &indx[1]);
271 for (i__ = 1; i__ <= i__1; ++i__) {
272 d__[i__] = dlamda[indx[i__]];
273 z__[i__] = w[indx[i__]];
277 /* Calculate the allowable deflation tolerence */
279 imax = isamax_(n, &z__[1], &c__1);
280 jmax = isamax_(n, &d__[1], &c__1);
281 eps = slamch_("Epsilon");
282 tol = eps * 8.f * (r__1 = d__[jmax], dabs(r__1));
284 /* If the rank-1 modifier is small enough, no more needs to be done */
285 /* except to reorganize Q so that its columns correspond with the */
288 if (*rho * (r__1 = z__[imax], dabs(r__1)) <= tol) {
292 for (j = 1; j <= i__1; ++j) {
293 perm[j] = indxq[indx[j]];
298 for (j = 1; j <= i__1; ++j) {
299 perm[j] = indxq[indx[j]];
300 scopy_(qsiz, &q[perm[j] * q_dim1 + 1], &c__1, &q2[j * q2_dim1
304 slacpy_("A", qsiz, n, &q2[q2_dim1 + 1], ldq2, &q[q_dim1 + 1], ldq);
309 /* If there are multiple eigenvalues then the problem deflates. Here */
310 /* the number of equal eigenvalues are found. As each equal */
311 /* eigenvalue is found, an elementary reflector is computed to rotate */
312 /* the corresponding eigensubspace so that the corresponding */
313 /* components of Z are zero in this new basis. */
319 for (j = 1; j <= i__1; ++j) {
320 if (*rho * (r__1 = z__[j], dabs(r__1)) <= tol) {
322 /* Deflate due to small z component. */
340 if (*rho * (r__1 = z__[j], dabs(r__1)) <= tol) {
342 /* Deflate due to small z component. */
348 /* Check if eigenvalues are close enough to allow deflation. */
353 /* Find sqrt(a**2+b**2) without overflow or */
354 /* destructive underflow. */
356 tau = slapy2_(&c__, &s);
357 t = d__[j] - d__[jlam];
360 if ((r__1 = t * c__ * s, dabs(r__1)) <= tol) {
362 /* Deflation is possible. */
367 /* Record the appropriate Givens rotation */
370 givcol[(*givptr << 1) + 1] = indxq[indx[jlam]];
371 givcol[(*givptr << 1) + 2] = indxq[indx[j]];
372 givnum[(*givptr << 1) + 1] = c__;
373 givnum[(*givptr << 1) + 2] = s;
375 srot_(qsiz, &q[indxq[indx[jlam]] * q_dim1 + 1], &c__1, &q[
376 indxq[indx[j]] * q_dim1 + 1], &c__1, &c__, &s);
378 t = d__[jlam] * c__ * c__ + d__[j] * s * s;
379 d__[j] = d__[jlam] * s * s + d__[j] * c__ * c__;
384 if (k2 + i__ <= *n) {
385 if (d__[jlam] < d__[indxp[k2 + i__]]) {
386 indxp[k2 + i__ - 1] = indxp[k2 + i__];
387 indxp[k2 + i__] = jlam;
391 indxp[k2 + i__ - 1] = jlam;
394 indxp[k2 + i__ - 1] = jlam;
400 dlamda[*k] = d__[jlam];
408 /* Record the last eigenvalue. */
412 dlamda[*k] = d__[jlam];
417 /* Sort the eigenvalues and corresponding eigenvectors into DLAMDA */
418 /* and Q2 respectively. The eigenvalues/vectors which were not */
419 /* deflated go into the first K slots of DLAMDA and Q2 respectively, */
420 /* while those which were deflated go into the last N - K slots. */
424 for (j = 1; j <= i__1; ++j) {
427 perm[j] = indxq[indx[jp]];
432 for (j = 1; j <= i__1; ++j) {
435 perm[j] = indxq[indx[jp]];
436 scopy_(qsiz, &q[perm[j] * q_dim1 + 1], &c__1, &q2[j * q2_dim1 + 1]
442 /* The deflated eigenvalues and their corresponding vectors go back */
443 /* into the last N - K slots of D and Q respectively. */
448 scopy_(&i__1, &dlamda[*k + 1], &c__1, &d__[*k + 1], &c__1);
451 scopy_(&i__1, &dlamda[*k + 1], &c__1, &d__[*k + 1], &c__1);
453 slacpy_("A", qsiz, &i__1, &q2[(*k + 1) * q2_dim1 + 1], ldq2, &q[(*
454 k + 1) * q_dim1 + 1], ldq);