3 /* Table of constant values */
5 static real c_b5 = 0.f;
6 static integer c__1 = 1;
7 static integer c__2 = 2;
9 /* Subroutine */ int slarrv_(integer *n, real *vl, real *vu, real *d__, real *
10 l, real *pivmin, integer *isplit, integer *m, integer *dol, integer *
11 dou, real *minrgp, real *rtol1, real *rtol2, real *w, real *werr,
12 real *wgap, integer *iblock, integer *indexw, real *gers, real *z__,
13 integer *ldz, integer *isuppz, real *work, integer *iwork, integer *
16 /* System generated locals */
17 integer z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5;
21 /* Builtin functions */
22 double log(doublereal);
25 integer minwsize, i__, j, k, p, q, miniwsize, ii;
28 real gu, gap, eps, tau, tol, tmp;
43 extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
47 extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *,
50 integer iindc1, iindc2;
51 extern /* Subroutine */ int slar1v_(integer *, integer *, integer *, real
52 *, real *, real *, real *, real *, real *, real *, real *,
53 logical *, integer *, real *, real *, integer *, integer *, real *
54 , real *, real *, real *);
57 integer ibegin, indeig;
61 extern doublereal slamch_(char *);
62 integer oldien, oldncl, wbegin;
64 integer negcnt, oldcls;
69 integer iindwk, offset;
71 extern /* Subroutine */ int slarrb_(integer *, real *, real *, integer *,
72 integer *, real *, real *, integer *, real *, real *, real *,
73 real *, integer *, real *, real *, integer *, integer *), slarrf_(
74 integer *, real *, real *, real *, integer *, integer *, real *,
75 real *, real *, real *, real *, real *, real *, real *, real *,
76 real *, real *, integer *);
77 integer newcls, oldfst, indwrk, windex, oldlst;
79 integer newfst, newftt, parity, windmn, isupmn, newlst, windpl, zusedl,
80 newsiz, zusedu, zusedw;
85 extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *,
86 real *, real *, integer *);
89 /* -- LAPACK auxiliary routine (version 3.1.1) -- */
90 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
93 /* .. Scalar Arguments .. */
95 /* .. Array Arguments .. */
101 /* SLARRV computes the eigenvectors of the tridiagonal matrix */
102 /* T = L D L^T given L, D and APPROXIMATIONS to the eigenvalues of L D L^T. */
103 /* The input eigenvalues should have been computed by SLARRE. */
108 /* N (input) INTEGER */
109 /* The order of the matrix. N >= 0. */
111 /* VL (input) REAL */
112 /* VU (input) REAL */
113 /* Lower and upper bounds of the interval that contains the desired */
114 /* eigenvalues. VL < VU. Needed to compute gaps on the left or right */
115 /* end of the extremal eigenvalues in the desired RANGE. */
117 /* D (input/output) REAL array, dimension (N) */
118 /* On entry, the N diagonal elements of the diagonal matrix D. */
119 /* On exit, D may be overwritten. */
121 /* L (input/output) REAL array, dimension (N) */
122 /* On entry, the (N-1) subdiagonal elements of the unit */
123 /* bidiagonal matrix L are in elements 1 to N-1 of L */
124 /* (if the matrix is not splitted.) At the end of each block */
125 /* is stored the corresponding shift as given by SLARRE. */
126 /* On exit, L is overwritten. */
128 /* PIVMIN (in) DOUBLE PRECISION */
129 /* The minimum pivot allowed in the Sturm sequence. */
131 /* ISPLIT (input) INTEGER array, dimension (N) */
132 /* The splitting points, at which T breaks up into blocks. */
133 /* The first block consists of rows/columns 1 to */
134 /* ISPLIT( 1 ), the second of rows/columns ISPLIT( 1 )+1 */
135 /* through ISPLIT( 2 ), etc. */
137 /* M (input) INTEGER */
138 /* The total number of input eigenvalues. 0 <= M <= N. */
140 /* DOL (input) INTEGER */
141 /* DOU (input) INTEGER */
142 /* If the user wants to compute only selected eigenvectors from all */
143 /* the eigenvalues supplied, he can specify an index range DOL:DOU. */
144 /* Or else the setting DOL=1, DOU=M should be applied. */
145 /* Note that DOL and DOU refer to the order in which the eigenvalues */
146 /* are stored in W. */
147 /* If the user wants to compute only selected eigenpairs, then */
148 /* the columns DOL-1 to DOU+1 of the eigenvector space Z contain the */
149 /* computed eigenvectors. All other columns of Z are set to zero. */
151 /* MINRGP (input) REAL */
153 /* RTOL1 (input) REAL */
154 /* RTOL2 (input) REAL */
155 /* Parameters for bisection. */
156 /* An interval [LEFT,RIGHT] has converged if */
157 /* RIGHT-LEFT.LT.MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) ) */
159 /* W (input/output) REAL array, dimension (N) */
160 /* The first M elements of W contain the APPROXIMATE eigenvalues for */
161 /* which eigenvectors are to be computed. The eigenvalues */
162 /* should be grouped by split-off block and ordered from */
163 /* smallest to largest within the block ( The output array */
164 /* W from SLARRE is expected here ). Furthermore, they are with */
165 /* respect to the shift of the corresponding root representation */
166 /* for their block. On exit, W holds the eigenvalues of the */
167 /* UNshifted matrix. */
169 /* WERR (input/output) REAL array, dimension (N) */
170 /* The first M elements contain the semiwidth of the uncertainty */
171 /* interval of the corresponding eigenvalue in W */
173 /* WGAP (input/output) REAL array, dimension (N) */
174 /* The separation from the right neighbor eigenvalue in W. */
176 /* IBLOCK (input) INTEGER array, dimension (N) */
177 /* The indices of the blocks (submatrices) associated with the */
178 /* corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue */
179 /* W(i) belongs to the first block from the top, =2 if W(i) */
180 /* belongs to the second block, etc. */
182 /* INDEXW (input) INTEGER array, dimension (N) */
183 /* The indices of the eigenvalues within each block (submatrix); */
184 /* for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the */
185 /* i-th eigenvalue W(i) is the 10-th eigenvalue in the second block. */
187 /* GERS (input) REAL array, dimension (2*N) */
188 /* The N Gerschgorin intervals (the i-th Gerschgorin interval */
189 /* is (GERS(2*i-1), GERS(2*i)). The Gerschgorin intervals should */
190 /* be computed from the original UNshifted matrix. */
192 /* Z (output) REAL array, dimension (LDZ, max(1,M) ) */
193 /* If INFO = 0, the first M columns of Z contain the */
194 /* orthonormal eigenvectors of the matrix T */
195 /* corresponding to the input eigenvalues, with the i-th */
196 /* column of Z holding the eigenvector associated with W(i). */
197 /* Note: the user must ensure that at least max(1,M) columns are */
198 /* supplied in the array Z. */
200 /* LDZ (input) INTEGER */
201 /* The leading dimension of the array Z. LDZ >= 1, and if */
202 /* JOBZ = 'V', LDZ >= max(1,N). */
204 /* ISUPPZ (output) INTEGER array, dimension ( 2*max(1,M) ) */
205 /* The support of the eigenvectors in Z, i.e., the indices */
206 /* indicating the nonzero elements in Z. The I-th eigenvector */
207 /* is nonzero only in elements ISUPPZ( 2*I-1 ) through */
210 /* WORK (workspace) REAL array, dimension (12*N) */
212 /* IWORK (workspace) INTEGER array, dimension (7*N) */
214 /* INFO (output) INTEGER */
215 /* = 0: successful exit */
217 /* > 0: A problem occured in SLARRV. */
218 /* < 0: One of the called subroutines signaled an internal problem. */
219 /* Needs inspection of the corresponding parameter IINFO */
220 /* for further information. */
222 /* =-1: Problem in SLARRB when refining a child's eigenvalues. */
223 /* =-2: Problem in SLARRF when computing the RRR of a child. */
224 /* When a child is inside a tight cluster, it can be difficult */
225 /* to find an RRR. A partial remedy from the user's point of */
226 /* view is to make the parameter MINRGP smaller and recompile. */
227 /* However, as the orthogonality of the computed vectors is */
228 /* proportional to 1/MINRGP, the user should be aware that */
229 /* he might be trading in precision when he decreases MINRGP. */
230 /* =-3: Problem in SLARRB when refining a single eigenvalue */
231 /* after the Rayleigh correction was rejected. */
232 /* = 5: The Rayleigh Quotient Iteration failed to converge to */
233 /* full accuracy in MAXITR steps. */
235 /* Further Details */
236 /* =============== */
238 /* Based on contributions by */
239 /* Beresford Parlett, University of California, Berkeley, USA */
240 /* Jim Demmel, University of California, Berkeley, USA */
241 /* Inderjit Dhillon, University of Texas, Austin, USA */
242 /* Osni Marques, LBNL/NERSC, USA */
243 /* Christof Voemel, University of California, Berkeley, USA */
245 /* ===================================================================== */
247 /* .. Parameters .. */
249 /* .. Local Scalars .. */
251 /* .. External Functions .. */
253 /* .. External Subroutines .. */
255 /* .. Intrinsic Functions .. */
257 /* .. Executable Statements .. */
259 /* The first N entries of WORK are reserved for the eigenvalues */
260 /* Parameter adjustments */
271 z_offset = 1 + z_dim1;
279 indlld = (*n << 1) + 1;
283 for (i__ = 1; i__ <= i__1; ++i__) {
287 /* IWORK(IINDR+1:IINDR+N) hold the twist indices R for the */
288 /* factorization used to compute the FP vector */
290 /* IWORK(IINDC1+1:IINC2+N) are used to store the clusters of the current */
291 /* layer and the one above. */
297 for (i__ = 1; i__ <= i__1; ++i__) {
303 /* Set lower bound for use of Z */
308 /* Set lower bound for use of Z */
311 /* The width of the part of Z that is used */
312 zusedw = zusedu - zusedl + 1;
313 slaset_("Full", n, &zusedw, &c_b5, &c_b5, &z__[zusedl * z_dim1 + 1], ldz);
314 eps = slamch_("Precision");
317 /* Set expert flags for standard code. */
319 if (*dol == 1 && *dou == *m) {
321 /* Only selected eigenpairs are computed. Since the other evalues */
322 /* are not refined by RQ iteration, bisection has to compute to full */
327 /* The entries WBEGIN:WEND in W, WERR, WGAP correspond to the */
328 /* desired eigenvalues. The support of the nonzero eigenvector */
329 /* entries is contained in the interval IBEGIN:IEND. */
330 /* Remark that if k eigenpairs are desired, then the eigenvectors */
331 /* are stored in k contiguous columns of Z. */
332 /* DONE is the number of eigenvectors already computed */
337 for (jblk = 1; jblk <= i__1; ++jblk) {
340 /* Find the eigenvectors of the submatrix indexed IBEGIN */
345 if (iblock[wend + 1] == jblk) {
353 } else if (wend < *dol || wbegin > *dou) {
358 /* Find local spectral diameter of the block */
359 gl = gers[(ibegin << 1) - 1];
360 gu = gers[ibegin * 2];
362 for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
364 r__1 = gers[(i__ << 1) - 1];
367 r__1 = gers[i__ * 2];
372 /* OLDIEN is the last index of the previous block */
374 /* Calculate the size of the current block */
375 in = iend - ibegin + 1;
376 /* The number of eigenvalues in the current block */
377 im = wend - wbegin + 1;
378 /* This is for a 1x1 block */
379 if (ibegin == iend) {
381 z__[ibegin + wbegin * z_dim1] = 1.f;
382 isuppz[(wbegin << 1) - 1] = ibegin;
383 isuppz[wbegin * 2] = ibegin;
385 work[wbegin] = w[wbegin];
390 /* The desired (shifted) eigenvalues are stored in W(WBEGIN:WEND) */
391 /* Note that these can be approximations, in this case, the corresp. */
392 /* entries of WERR give the size of the uncertainty interval. */
393 /* The eigenvalue approximations will be refined when necessary as */
394 /* high relative accuracy is required for the computation of the */
395 /* corresponding eigenvectors. */
396 scopy_(&im, &w[wbegin], &c__1, &work[wbegin], &c__1);
397 /* We store in W the eigenvalue approximations w.r.t. the original */
400 for (i__ = 1; i__ <= i__2; ++i__) {
401 w[wbegin + i__ - 1] += sigma;
404 /* NDEPTH is the current depth of the representation tree */
406 /* PARITY is either 1 or 0 */
408 /* NCLUS is the number of clusters for the next level of the */
409 /* representation tree, we start with NCLUS = 1 for the root */
411 iwork[iindc1 + 1] = 1;
412 iwork[iindc1 + 2] = im;
413 /* IDONE is the number of eigenvectors already computed in the current */
416 /* loop while( IDONE.LT.IM ) */
417 /* generate the representation tree for the current block and */
418 /* compute the eigenvectors */
421 /* This is a crude protection against infinitely deep trees */
426 /* breadth first processing of the current level of the representation */
427 /* tree: OLDNCL = number of clusters on current level */
429 /* reset NCLUS to count the number of child clusters */
440 /* Process the clusters on the current level */
442 for (i__ = 1; i__ <= i__2; ++i__) {
443 j = oldcls + (i__ << 1);
444 /* OLDFST, OLDLST = first, last index of current cluster. */
445 /* cluster indices start with 1 and are relative */
446 /* to WBEGIN when accessing W, WGAP, WERR, Z */
447 oldfst = iwork[j - 1];
450 /* Retrieve relatively robust representation (RRR) of cluster */
451 /* that has been computed at the previous level */
452 /* The RRR is stored in Z and overwritten once the eigenvectors */
453 /* have been computed or when the cluster is refined */
454 if (*dol == 1 && *dou == *m) {
455 /* Get representation from location of the leftmost evalue */
457 j = wbegin + oldfst - 1;
459 if (wbegin + oldfst - 1 < *dol) {
460 /* Get representation from the left end of Z array */
462 } else if (wbegin + oldfst - 1 > *dou) {
463 /* Get representation from the right end of Z array */
466 j = wbegin + oldfst - 1;
469 scopy_(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
472 scopy_(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
474 sigma = z__[iend + (j + 1) * z_dim1];
475 /* Set the corresponding entries in Z to zero */
476 slaset_("Full", &in, &c__2, &c_b5, &c_b5, &z__[ibegin + j
479 /* Compute DL and DLL of current RRR */
481 for (j = ibegin; j <= i__3; ++j) {
483 work[indld - 1 + j] = tmp;
484 work[indlld - 1 + j] = tmp * l[j];
488 /* P and Q are index of the first and last eigenvalue to compute */
489 /* within the current block */
490 p = indexw[wbegin - 1 + oldfst];
491 q = indexw[wbegin - 1 + oldlst];
492 /* Offset for the arrays WORK, WGAP and WERR, i.e., th P-OFFSET */
493 /* thru' Q-OFFSET elements of these arrays are to be used. */
494 /* OFFSET = P-OLDFST */
495 offset = indexw[wbegin] - 1;
496 /* perform limited bisection (if necessary) to get approximate */
497 /* eigenvalues to the precision needed. */
498 slarrb_(&in, &d__[ibegin], &work[indlld + ibegin - 1], &p,
499 &q, rtol1, rtol2, &offset, &work[wbegin], &wgap[
500 wbegin], &werr[wbegin], &work[indwrk], &iwork[
501 iindwk], pivmin, &spdiam, &in, &iinfo);
506 /* We also recompute the extremal gaps. W holds all eigenvalues */
507 /* of the unshifted matrix and must be used for computation */
508 /* of WGAP, the entries of WORK might stem from RRRs with */
509 /* different shifts. The gaps from WBEGIN-1+OLDFST to */
510 /* WBEGIN-1+OLDLST are correctly computed in SLARRB. */
511 /* However, we only allow the gaps to become greater since */
512 /* this is what should happen when we decrease WERR */
515 r__1 = wgap[wbegin + oldfst - 2], r__2 = w[wbegin +
516 oldfst - 1] - werr[wbegin + oldfst - 1] - w[
517 wbegin + oldfst - 2] - werr[wbegin + oldfst -
519 wgap[wbegin + oldfst - 2] = dmax(r__1,r__2);
521 if (wbegin + oldlst - 1 < wend) {
523 r__1 = wgap[wbegin + oldlst - 1], r__2 = w[wbegin +
524 oldlst] - werr[wbegin + oldlst] - w[wbegin +
525 oldlst - 1] - werr[wbegin + oldlst - 1];
526 wgap[wbegin + oldlst - 1] = dmax(r__1,r__2);
528 /* Each time the eigenvalues in WORK get refined, we store */
529 /* the newly found approximation with all shifts applied in W */
531 for (j = oldfst; j <= i__3; ++j) {
532 w[wbegin + j - 1] = work[wbegin + j - 1] + sigma;
536 /* Process the current node. */
539 for (j = oldfst; j <= i__3; ++j) {
541 /* we are at the right end of the cluster, this is also the */
542 /* boundary of the child cluster */
544 } else if (wgap[wbegin + j - 1] >= *minrgp * (r__1 = work[
545 wbegin + j - 1], dabs(r__1))) {
546 /* the right relative gap is big enough, the child cluster */
547 /* (NEWFST,..,NEWLST) is well separated from the following */
550 /* inside a child cluster, the relative gap is not */
554 /* Compute size of child cluster found */
555 newsiz = newlst - newfst + 1;
556 /* NEWFTT is the place in Z where the new RRR or the computed */
557 /* eigenvector is to be stored */
558 if (*dol == 1 && *dou == *m) {
559 /* Store representation at location of the leftmost evalue */
561 newftt = wbegin + newfst - 1;
563 if (wbegin + newfst - 1 < *dol) {
564 /* Store representation at the left end of Z array */
566 } else if (wbegin + newfst - 1 > *dou) {
567 /* Store representation at the right end of Z array */
570 newftt = wbegin + newfst - 1;
575 /* Current child is not a singleton but a cluster. */
576 /* Compute and store new representation of child. */
579 /* Compute left and right cluster gap. */
581 /* LGAP and RGAP are not computed from WORK because */
582 /* the eigenvalue approximations may stem from RRRs */
583 /* different shifts. However, W hold all eigenvalues */
584 /* of the unshifted matrix. Still, the entries in WGAP */
585 /* have to be computed from WORK since the entries */
586 /* in W might be of the same order so that gaps are not */
587 /* exhibited correctly for very close eigenvalues. */
590 r__1 = 0.f, r__2 = w[wbegin] - werr[wbegin] - *vl;
591 lgap = dmax(r__1,r__2);
593 lgap = wgap[wbegin + newfst - 2];
595 rgap = wgap[wbegin + newlst - 1];
597 /* Compute left- and rightmost eigenvalue of child */
598 /* to high precision in order to shift as close */
599 /* as possible and obtain as large relative gaps */
602 for (k = 1; k <= 2; ++k) {
604 p = indexw[wbegin - 1 + newfst];
606 p = indexw[wbegin - 1 + newlst];
608 offset = indexw[wbegin] - 1;
609 slarrb_(&in, &d__[ibegin], &work[indlld + ibegin
610 - 1], &p, &p, &rqtol, &rqtol, &offset, &
611 work[wbegin], &wgap[wbegin], &werr[wbegin]
612 , &work[indwrk], &iwork[iindwk], pivmin, &
613 spdiam, &in, &iinfo);
617 if (wbegin + newlst - 1 < *dol || wbegin + newfst - 1
619 /* if the cluster contains no desired eigenvalues */
620 /* skip the computation of that branch of the rep. tree */
622 /* We could skip before the refinement of the extremal */
623 /* eigenvalues of the child, but then the representation */
624 /* tree could be different from the one when nothing is */
625 /* skipped. For this reason we skip at this place. */
626 idone = idone + newlst - newfst + 1;
630 /* Compute RRR of child cluster. */
631 /* Note that the new RRR is stored in Z */
633 /* SLARRF needs LWORK = 2*N */
634 slarrf_(&in, &d__[ibegin], &l[ibegin], &work[indld +
635 ibegin - 1], &newfst, &newlst, &work[wbegin],
636 &wgap[wbegin], &werr[wbegin], &spdiam, &lgap,
637 &rgap, pivmin, &tau, &z__[ibegin + newftt *
638 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
639 &work[indwrk], &iinfo);
641 /* a new RRR for the cluster was found by SLARRF */
642 /* update shift and store it */
643 ssigma = sigma + tau;
644 z__[iend + (newftt + 1) * z_dim1] = ssigma;
645 /* WORK() are the midpoints and WERR() the semi-width */
646 /* Note that the entries in W are unchanged. */
648 for (k = newfst; k <= i__4; ++k) {
649 fudge = eps * 3.f * (r__1 = work[wbegin + k -
651 work[wbegin + k - 1] -= tau;
652 fudge += eps * 4.f * (r__1 = work[wbegin + k
655 werr[wbegin + k - 1] += fudge;
656 /* Gaps are not fudged. Provided that WERR is small */
657 /* when eigenvalues are close, a zero gap indicates */
658 /* that a new representation is needed for resolving */
659 /* the cluster. A fudge could lead to a wrong decision */
660 /* of judging eigenvalues 'separated' which in */
661 /* reality are not. This could have a negative impact */
662 /* on the orthogonality of the computed eigenvectors. */
666 k = newcls + (nclus << 1);
667 iwork[k - 1] = newfst;
675 /* Compute eigenvector of singleton */
679 tol = log((real) in) * 4.f * eps;
682 windex = wbegin + k - 1;
685 windmn = max(i__4,1);
688 windpl = min(i__4,*m);
689 lambda = work[windex];
691 /* Check if eigenvector computation is to be skipped */
692 if (windex < *dol || windex > *dou) {
698 left = work[windex] - werr[windex];
699 right = work[windex] + werr[windex];
700 indeig = indexw[windex];
701 /* Note that since we compute the eigenpairs for a child, */
702 /* all eigenvalue approximations are w.r.t the same shift. */
703 /* In this case, the entries in WORK should be used for */
704 /* computing the gaps since they exhibit even very small */
705 /* differences in the eigenvalues, as opposed to the */
706 /* entries in W which might "look" the same. */
708 /* In the case RANGE='I' and with not much initial */
709 /* accuracy in LAMBDA and VL, the formula */
710 /* LGAP = MAX( ZERO, (SIGMA - VL) + LAMBDA ) */
711 /* can lead to an overestimation of the left gap and */
712 /* thus to inadequately early RQI 'convergence'. */
713 /* Prevent this by forcing a small left gap. */
715 r__1 = dabs(left), r__2 = dabs(right);
716 lgap = eps * dmax(r__1,r__2);
721 /* In the case RANGE='I' and with not much initial */
722 /* accuracy in LAMBDA and VU, the formula */
723 /* can lead to an overestimation of the right gap and */
724 /* thus to inadequately early RQI 'convergence'. */
725 /* Prevent this by forcing a small right gap. */
727 r__1 = dabs(left), r__2 = dabs(right);
728 rgap = eps * dmax(r__1,r__2);
732 gap = dmin(lgap,rgap);
733 if (k == 1 || k == im) {
734 /* The eigenvector support can become wrong */
735 /* because significant entries could be cut off due to a */
736 /* large GAPTOL parameter in LAR1V. Prevent this. */
743 /* Update WGAP so that it holds the minimum gap */
744 /* to the left or the right. This is crucial in the */
745 /* case where bisection is used to ensure that the */
746 /* eigenvalue is refined up to the required precision. */
747 /* The correct value is restored afterwards. */
748 savgap = wgap[windex];
750 /* We want to use the Rayleigh Quotient Correction */
751 /* as often as possible since it converges quadratically */
752 /* when we are close enough to the desired eigenvalue. */
753 /* However, the Rayleigh Quotient can have the wrong sign */
754 /* and lead us away from the desired eigenvalue. In this */
755 /* case, the best we can do is to use bisection. */
758 /* Bisection is initially turned off unless it is forced */
761 /* Check if bisection should be used to refine eigenvalue */
763 /* Take the bisection as new iterate */
765 itmp1 = iwork[iindr + windex];
766 offset = indexw[wbegin] - 1;
768 slarrb_(&in, &d__[ibegin], &work[indlld + ibegin
769 - 1], &indeig, &indeig, &c_b5, &r__1, &
770 offset, &work[wbegin], &wgap[wbegin], &
771 werr[wbegin], &work[indwrk], &iwork[
772 iindwk], pivmin, &spdiam, &itmp1, &iinfo);
777 lambda = work[windex];
778 /* Reset twist index from inaccurate LAMBDA to */
779 /* force computation of true MINGMA */
780 iwork[iindr + windex] = 0;
782 /* Given LAMBDA, compute the eigenvector. */
784 slar1v_(&in, &c__1, &in, &lambda, &d__[ibegin], &l[
785 ibegin], &work[indld + ibegin - 1], &work[
786 indlld + ibegin - 1], pivmin, &gaptol, &z__[
787 ibegin + windex * z_dim1], &L__1, &negcnt, &
788 ztz, &mingma, &iwork[iindr + windex], &isuppz[
789 (windex << 1) - 1], &nrminv, &resid, &rqcorr,
794 } else if (resid < bstres) {
799 i__4 = isupmn, i__5 = isuppz[(windex << 1) - 1];
800 isupmn = min(i__4,i__5);
802 i__4 = isupmx, i__5 = isuppz[windex * 2];
803 isupmx = max(i__4,i__5);
805 /* sin alpha <= |resid|/gap */
806 /* Note that both the residual and the gap are */
807 /* proportional to the matrix, so ||T|| doesn't play */
808 /* a role in the quotient */
810 /* Convergence test for Rayleigh-Quotient iteration */
811 /* (omitted when Bisection has been used) */
813 if (resid > tol * gap && dabs(rqcorr) > rqtol * dabs(
814 lambda) && ! usedbs) {
815 /* We need to check that the RQCORR update doesn't */
816 /* move the eigenvalue away from the desired one and */
817 /* towards a neighbor. -> protection with bisection */
818 if (indeig <= negcnt) {
819 /* The wanted eigenvalue lies to the left */
822 /* The wanted eigenvalue lies to the right */
825 /* We only use the RQCORR if it improves the */
826 /* the iterate reasonably. */
827 if (rqcorr * sgndef >= 0.f && lambda + rqcorr <=
828 right && lambda + rqcorr >= left) {
830 /* Store new midpoint of bisection interval in WORK */
832 /* The current LAMBDA is on the left of the true */
835 /* We prefer to assume that the error estimate */
836 /* is correct. We could make the interval not */
837 /* as a bracket but to be modified if the RQCORR */
838 /* chooses to. In this case, the RIGHT side should */
839 /* be modified as follows: */
840 /* RIGHT = MAX(RIGHT, LAMBDA + RQCORR) */
842 /* The current LAMBDA is on the right of the true */
845 /* See comment about assuming the error estimate is */
847 /* LEFT = MIN(LEFT, LAMBDA + RQCORR) */
849 work[windex] = (right + left) * .5f;
850 /* Take RQCORR since it has the correct sign and */
851 /* improves the iterate reasonably */
853 /* Update width of error interval */
854 werr[windex] = (right - left) * .5f;
858 if (right - left < rqtol * dabs(lambda)) {
859 /* The eigenvalue is computed to bisection accuracy */
860 /* compute eigenvector and stop */
863 } else if (iter < 10) {
865 } else if (iter == 10) {
874 if (usedrq && usedbs && bstres <= resid) {
879 /* improve error angle by second step */
881 slar1v_(&in, &c__1, &in, &lambda, &d__[ibegin]
882 , &l[ibegin], &work[indld + ibegin -
883 1], &work[indlld + ibegin - 1],
884 pivmin, &gaptol, &z__[ibegin + windex
885 * z_dim1], &L__1, &negcnt, &ztz, &
886 mingma, &iwork[iindr + windex], &
887 isuppz[(windex << 1) - 1], &nrminv, &
888 resid, &rqcorr, &work[indwrk]);
890 work[windex] = lambda;
893 /* Compute FP-vector support w.r.t. whole matrix */
895 isuppz[(windex << 1) - 1] += oldien;
896 isuppz[windex * 2] += oldien;
897 zfrom = isuppz[(windex << 1) - 1];
898 zto = isuppz[windex * 2];
901 /* Ensure vector is ok if support in the RQI has changed */
902 if (isupmn < zfrom) {
904 for (ii = isupmn; ii <= i__4; ++ii) {
905 z__[ii + windex * z_dim1] = 0.f;
911 for (ii = zto + 1; ii <= i__4; ++ii) {
912 z__[ii + windex * z_dim1] = 0.f;
916 i__4 = zto - zfrom + 1;
917 sscal_(&i__4, &nrminv, &z__[zfrom + windex * z_dim1],
921 w[windex] = lambda + sigma;
922 /* Recompute the gaps on the left and right */
923 /* But only allow them to become larger and not */
924 /* smaller (which can only happen through "bad" */
925 /* cancellation and doesn't reflect the theory */
926 /* where the initial gaps are underestimated due */
927 /* to WERR being too crude.) */
931 r__1 = wgap[windmn], r__2 = w[windex] - werr[
932 windex] - w[windmn] - werr[windmn];
933 wgap[windmn] = dmax(r__1,r__2);
937 r__1 = savgap, r__2 = w[windpl] - werr[windpl]
938 - w[windex] - werr[windex];
939 wgap[windex] = dmax(r__1,r__2);
944 /* here ends the code for the current child */
947 /* Proceed to any remaining child nodes */