69e836ec39cb3949a61d2b092b4ccd36ccf0a0dc
[profile/ivi/opencv.git] / 3rdparty / lapack / slarrj.c
1 /* slarrj.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
7                 cc *.o -lf2c -lm
8         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
9
10                 http://www.netlib.org/f2c/libf2c.zip
11 */
12
13 #include "clapack.h"
14
15
16 /* Subroutine */ int slarrj_(integer *n, real *d__, real *e2, integer *ifirst, 
17          integer *ilast, real *rtol, integer *offset, real *w, real *werr, 
18         real *work, integer *iwork, real *pivmin, real *spdiam, integer *info)
19 {
20     /* System generated locals */
21     integer i__1, i__2;
22     real r__1, r__2;
23
24     /* Builtin functions */
25     double log(doublereal);
26
27     /* Local variables */
28     integer i__, j, k, p;
29     real s;
30     integer i1, i2, ii;
31     real fac, mid;
32     integer cnt;
33     real tmp, left;
34     integer iter, nint, prev, next, savi1;
35     real right, width, dplus;
36     integer olnint, maxitr;
37
38
39 /*  -- LAPACK auxiliary routine (version 3.2) -- */
40 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
41 /*     November 2006 */
42
43 /*     .. Scalar Arguments .. */
44 /*     .. */
45 /*     .. Array Arguments .. */
46 /*     .. */
47
48 /*  Purpose */
49 /*  ======= */
50
51 /*  Given the initial eigenvalue approximations of T, SLARRJ */
52 /*  does  bisection to refine the eigenvalues of T, */
53 /*  W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial */
54 /*  guesses for these eigenvalues are input in W, the corresponding estimate */
55 /*  of the error in these guesses in WERR. During bisection, intervals */
56 /*  [left, right] are maintained by storing their mid-points and */
57 /*  semi-widths in the arrays W and WERR respectively. */
58
59 /*  Arguments */
60 /*  ========= */
61
62 /*  N       (input) INTEGER */
63 /*          The order of the matrix. */
64
65 /*  D       (input) REAL             array, dimension (N) */
66 /*          The N diagonal elements of T. */
67
68 /*  E2      (input) REAL             array, dimension (N-1) */
69 /*          The Squares of the (N-1) subdiagonal elements of T. */
70
71 /*  IFIRST  (input) INTEGER */
72 /*          The index of the first eigenvalue to be computed. */
73
74 /*  ILAST   (input) INTEGER */
75 /*          The index of the last eigenvalue to be computed. */
76
77 /*  RTOL   (input) REAL */
78 /*          Tolerance for the convergence of the bisection intervals. */
79 /*          An interval [LEFT,RIGHT] has converged if */
80 /*          RIGHT-LEFT.LT.RTOL*MAX(|LEFT|,|RIGHT|). */
81
82 /*  OFFSET  (input) INTEGER */
83 /*          Offset for the arrays W and WERR, i.e., the IFIRST-OFFSET */
84 /*          through ILAST-OFFSET elements of these arrays are to be used. */
85
86 /*  W       (input/output) REAL             array, dimension (N) */
87 /*          On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are */
88 /*          estimates of the eigenvalues of L D L^T indexed IFIRST through */
89 /*          ILAST. */
90 /*          On output, these estimates are refined. */
91
92 /*  WERR    (input/output) REAL             array, dimension (N) */
93 /*          On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are */
94 /*          the errors in the estimates of the corresponding elements in W. */
95 /*          On output, these errors are refined. */
96
97 /*  WORK    (workspace) REAL             array, dimension (2*N) */
98 /*          Workspace. */
99
100 /*  IWORK   (workspace) INTEGER array, dimension (2*N) */
101 /*          Workspace. */
102
103 /*  PIVMIN  (input) DOUBLE PRECISION */
104 /*          The minimum pivot in the Sturm sequence for T. */
105
106 /*  SPDIAM  (input) DOUBLE PRECISION */
107 /*          The spectral diameter of T. */
108
109 /*  INFO    (output) INTEGER */
110 /*          Error flag. */
111
112 /*  Further Details */
113 /*  =============== */
114
115 /*  Based on contributions by */
116 /*     Beresford Parlett, University of California, Berkeley, USA */
117 /*     Jim Demmel, University of California, Berkeley, USA */
118 /*     Inderjit Dhillon, University of Texas, Austin, USA */
119 /*     Osni Marques, LBNL/NERSC, USA */
120 /*     Christof Voemel, University of California, Berkeley, USA */
121
122 /*  ===================================================================== */
123
124 /*     .. Parameters .. */
125 /*     .. */
126 /*     .. Local Scalars .. */
127
128 /*     .. */
129 /*     .. Intrinsic Functions .. */
130 /*     .. */
131 /*     .. Executable Statements .. */
132
133     /* Parameter adjustments */
134     --iwork;
135     --work;
136     --werr;
137     --w;
138     --e2;
139     --d__;
140
141     /* Function Body */
142     *info = 0;
143
144     maxitr = (integer) ((log(*spdiam + *pivmin) - log(*pivmin)) / log(2.f)) + 
145             2;
146
147 /*     Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ]. */
148 /*     The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while */
149 /*     Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 ) */
150 /*     for an unconverged interval is set to the index of the next unconverged */
151 /*     interval, and is -1 or 0 for a converged interval. Thus a linked */
152 /*     list of unconverged intervals is set up. */
153
154     i1 = *ifirst;
155     i2 = *ilast;
156 /*     The number of unconverged intervals */
157     nint = 0;
158 /*     The last unconverged interval found */
159     prev = 0;
160     i__1 = i2;
161     for (i__ = i1; i__ <= i__1; ++i__) {
162         k = i__ << 1;
163         ii = i__ - *offset;
164         left = w[ii] - werr[ii];
165         mid = w[ii];
166         right = w[ii] + werr[ii];
167         width = right - mid;
168 /* Computing MAX */
169         r__1 = dabs(left), r__2 = dabs(right);
170         tmp = dmax(r__1,r__2);
171 /*        The following test prevents the test of converged intervals */
172         if (width < *rtol * tmp) {
173 /*           This interval has already converged and does not need refinement. */
174 /*           (Note that the gaps might change through refining the */
175 /*            eigenvalues, however, they can only get bigger.) */
176 /*           Remove it from the list. */
177             iwork[k - 1] = -1;
178 /*           Make sure that I1 always points to the first unconverged interval */
179             if (i__ == i1 && i__ < i2) {
180                 i1 = i__ + 1;
181             }
182             if (prev >= i1 && i__ <= i2) {
183                 iwork[(prev << 1) - 1] = i__ + 1;
184             }
185         } else {
186 /*           unconverged interval found */
187             prev = i__;
188 /*           Make sure that [LEFT,RIGHT] contains the desired eigenvalue */
189
190 /*           Do while( CNT(LEFT).GT.I-1 ) */
191
192             fac = 1.f;
193 L20:
194             cnt = 0;
195             s = left;
196             dplus = d__[1] - s;
197             if (dplus < 0.f) {
198                 ++cnt;
199             }
200             i__2 = *n;
201             for (j = 2; j <= i__2; ++j) {
202                 dplus = d__[j] - s - e2[j - 1] / dplus;
203                 if (dplus < 0.f) {
204                     ++cnt;
205                 }
206 /* L30: */
207             }
208             if (cnt > i__ - 1) {
209                 left -= werr[ii] * fac;
210                 fac *= 2.f;
211                 goto L20;
212             }
213
214 /*           Do while( CNT(RIGHT).LT.I ) */
215
216             fac = 1.f;
217 L50:
218             cnt = 0;
219             s = right;
220             dplus = d__[1] - s;
221             if (dplus < 0.f) {
222                 ++cnt;
223             }
224             i__2 = *n;
225             for (j = 2; j <= i__2; ++j) {
226                 dplus = d__[j] - s - e2[j - 1] / dplus;
227                 if (dplus < 0.f) {
228                     ++cnt;
229                 }
230 /* L60: */
231             }
232             if (cnt < i__) {
233                 right += werr[ii] * fac;
234                 fac *= 2.f;
235                 goto L50;
236             }
237             ++nint;
238             iwork[k - 1] = i__ + 1;
239             iwork[k] = cnt;
240         }
241         work[k - 1] = left;
242         work[k] = right;
243 /* L75: */
244     }
245     savi1 = i1;
246
247 /*     Do while( NINT.GT.0 ), i.e. there are still unconverged intervals */
248 /*     and while (ITER.LT.MAXITR) */
249
250     iter = 0;
251 L80:
252     prev = i1 - 1;
253     i__ = i1;
254     olnint = nint;
255     i__1 = olnint;
256     for (p = 1; p <= i__1; ++p) {
257         k = i__ << 1;
258         ii = i__ - *offset;
259         next = iwork[k - 1];
260         left = work[k - 1];
261         right = work[k];
262         mid = (left + right) * .5f;
263 /*        semiwidth of interval */
264         width = right - mid;
265 /* Computing MAX */
266         r__1 = dabs(left), r__2 = dabs(right);
267         tmp = dmax(r__1,r__2);
268         if (width < *rtol * tmp || iter == maxitr) {
269 /*           reduce number of unconverged intervals */
270             --nint;
271 /*           Mark interval as converged. */
272             iwork[k - 1] = 0;
273             if (i1 == i__) {
274                 i1 = next;
275             } else {
276 /*              Prev holds the last unconverged interval previously examined */
277                 if (prev >= i1) {
278                     iwork[(prev << 1) - 1] = next;
279                 }
280             }
281             i__ = next;
282             goto L100;
283         }
284         prev = i__;
285
286 /*        Perform one bisection step */
287
288         cnt = 0;
289         s = mid;
290         dplus = d__[1] - s;
291         if (dplus < 0.f) {
292             ++cnt;
293         }
294         i__2 = *n;
295         for (j = 2; j <= i__2; ++j) {
296             dplus = d__[j] - s - e2[j - 1] / dplus;
297             if (dplus < 0.f) {
298                 ++cnt;
299             }
300 /* L90: */
301         }
302         if (cnt <= i__ - 1) {
303             work[k - 1] = mid;
304         } else {
305             work[k] = mid;
306         }
307         i__ = next;
308 L100:
309         ;
310     }
311     ++iter;
312 /*     do another loop if there are still unconverged intervals */
313 /*     However, in the last iteration, all intervals are accepted */
314 /*     since this is the best we can do. */
315     if (nint > 0 && iter <= maxitr) {
316         goto L80;
317     }
318
319
320 /*     At this point, all the intervals have converged */
321     i__1 = *ilast;
322     for (i__ = savi1; i__ <= i__1; ++i__) {
323         k = i__ << 1;
324         ii = i__ - *offset;
325 /*        All intervals marked by '0' have been refined. */
326         if (iwork[k - 1] == 0) {
327             w[ii] = (work[k - 1] + work[k]) * .5f;
328             werr[ii] = work[k] - w[ii];
329         }
330 /* L110: */
331     }
332
333     return 0;
334
335 /*     End of SLARRJ */
336
337 } /* slarrj_ */