Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / lapack / dlaed9.c
1 #include "clapack.h"
2
3 /* Table of constant values */
4
5 static integer c__1 = 1;
6
7 /* Subroutine */ int dlaed9_(integer *k, integer *kstart, integer *kstop, 
8         integer *n, doublereal *d__, doublereal *q, integer *ldq, doublereal *
9         rho, doublereal *dlamda, doublereal *w, doublereal *s, integer *lds, 
10         integer *info)
11 {
12     /* System generated locals */
13     integer q_dim1, q_offset, s_dim1, s_offset, i__1, i__2;
14     doublereal d__1;
15
16     /* Builtin functions */
17     double sqrt(doublereal), d_sign(doublereal *, doublereal *);
18
19     /* Local variables */
20     integer i__, j;
21     doublereal temp;
22     extern doublereal dnrm2_(integer *, doublereal *, integer *);
23     extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *, 
24             doublereal *, integer *), dlaed4_(integer *, integer *, 
25             doublereal *, doublereal *, doublereal *, doublereal *, 
26             doublereal *, integer *);
27     extern doublereal dlamc3_(doublereal *, doublereal *);
28     extern /* Subroutine */ int xerbla_(char *, integer *);
29
30
31 /*  -- LAPACK 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 /*  DLAED9 finds the roots of the secular equation, as defined by the */
44 /*  values in D, Z, and RHO, between KSTART and KSTOP.  It makes the */
45 /*  appropriate calls to DLAED4 and then stores the new matrix of */
46 /*  eigenvectors for use in calculating the next level of Z vectors. */
47
48 /*  Arguments */
49 /*  ========= */
50
51 /*  K       (input) INTEGER */
52 /*          The number of terms in the rational function to be solved by */
53 /*          DLAED4.  K >= 0. */
54
55 /*  KSTART  (input) INTEGER */
56 /*  KSTOP   (input) INTEGER */
57 /*          The updated eigenvalues Lambda(I), KSTART <= I <= KSTOP */
58 /*          are to be computed.  1 <= KSTART <= KSTOP <= K. */
59
60 /*  N       (input) INTEGER */
61 /*          The number of rows and columns in the Q matrix. */
62 /*          N >= K (delation may result in N > K). */
63
64 /*  D       (output) DOUBLE PRECISION array, dimension (N) */
65 /*          D(I) contains the updated eigenvalues */
66 /*          for KSTART <= I <= KSTOP. */
67
68 /*  Q       (workspace) DOUBLE PRECISION array, dimension (LDQ,N) */
69
70 /*  LDQ     (input) INTEGER */
71 /*          The leading dimension of the array Q.  LDQ >= max( 1, N ). */
72
73 /*  RHO     (input) DOUBLE PRECISION */
74 /*          The value of the parameter in the rank one update equation. */
75 /*          RHO >= 0 required. */
76
77 /*  DLAMDA  (input) DOUBLE PRECISION array, dimension (K) */
78 /*          The first K elements of this array contain the old roots */
79 /*          of the deflated updating problem.  These are the poles */
80 /*          of the secular equation. */
81
82 /*  W       (input) DOUBLE PRECISION array, dimension (K) */
83 /*          The first K elements of this array contain the components */
84 /*          of the deflation-adjusted updating vector. */
85
86 /*  S       (output) DOUBLE PRECISION array, dimension (LDS, K) */
87 /*          Will contain the eigenvectors of the repaired matrix which */
88 /*          will be stored for subsequent Z vector calculation and */
89 /*          multiplied by the previously accumulated eigenvectors */
90 /*          to update the system. */
91
92 /*  LDS     (input) INTEGER */
93 /*          The leading dimension of S.  LDS >= max( 1, K ). */
94
95 /*  INFO    (output) INTEGER */
96 /*          = 0:  successful exit. */
97 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
98 /*          > 0:  if INFO = 1, an eigenvalue did not converge */
99
100 /*  Further Details */
101 /*  =============== */
102
103 /*  Based on contributions by */
104 /*     Jeff Rutter, Computer Science Division, University of California */
105 /*     at Berkeley, USA */
106
107 /*  ===================================================================== */
108
109 /*     .. Local Scalars .. */
110 /*     .. */
111 /*     .. External Functions .. */
112 /*     .. */
113 /*     .. External Subroutines .. */
114 /*     .. */
115 /*     .. Intrinsic Functions .. */
116 /*     .. */
117 /*     .. Executable Statements .. */
118
119 /*     Test the input parameters. */
120
121     /* Parameter adjustments */
122     --d__;
123     q_dim1 = *ldq;
124     q_offset = 1 + q_dim1;
125     q -= q_offset;
126     --dlamda;
127     --w;
128     s_dim1 = *lds;
129     s_offset = 1 + s_dim1;
130     s -= s_offset;
131
132     /* Function Body */
133     *info = 0;
134
135     if (*k < 0) {
136         *info = -1;
137     } else if (*kstart < 1 || *kstart > max(1,*k)) {
138         *info = -2;
139     } else if (max(1,*kstop) < *kstart || *kstop > max(1,*k)) {
140         *info = -3;
141     } else if (*n < *k) {
142         *info = -4;
143     } else if (*ldq < max(1,*k)) {
144         *info = -7;
145     } else if (*lds < max(1,*k)) {
146         *info = -12;
147     }
148     if (*info != 0) {
149         i__1 = -(*info);
150         xerbla_("DLAED9", &i__1);
151         return 0;
152     }
153
154 /*     Quick return if possible */
155
156     if (*k == 0) {
157         return 0;
158     }
159
160 /*     Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can */
161 /*     be computed with high relative accuracy (barring over/underflow). */
162 /*     This is a problem on machines without a guard digit in */
163 /*     add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2). */
164 /*     The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I), */
165 /*     which on any of these machines zeros out the bottommost */
166 /*     bit of DLAMDA(I) if it is 1; this makes the subsequent */
167 /*     subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation */
168 /*     occurs. On binary machines with a guard digit (almost all */
169 /*     machines) it does not change DLAMDA(I) at all. On hexadecimal */
170 /*     and decimal machines with a guard digit, it slightly */
171 /*     changes the bottommost bits of DLAMDA(I). It does not account */
172 /*     for hexadecimal or decimal machines without guard digits */
173 /*     (we know of none). We use a subroutine call to compute */
174 /*     2*DLAMBDA(I) to prevent optimizing compilers from eliminating */
175 /*     this code. */
176
177     i__1 = *n;
178     for (i__ = 1; i__ <= i__1; ++i__) {
179         dlamda[i__] = dlamc3_(&dlamda[i__], &dlamda[i__]) - dlamda[i__];
180 /* L10: */
181     }
182
183     i__1 = *kstop;
184     for (j = *kstart; j <= i__1; ++j) {
185         dlaed4_(k, &j, &dlamda[1], &w[1], &q[j * q_dim1 + 1], rho, &d__[j], 
186                 info);
187
188 /*        If the zero finder fails, the computation is terminated. */
189
190         if (*info != 0) {
191             goto L120;
192         }
193 /* L20: */
194     }
195
196     if (*k == 1 || *k == 2) {
197         i__1 = *k;
198         for (i__ = 1; i__ <= i__1; ++i__) {
199             i__2 = *k;
200             for (j = 1; j <= i__2; ++j) {
201                 s[j + i__ * s_dim1] = q[j + i__ * q_dim1];
202 /* L30: */
203             }
204 /* L40: */
205         }
206         goto L120;
207     }
208
209 /*     Compute updated W. */
210
211     dcopy_(k, &w[1], &c__1, &s[s_offset], &c__1);
212
213 /*     Initialize W(I) = Q(I,I) */
214
215     i__1 = *ldq + 1;
216     dcopy_(k, &q[q_offset], &i__1, &w[1], &c__1);
217     i__1 = *k;
218     for (j = 1; j <= i__1; ++j) {
219         i__2 = j - 1;
220         for (i__ = 1; i__ <= i__2; ++i__) {
221             w[i__] *= q[i__ + j * q_dim1] / (dlamda[i__] - dlamda[j]);
222 /* L50: */
223         }
224         i__2 = *k;
225         for (i__ = j + 1; i__ <= i__2; ++i__) {
226             w[i__] *= q[i__ + j * q_dim1] / (dlamda[i__] - dlamda[j]);
227 /* L60: */
228         }
229 /* L70: */
230     }
231     i__1 = *k;
232     for (i__ = 1; i__ <= i__1; ++i__) {
233         d__1 = sqrt(-w[i__]);
234         w[i__] = d_sign(&d__1, &s[i__ + s_dim1]);
235 /* L80: */
236     }
237
238 /*     Compute eigenvectors of the modified rank-1 modification. */
239
240     i__1 = *k;
241     for (j = 1; j <= i__1; ++j) {
242         i__2 = *k;
243         for (i__ = 1; i__ <= i__2; ++i__) {
244             q[i__ + j * q_dim1] = w[i__] / q[i__ + j * q_dim1];
245 /* L90: */
246         }
247         temp = dnrm2_(k, &q[j * q_dim1 + 1], &c__1);
248         i__2 = *k;
249         for (i__ = 1; i__ <= i__2; ++i__) {
250             s[i__ + j * s_dim1] = q[i__ + j * q_dim1] / temp;
251 /* L100: */
252         }
253 /* L110: */
254     }
255
256 L120:
257     return 0;
258
259 /*     End of DLAED9 */
260
261 } /* dlaed9_ */