Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / lapack / dlazq3.c
1 #include "clapack.h"
2
3 /* Subroutine */ int dlazq3_(integer *i0, integer *n0, doublereal *z__, 
4         integer *pp, doublereal *dmin__, doublereal *sigma, doublereal *desig, 
5          doublereal *qmax, integer *nfail, integer *iter, integer *ndiv, 
6         logical *ieee, integer *ttype, doublereal *dmin1, doublereal *dmin2, 
7         doublereal *dn, doublereal *dn1, doublereal *dn2, doublereal *tau)
8 {
9     /* System generated locals */
10     integer i__1;
11     doublereal d__1, d__2;
12
13     /* Builtin functions */
14     double sqrt(doublereal);
15
16     /* Local variables */
17     doublereal g, s, t;
18     integer j4, nn;
19     doublereal eps, tol;
20     integer n0in, ipn4;
21     doublereal tol2, temp;
22     extern /* Subroutine */ int dlasq5_(integer *, integer *, doublereal *, 
23             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
24              doublereal *, doublereal *, doublereal *, logical *), dlasq6_(
25             integer *, integer *, doublereal *, integer *, doublereal *, 
26             doublereal *, doublereal *, doublereal *, doublereal *, 
27             doublereal *), dlazq4_(integer *, integer *, doublereal *, 
28             integer *, integer *, doublereal *, doublereal *, doublereal *, 
29             doublereal *, doublereal *, doublereal *, doublereal *, integer *, 
30              doublereal *);
31     extern doublereal dlamch_(char *);
32     doublereal safmin;
33
34
35 /*  -- LAPACK auxiliary routine (version 3.1) -- */
36 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
37 /*     November 2006 */
38
39 /*     .. Scalar Arguments .. */
40 /*     .. */
41 /*     .. Array Arguments .. */
42 /*     .. */
43
44 /*  Purpose */
45 /*  ======= */
46
47 /*  DLAZQ3 checks for deflation, computes a shift (TAU) and calls dqds. */
48 /*  In case of failure it changes shifts, and tries again until output */
49 /*  is positive. */
50
51 /*  Arguments */
52 /*  ========= */
53
54 /*  I0     (input) INTEGER */
55 /*         First index. */
56
57 /*  N0     (input) INTEGER */
58 /*         Last index. */
59
60 /*  Z      (input) DOUBLE PRECISION array, dimension ( 4*N ) */
61 /*         Z holds the qd array. */
62
63 /*  PP     (input) INTEGER */
64 /*         PP=0 for ping, PP=1 for pong. */
65
66 /*  DMIN   (output) DOUBLE PRECISION */
67 /*         Minimum value of d. */
68
69 /*  SIGMA  (output) DOUBLE PRECISION */
70 /*         Sum of shifts used in current segment. */
71
72 /*  DESIG  (input/output) DOUBLE PRECISION */
73 /*         Lower order part of SIGMA */
74
75 /*  QMAX   (input) DOUBLE PRECISION */
76 /*         Maximum value of q. */
77
78 /*  NFAIL  (output) INTEGER */
79 /*         Number of times shift was too big. */
80
81 /*  ITER   (output) INTEGER */
82 /*         Number of iterations. */
83
84 /*  NDIV   (output) INTEGER */
85 /*         Number of divisions. */
86
87 /*  IEEE   (input) LOGICAL */
88 /*         Flag for IEEE or non IEEE arithmetic (passed to DLASQ5). */
89
90 /*  TTYPE  (input/output) INTEGER */
91 /*         Shift type.  TTYPE is passed as an argument in order to save */
92 /*         its value between calls to DLAZQ3 */
93
94 /*  DMIN1  (input/output) REAL */
95 /*  DMIN2  (input/output) REAL */
96 /*  DN     (input/output) REAL */
97 /*  DN1    (input/output) REAL */
98 /*  DN2    (input/output) REAL */
99 /*  TAU    (input/output) REAL */
100 /*         These are passed as arguments in order to save their values */
101 /*         between calls to DLAZQ3 */
102
103 /*  This is a thread safe version of DLASQ3, which passes TTYPE, DMIN1, */
104 /*  DMIN2, DN, DN1. DN2 and TAU through the argument list in place of */
105 /*  declaring them in a SAVE statment. */
106
107 /*  ===================================================================== */
108
109 /*     .. Parameters .. */
110 /*     .. */
111 /*     .. Local Scalars .. */
112 /*     .. */
113 /*     .. External Subroutines .. */
114 /*     .. */
115 /*     .. External Function .. */
116 /*     .. */
117 /*     .. Intrinsic Functions .. */
118 /*     .. */
119 /*     .. Executable Statements .. */
120
121     /* Parameter adjustments */
122     --z__;
123
124     /* Function Body */
125     n0in = *n0;
126     eps = dlamch_("Precision");
127     safmin = dlamch_("Safe minimum");
128     tol = eps * 100.;
129 /* Computing 2nd power */
130     d__1 = tol;
131     tol2 = d__1 * d__1;
132     g = 0.;
133
134 /*     Check for deflation. */
135
136 L10:
137
138     if (*n0 < *i0) {
139         return 0;
140     }
141     if (*n0 == *i0) {
142         goto L20;
143     }
144     nn = (*n0 << 2) + *pp;
145     if (*n0 == *i0 + 1) {
146         goto L40;
147     }
148
149 /*     Check whether E(N0-1) is negligible, 1 eigenvalue. */
150
151     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
152             4] > tol2 * z__[nn - 7]) {
153         goto L30;
154     }
155
156 L20:
157
158     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
159     --(*n0);
160     goto L10;
161
162 /*     Check  whether E(N0-2) is negligible, 2 eigenvalues. */
163
164 L30:
165
166     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
167             nn - 11]) {
168         goto L50;
169     }
170
171 L40:
172
173     if (z__[nn - 3] > z__[nn - 7]) {
174         s = z__[nn - 3];
175         z__[nn - 3] = z__[nn - 7];
176         z__[nn - 7] = s;
177     }
178     if (z__[nn - 5] > z__[nn - 3] * tol2) {
179         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
180         s = z__[nn - 3] * (z__[nn - 5] / t);
181         if (s <= t) {
182             s = z__[nn - 3] * (z__[nn - 5] / (t * (sqrt(s / t + 1.) + 1.)));
183         } else {
184             s = z__[nn - 3] * (z__[nn - 5] / (t + sqrt(t) * sqrt(t + s)));
185         }
186         t = z__[nn - 7] + (s + z__[nn - 5]);
187         z__[nn - 3] *= z__[nn - 7] / t;
188         z__[nn - 7] = t;
189     }
190     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
191     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
192     *n0 += -2;
193     goto L10;
194
195 L50:
196
197 /*     Reverse the qd-array, if warranted. */
198
199     if (*dmin__ <= 0. || *n0 < n0in) {
200         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
201             ipn4 = *i0 + *n0 << 2;
202             i__1 = *i0 + *n0 - 1 << 1;
203             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
204                 temp = z__[j4 - 3];
205                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
206                 z__[ipn4 - j4 - 3] = temp;
207                 temp = z__[j4 - 2];
208                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
209                 z__[ipn4 - j4 - 2] = temp;
210                 temp = z__[j4 - 1];
211                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
212                 z__[ipn4 - j4 - 5] = temp;
213                 temp = z__[j4];
214                 z__[j4] = z__[ipn4 - j4 - 4];
215                 z__[ipn4 - j4 - 4] = temp;
216 /* L60: */
217             }
218             if (*n0 - *i0 <= 4) {
219                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
220                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
221             }
222 /* Computing MIN */
223             d__1 = *dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
224             *dmin2 = min(d__1,d__2);
225 /* Computing MIN */
226             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
227                     , d__1 = min(d__1,d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
228             z__[(*n0 << 2) + *pp - 1] = min(d__1,d__2);
229 /* Computing MIN */
230             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
231                      min(d__1,d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
232             z__[(*n0 << 2) - *pp] = min(d__1,d__2);
233 /* Computing MAX */
234             d__1 = *qmax, d__2 = z__[(*i0 << 2) + *pp - 3], d__1 = max(d__1,
235                     d__2), d__2 = z__[(*i0 << 2) + *pp + 1];
236             *qmax = max(d__1,d__2);
237             *dmin__ = -0.;
238         }
239     }
240
241 /* Computing MIN */
242     d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*n0 << 2) + *pp - 9], d__1 =
243              min(d__1,d__2), d__2 = *dmin2 + z__[(*n0 << 2) - *pp];
244     if (*dmin__ < 0. || safmin * *qmax < min(d__1,d__2)) {
245
246 /*        Choose a shift. */
247
248         dlazq4_(i0, n0, &z__[1], pp, &n0in, dmin__, dmin1, dmin2, dn, dn1, 
249                 dn2, tau, ttype, &g);
250
251 /*        Call dqds until DMIN > 0. */
252
253 L80:
254
255         dlasq5_(i0, n0, &z__[1], pp, tau, dmin__, dmin1, dmin2, dn, dn1, dn2, 
256                 ieee);
257
258         *ndiv += *n0 - *i0 + 2;
259         ++(*iter);
260
261 /*        Check status. */
262
263         if (*dmin__ >= 0. && *dmin1 > 0.) {
264
265 /*           Success. */
266
267             goto L100;
268
269         } else if (*dmin__ < 0. && *dmin1 > 0. && z__[(*n0 - 1 << 2) - *pp] < 
270                 tol * (*sigma + *dn1) && abs(*dn) < tol * *sigma) {
271
272 /*           Convergence hidden by negative DN. */
273
274             z__[(*n0 - 1 << 2) - *pp + 2] = 0.;
275             *dmin__ = 0.;
276             goto L100;
277         } else if (*dmin__ < 0.) {
278
279 /*           TAU too big. Select new TAU and try again. */
280
281             ++(*nfail);
282             if (*ttype < -22) {
283
284 /*              Failed twice. Play it safe. */
285
286                 *tau = 0.;
287             } else if (*dmin1 > 0.) {
288
289 /*              Late failure. Gives excellent shift. */
290
291                 *tau = (*tau + *dmin__) * (1. - eps * 2.);
292                 *ttype += -11;
293             } else {
294
295 /*              Early failure. Divide by 4. */
296
297                 *tau *= .25;
298                 *ttype += -12;
299             }
300             goto L80;
301         } else if (*dmin__ != *dmin__) {
302
303 /*           NaN. */
304
305             *tau = 0.;
306             goto L80;
307         } else {
308
309 /*           Possible underflow. Play it safe. */
310
311             goto L90;
312         }
313     }
314
315 /*     Risk of underflow. */
316
317 L90:
318     dlasq6_(i0, n0, &z__[1], pp, dmin__, dmin1, dmin2, dn, dn1, dn2);
319     *ndiv += *n0 - *i0 + 2;
320     ++(*iter);
321     *tau = 0.;
322
323 L100:
324     if (*tau < *sigma) {
325         *desig += *tau;
326         t = *sigma + *desig;
327         *desig -= t - *sigma;
328     } else {
329         t = *sigma + *tau;
330         *desig = *sigma - (t - *tau) + *desig;
331     }
332     *sigma = t;
333
334     return 0;
335
336 /*     End of DLAZQ3 */
337
338 } /* dlazq3_ */