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