Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / lapack / dsyr2k.c
1 #include "clapack.h"
2
3 /* Subroutine */ int dsyr2k_(char *uplo, char *trans, integer *n, integer *k, 
4         doublereal *alpha, doublereal *a, integer *lda, doublereal *b, 
5         integer *ldb, doublereal *beta, doublereal *c__, integer *ldc)
6 {
7     /* System generated locals */
8     integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, i__1, i__2, 
9             i__3;
10
11     /* Local variables */
12     integer i__, j, l, info;
13     doublereal temp1, temp2;
14     extern logical lsame_(char *, char *);
15     integer nrowa;
16     logical upper;
17     extern /* Subroutine */ int xerbla_(char *, integer *);
18
19 /*     .. Scalar Arguments .. */
20 /*     .. */
21 /*     .. Array Arguments .. */
22 /*     .. */
23
24 /*  Purpose */
25 /*  ======= */
26
27 /*  DSYR2K  performs one of the symmetric rank 2k operations */
28
29 /*     C := alpha*A*B' + alpha*B*A' + beta*C, */
30
31 /*  or */
32
33 /*     C := alpha*A'*B + alpha*B'*A + beta*C, */
34
35 /*  where  alpha and beta  are scalars, C is an  n by n  symmetric matrix */
36 /*  and  A and B  are  n by k  matrices  in the  first  case  and  k by n */
37 /*  matrices in the second case. */
38
39 /*  Arguments */
40 /*  ========== */
41
42 /*  UPLO   - CHARACTER*1. */
43 /*           On  entry,   UPLO  specifies  whether  the  upper  or  lower */
44 /*           triangular  part  of the  array  C  is to be  referenced  as */
45 /*           follows: */
46
47 /*              UPLO = 'U' or 'u'   Only the  upper triangular part of  C */
48 /*                                  is to be referenced. */
49
50 /*              UPLO = 'L' or 'l'   Only the  lower triangular part of  C */
51 /*                                  is to be referenced. */
52
53 /*           Unchanged on exit. */
54
55 /*  TRANS  - CHARACTER*1. */
56 /*           On entry,  TRANS  specifies the operation to be performed as */
57 /*           follows: */
58
59 /*              TRANS = 'N' or 'n'   C := alpha*A*B' + alpha*B*A' + */
60 /*                                        beta*C. */
61
62 /*              TRANS = 'T' or 't'   C := alpha*A'*B + alpha*B'*A + */
63 /*                                        beta*C. */
64
65 /*              TRANS = 'C' or 'c'   C := alpha*A'*B + alpha*B'*A + */
66 /*                                        beta*C. */
67
68 /*           Unchanged on exit. */
69
70 /*  N      - INTEGER. */
71 /*           On entry,  N specifies the order of the matrix C.  N must be */
72 /*           at least zero. */
73 /*           Unchanged on exit. */
74
75 /*  K      - INTEGER. */
76 /*           On entry with  TRANS = 'N' or 'n',  K  specifies  the number */
77 /*           of  columns  of the  matrices  A and B,  and on  entry  with */
78 /*           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number */
79 /*           of rows of the matrices  A and B.  K must be at least  zero. */
80 /*           Unchanged on exit. */
81
82 /*  ALPHA  - DOUBLE PRECISION. */
83 /*           On entry, ALPHA specifies the scalar alpha. */
84 /*           Unchanged on exit. */
85
86 /*  A      - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is */
87 /*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise. */
88 /*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k */
89 /*           part of the array  A  must contain the matrix  A,  otherwise */
90 /*           the leading  k by n  part of the array  A  must contain  the */
91 /*           matrix A. */
92 /*           Unchanged on exit. */
93
94 /*  LDA    - INTEGER. */
95 /*           On entry, LDA specifies the first dimension of A as declared */
96 /*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n' */
97 /*           then  LDA must be at least  max( 1, n ), otherwise  LDA must */
98 /*           be at least  max( 1, k ). */
99 /*           Unchanged on exit. */
100
101 /*  B      - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is */
102 /*           k  when  TRANS = 'N' or 'n',  and is  n  otherwise. */
103 /*           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k */
104 /*           part of the array  B  must contain the matrix  B,  otherwise */
105 /*           the leading  k by n  part of the array  B  must contain  the */
106 /*           matrix B. */
107 /*           Unchanged on exit. */
108
109 /*  LDB    - INTEGER. */
110 /*           On entry, LDB specifies the first dimension of B as declared */
111 /*           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n' */
112 /*           then  LDB must be at least  max( 1, n ), otherwise  LDB must */
113 /*           be at least  max( 1, k ). */
114 /*           Unchanged on exit. */
115
116 /*  BETA   - DOUBLE PRECISION. */
117 /*           On entry, BETA specifies the scalar beta. */
118 /*           Unchanged on exit. */
119
120 /*  C      - DOUBLE PRECISION array of DIMENSION ( LDC, n ). */
121 /*           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n */
122 /*           upper triangular part of the array C must contain the upper */
123 /*           triangular part  of the  symmetric matrix  and the strictly */
124 /*           lower triangular part of C is not referenced.  On exit, the */
125 /*           upper triangular part of the array  C is overwritten by the */
126 /*           upper triangular part of the updated matrix. */
127 /*           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n */
128 /*           lower triangular part of the array C must contain the lower */
129 /*           triangular part  of the  symmetric matrix  and the strictly */
130 /*           upper triangular part of C is not referenced.  On exit, the */
131 /*           lower triangular part of the array  C is overwritten by the */
132 /*           lower triangular part of the updated matrix. */
133
134 /*  LDC    - INTEGER. */
135 /*           On entry, LDC specifies the first dimension of C as declared */
136 /*           in  the  calling  (sub)  program.   LDC  must  be  at  least */
137 /*           max( 1, n ). */
138 /*           Unchanged on exit. */
139
140
141 /*  Level 3 Blas routine. */
142
143
144 /*  -- Written on 8-February-1989. */
145 /*     Jack Dongarra, Argonne National Laboratory. */
146 /*     Iain Duff, AERE Harwell. */
147 /*     Jeremy Du Croz, Numerical Algorithms Group Ltd. */
148 /*     Sven Hammarling, Numerical Algorithms Group Ltd. */
149
150
151 /*     .. External Functions .. */
152 /*     .. */
153 /*     .. External Subroutines .. */
154 /*     .. */
155 /*     .. Intrinsic Functions .. */
156 /*     .. */
157 /*     .. Local Scalars .. */
158 /*     .. */
159 /*     .. Parameters .. */
160 /*     .. */
161
162 /*     Test the input parameters. */
163
164     /* Parameter adjustments */
165     a_dim1 = *lda;
166     a_offset = 1 + a_dim1;
167     a -= a_offset;
168     b_dim1 = *ldb;
169     b_offset = 1 + b_dim1;
170     b -= b_offset;
171     c_dim1 = *ldc;
172     c_offset = 1 + c_dim1;
173     c__ -= c_offset;
174
175     /* Function Body */
176     if (lsame_(trans, "N")) {
177         nrowa = *n;
178     } else {
179         nrowa = *k;
180     }
181     upper = lsame_(uplo, "U");
182
183     info = 0;
184     if (! upper && ! lsame_(uplo, "L")) {
185         info = 1;
186     } else if (! lsame_(trans, "N") && ! lsame_(trans, 
187             "T") && ! lsame_(trans, "C")) {
188         info = 2;
189     } else if (*n < 0) {
190         info = 3;
191     } else if (*k < 0) {
192         info = 4;
193     } else if (*lda < max(1,nrowa)) {
194         info = 7;
195     } else if (*ldb < max(1,nrowa)) {
196         info = 9;
197     } else if (*ldc < max(1,*n)) {
198         info = 12;
199     }
200     if (info != 0) {
201         xerbla_("DSYR2K", &info);
202         return 0;
203     }
204
205 /*     Quick return if possible. */
206
207     if (*n == 0 || (*alpha == 0. || *k == 0) && *beta == 1.) {
208         return 0;
209     }
210
211 /*     And when  alpha.eq.zero. */
212
213     if (*alpha == 0.) {
214         if (upper) {
215             if (*beta == 0.) {
216                 i__1 = *n;
217                 for (j = 1; j <= i__1; ++j) {
218                     i__2 = j;
219                     for (i__ = 1; i__ <= i__2; ++i__) {
220                         c__[i__ + j * c_dim1] = 0.;
221 /* L10: */
222                     }
223 /* L20: */
224                 }
225             } else {
226                 i__1 = *n;
227                 for (j = 1; j <= i__1; ++j) {
228                     i__2 = j;
229                     for (i__ = 1; i__ <= i__2; ++i__) {
230                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1];
231 /* L30: */
232                     }
233 /* L40: */
234                 }
235             }
236         } else {
237             if (*beta == 0.) {
238                 i__1 = *n;
239                 for (j = 1; j <= i__1; ++j) {
240                     i__2 = *n;
241                     for (i__ = j; i__ <= i__2; ++i__) {
242                         c__[i__ + j * c_dim1] = 0.;
243 /* L50: */
244                     }
245 /* L60: */
246                 }
247             } else {
248                 i__1 = *n;
249                 for (j = 1; j <= i__1; ++j) {
250                     i__2 = *n;
251                     for (i__ = j; i__ <= i__2; ++i__) {
252                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1];
253 /* L70: */
254                     }
255 /* L80: */
256                 }
257             }
258         }
259         return 0;
260     }
261
262 /*     Start the operations. */
263
264     if (lsame_(trans, "N")) {
265
266 /*        Form  C := alpha*A*B' + alpha*B*A' + C. */
267
268         if (upper) {
269             i__1 = *n;
270             for (j = 1; j <= i__1; ++j) {
271                 if (*beta == 0.) {
272                     i__2 = j;
273                     for (i__ = 1; i__ <= i__2; ++i__) {
274                         c__[i__ + j * c_dim1] = 0.;
275 /* L90: */
276                     }
277                 } else if (*beta != 1.) {
278                     i__2 = j;
279                     for (i__ = 1; i__ <= i__2; ++i__) {
280                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1];
281 /* L100: */
282                     }
283                 }
284                 i__2 = *k;
285                 for (l = 1; l <= i__2; ++l) {
286                     if (a[j + l * a_dim1] != 0. || b[j + l * b_dim1] != 0.) {
287                         temp1 = *alpha * b[j + l * b_dim1];
288                         temp2 = *alpha * a[j + l * a_dim1];
289                         i__3 = j;
290                         for (i__ = 1; i__ <= i__3; ++i__) {
291                             c__[i__ + j * c_dim1] = c__[i__ + j * c_dim1] + a[
292                                     i__ + l * a_dim1] * temp1 + b[i__ + l * 
293                                     b_dim1] * temp2;
294 /* L110: */
295                         }
296                     }
297 /* L120: */
298                 }
299 /* L130: */
300             }
301         } else {
302             i__1 = *n;
303             for (j = 1; j <= i__1; ++j) {
304                 if (*beta == 0.) {
305                     i__2 = *n;
306                     for (i__ = j; i__ <= i__2; ++i__) {
307                         c__[i__ + j * c_dim1] = 0.;
308 /* L140: */
309                     }
310                 } else if (*beta != 1.) {
311                     i__2 = *n;
312                     for (i__ = j; i__ <= i__2; ++i__) {
313                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1];
314 /* L150: */
315                     }
316                 }
317                 i__2 = *k;
318                 for (l = 1; l <= i__2; ++l) {
319                     if (a[j + l * a_dim1] != 0. || b[j + l * b_dim1] != 0.) {
320                         temp1 = *alpha * b[j + l * b_dim1];
321                         temp2 = *alpha * a[j + l * a_dim1];
322                         i__3 = *n;
323                         for (i__ = j; i__ <= i__3; ++i__) {
324                             c__[i__ + j * c_dim1] = c__[i__ + j * c_dim1] + a[
325                                     i__ + l * a_dim1] * temp1 + b[i__ + l * 
326                                     b_dim1] * temp2;
327 /* L160: */
328                         }
329                     }
330 /* L170: */
331                 }
332 /* L180: */
333             }
334         }
335     } else {
336
337 /*        Form  C := alpha*A'*B + alpha*B'*A + C. */
338
339         if (upper) {
340             i__1 = *n;
341             for (j = 1; j <= i__1; ++j) {
342                 i__2 = j;
343                 for (i__ = 1; i__ <= i__2; ++i__) {
344                     temp1 = 0.;
345                     temp2 = 0.;
346                     i__3 = *k;
347                     for (l = 1; l <= i__3; ++l) {
348                         temp1 += a[l + i__ * a_dim1] * b[l + j * b_dim1];
349                         temp2 += b[l + i__ * b_dim1] * a[l + j * a_dim1];
350 /* L190: */
351                     }
352                     if (*beta == 0.) {
353                         c__[i__ + j * c_dim1] = *alpha * temp1 + *alpha * 
354                                 temp2;
355                     } else {
356                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1] 
357                                 + *alpha * temp1 + *alpha * temp2;
358                     }
359 /* L200: */
360                 }
361 /* L210: */
362             }
363         } else {
364             i__1 = *n;
365             for (j = 1; j <= i__1; ++j) {
366                 i__2 = *n;
367                 for (i__ = j; i__ <= i__2; ++i__) {
368                     temp1 = 0.;
369                     temp2 = 0.;
370                     i__3 = *k;
371                     for (l = 1; l <= i__3; ++l) {
372                         temp1 += a[l + i__ * a_dim1] * b[l + j * b_dim1];
373                         temp2 += b[l + i__ * b_dim1] * a[l + j * a_dim1];
374 /* L220: */
375                     }
376                     if (*beta == 0.) {
377                         c__[i__ + j * c_dim1] = *alpha * temp1 + *alpha * 
378                                 temp2;
379                     } else {
380                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1] 
381                                 + *alpha * temp1 + *alpha * temp2;
382                     }
383 /* L230: */
384                 }
385 /* L240: */
386             }
387         }
388     }
389
390     return 0;
391
392 /*     End of DSYR2K. */
393
394 } /* dsyr2k_ */