Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / lapack / dgebrd.c
1 #include "clapack.h"
2
3 /* Table of constant values */
4
5 static integer c__1 = 1;
6 static integer c_n1 = -1;
7 static integer c__3 = 3;
8 static integer c__2 = 2;
9 static doublereal c_b21 = -1.;
10 static doublereal c_b22 = 1.;
11
12 /* Subroutine */ int dgebrd_(integer *m, integer *n, doublereal *a, integer *
13         lda, doublereal *d__, doublereal *e, doublereal *tauq, doublereal *
14         taup, doublereal *work, integer *lwork, integer *info)
15 {
16     /* System generated locals */
17     integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
18
19     /* Local variables */
20     integer i__, j, nb, nx;
21     doublereal ws;
22     extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *, 
23             integer *, doublereal *, doublereal *, integer *, doublereal *, 
24             integer *, doublereal *, doublereal *, integer *);
25     integer nbmin, iinfo, minmn;
26     extern /* Subroutine */ int dgebd2_(integer *, integer *, doublereal *, 
27             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
28              doublereal *, integer *), dlabrd_(integer *, integer *, integer *
29 , doublereal *, integer *, doublereal *, doublereal *, doublereal 
30             *, doublereal *, doublereal *, integer *, doublereal *, integer *)
31             , xerbla_(char *, integer *);
32     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
33             integer *, integer *);
34     integer ldwrkx, ldwrky, lwkopt;
35     logical lquery;
36
37
38 /*  -- LAPACK routine (version 3.1) -- */
39 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
40 /*     November 2006 */
41
42 /*     .. Scalar Arguments .. */
43 /*     .. */
44 /*     .. Array Arguments .. */
45 /*     .. */
46
47 /*  Purpose */
48 /*  ======= */
49
50 /*  DGEBRD reduces a general real M-by-N matrix A to upper or lower */
51 /*  bidiagonal form B by an orthogonal transformation: Q**T * A * P = B. */
52
53 /*  If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal. */
54
55 /*  Arguments */
56 /*  ========= */
57
58 /*  M       (input) INTEGER */
59 /*          The number of rows in the matrix A.  M >= 0. */
60
61 /*  N       (input) INTEGER */
62 /*          The number of columns in the matrix A.  N >= 0. */
63
64 /*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
65 /*          On entry, the M-by-N general matrix to be reduced. */
66 /*          On exit, */
67 /*          if m >= n, the diagonal and the first superdiagonal are */
68 /*            overwritten with the upper bidiagonal matrix B; the */
69 /*            elements below the diagonal, with the array TAUQ, represent */
70 /*            the orthogonal matrix Q as a product of elementary */
71 /*            reflectors, and the elements above the first superdiagonal, */
72 /*            with the array TAUP, represent the orthogonal matrix P as */
73 /*            a product of elementary reflectors; */
74 /*          if m < n, the diagonal and the first subdiagonal are */
75 /*            overwritten with the lower bidiagonal matrix B; the */
76 /*            elements below the first subdiagonal, with the array TAUQ, */
77 /*            represent the orthogonal matrix Q as a product of */
78 /*            elementary reflectors, and the elements above the diagonal, */
79 /*            with the array TAUP, represent the orthogonal matrix P as */
80 /*            a product of elementary reflectors. */
81 /*          See Further Details. */
82
83 /*  LDA     (input) INTEGER */
84 /*          The leading dimension of the array A.  LDA >= max(1,M). */
85
86 /*  D       (output) DOUBLE PRECISION array, dimension (min(M,N)) */
87 /*          The diagonal elements of the bidiagonal matrix B: */
88 /*          D(i) = A(i,i). */
89
90 /*  E       (output) DOUBLE PRECISION array, dimension (min(M,N)-1) */
91 /*          The off-diagonal elements of the bidiagonal matrix B: */
92 /*          if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1; */
93 /*          if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1. */
94
95 /*  TAUQ    (output) DOUBLE PRECISION array dimension (min(M,N)) */
96 /*          The scalar factors of the elementary reflectors which */
97 /*          represent the orthogonal matrix Q. See Further Details. */
98
99 /*  TAUP    (output) DOUBLE PRECISION array, dimension (min(M,N)) */
100 /*          The scalar factors of the elementary reflectors which */
101 /*          represent the orthogonal matrix P. See Further Details. */
102
103 /*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
104 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
105
106 /*  LWORK   (input) INTEGER */
107 /*          The length of the array WORK.  LWORK >= max(1,M,N). */
108 /*          For optimum performance LWORK >= (M+N)*NB, where NB */
109 /*          is the optimal blocksize. */
110
111 /*          If LWORK = -1, then a workspace query is assumed; the routine */
112 /*          only calculates the optimal size of the WORK array, returns */
113 /*          this value as the first entry of the WORK array, and no error */
114 /*          message related to LWORK is issued by XERBLA. */
115
116 /*  INFO    (output) INTEGER */
117 /*          = 0:  successful exit */
118 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
119
120 /*  Further Details */
121 /*  =============== */
122
123 /*  The matrices Q and P are represented as products of elementary */
124 /*  reflectors: */
125
126 /*  If m >= n, */
127
128 /*     Q = H(1) H(2) . . . H(n)  and  P = G(1) G(2) . . . G(n-1) */
129
130 /*  Each H(i) and G(i) has the form: */
131
132 /*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u' */
133
134 /*  where tauq and taup are real scalars, and v and u are real vectors; */
135 /*  v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i); */
136 /*  u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n); */
137 /*  tauq is stored in TAUQ(i) and taup in TAUP(i). */
138
139 /*  If m < n, */
140
141 /*     Q = H(1) H(2) . . . H(m-1)  and  P = G(1) G(2) . . . G(m) */
142
143 /*  Each H(i) and G(i) has the form: */
144
145 /*     H(i) = I - tauq * v * v'  and G(i) = I - taup * u * u' */
146
147 /*  where tauq and taup are real scalars, and v and u are real vectors; */
148 /*  v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i); */
149 /*  u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n); */
150 /*  tauq is stored in TAUQ(i) and taup in TAUP(i). */
151
152 /*  The contents of A on exit are illustrated by the following examples: */
153
154 /*  m = 6 and n = 5 (m > n):          m = 5 and n = 6 (m < n): */
155
156 /*    (  d   e   u1  u1  u1 )           (  d   u1  u1  u1  u1  u1 ) */
157 /*    (  v1  d   e   u2  u2 )           (  e   d   u2  u2  u2  u2 ) */
158 /*    (  v1  v2  d   e   u3 )           (  v1  e   d   u3  u3  u3 ) */
159 /*    (  v1  v2  v3  d   e  )           (  v1  v2  e   d   u4  u4 ) */
160 /*    (  v1  v2  v3  v4  d  )           (  v1  v2  v3  e   d   u5 ) */
161 /*    (  v1  v2  v3  v4  v5 ) */
162
163 /*  where d and e denote diagonal and off-diagonal elements of B, vi */
164 /*  denotes an element of the vector defining H(i), and ui an element of */
165 /*  the vector defining G(i). */
166
167 /*  ===================================================================== */
168
169 /*     .. Parameters .. */
170 /*     .. */
171 /*     .. Local Scalars .. */
172 /*     .. */
173 /*     .. External Subroutines .. */
174 /*     .. */
175 /*     .. Intrinsic Functions .. */
176 /*     .. */
177 /*     .. External Functions .. */
178 /*     .. */
179 /*     .. Executable Statements .. */
180
181 /*     Test the input parameters */
182
183     /* Parameter adjustments */
184     a_dim1 = *lda;
185     a_offset = 1 + a_dim1;
186     a -= a_offset;
187     --d__;
188     --e;
189     --tauq;
190     --taup;
191     --work;
192
193     /* Function Body */
194     *info = 0;
195 /* Computing MAX */
196     i__1 = 1, i__2 = ilaenv_(&c__1, "DGEBRD", " ", m, n, &c_n1, &c_n1);
197     nb = max(i__1,i__2);
198     lwkopt = (*m + *n) * nb;
199     work[1] = (doublereal) lwkopt;
200     lquery = *lwork == -1;
201     if (*m < 0) {
202         *info = -1;
203     } else if (*n < 0) {
204         *info = -2;
205     } else if (*lda < max(1,*m)) {
206         *info = -4;
207     } else /* if(complicated condition) */ {
208 /* Computing MAX */
209         i__1 = max(1,*m);
210         if (*lwork < max(i__1,*n) && ! lquery) {
211             *info = -10;
212         }
213     }
214     if (*info < 0) {
215         i__1 = -(*info);
216         xerbla_("DGEBRD", &i__1);
217         return 0;
218     } else if (lquery) {
219         return 0;
220     }
221
222 /*     Quick return if possible */
223
224     minmn = min(*m,*n);
225     if (minmn == 0) {
226         work[1] = 1.;
227         return 0;
228     }
229
230     ws = (doublereal) max(*m,*n);
231     ldwrkx = *m;
232     ldwrky = *n;
233
234     if (nb > 1 && nb < minmn) {
235
236 /*        Set the crossover point NX. */
237
238 /* Computing MAX */
239         i__1 = nb, i__2 = ilaenv_(&c__3, "DGEBRD", " ", m, n, &c_n1, &c_n1);
240         nx = max(i__1,i__2);
241
242 /*        Determine when to switch from blocked to unblocked code. */
243
244         if (nx < minmn) {
245             ws = (doublereal) ((*m + *n) * nb);
246             if ((doublereal) (*lwork) < ws) {
247
248 /*              Not enough work space for the optimal NB, consider using */
249 /*              a smaller block size. */
250
251                 nbmin = ilaenv_(&c__2, "DGEBRD", " ", m, n, &c_n1, &c_n1);
252                 if (*lwork >= (*m + *n) * nbmin) {
253                     nb = *lwork / (*m + *n);
254                 } else {
255                     nb = 1;
256                     nx = minmn;
257                 }
258             }
259         }
260     } else {
261         nx = minmn;
262     }
263
264     i__1 = minmn - nx;
265     i__2 = nb;
266     for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
267
268 /*        Reduce rows and columns i:i+nb-1 to bidiagonal form and return */
269 /*        the matrices X and Y which are needed to update the unreduced */
270 /*        part of the matrix */
271
272         i__3 = *m - i__ + 1;
273         i__4 = *n - i__ + 1;
274         dlabrd_(&i__3, &i__4, &nb, &a[i__ + i__ * a_dim1], lda, &d__[i__], &e[
275                 i__], &tauq[i__], &taup[i__], &work[1], &ldwrkx, &work[ldwrkx 
276                 * nb + 1], &ldwrky);
277
278 /*        Update the trailing submatrix A(i+nb:m,i+nb:n), using an update */
279 /*        of the form  A := A - V*Y' - X*U' */
280
281         i__3 = *m - i__ - nb + 1;
282         i__4 = *n - i__ - nb + 1;
283         dgemm_("No transpose", "Transpose", &i__3, &i__4, &nb, &c_b21, &a[i__ 
284                 + nb + i__ * a_dim1], lda, &work[ldwrkx * nb + nb + 1], &
285                 ldwrky, &c_b22, &a[i__ + nb + (i__ + nb) * a_dim1], lda);
286         i__3 = *m - i__ - nb + 1;
287         i__4 = *n - i__ - nb + 1;
288         dgemm_("No transpose", "No transpose", &i__3, &i__4, &nb, &c_b21, &
289                 work[nb + 1], &ldwrkx, &a[i__ + (i__ + nb) * a_dim1], lda, &
290                 c_b22, &a[i__ + nb + (i__ + nb) * a_dim1], lda);
291
292 /*        Copy diagonal and off-diagonal elements of B back into A */
293
294         if (*m >= *n) {
295             i__3 = i__ + nb - 1;
296             for (j = i__; j <= i__3; ++j) {
297                 a[j + j * a_dim1] = d__[j];
298                 a[j + (j + 1) * a_dim1] = e[j];
299 /* L10: */
300             }
301         } else {
302             i__3 = i__ + nb - 1;
303             for (j = i__; j <= i__3; ++j) {
304                 a[j + j * a_dim1] = d__[j];
305                 a[j + 1 + j * a_dim1] = e[j];
306 /* L20: */
307             }
308         }
309 /* L30: */
310     }
311
312 /*     Use unblocked code to reduce the remainder of the matrix */
313
314     i__2 = *m - i__ + 1;
315     i__1 = *n - i__ + 1;
316     dgebd2_(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &d__[i__], &e[i__], &
317             tauq[i__], &taup[i__], &work[1], &iinfo);
318     work[1] = ws;
319     return 0;
320
321 /*     End of DGEBRD */
322
323 } /* dgebrd_ */