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