Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / lapack / ssyr2k.c
1 #include "clapack.h"
2
3 /* Subroutine */ int ssyr2k_(char *uplo, char *trans, integer *n, integer *k, 
4         real *alpha, real *a, integer *lda, real *b, integer *ldb, real *beta, 
5          real *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     real 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 /*  SSYR2K  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  - REAL            . */
83 /*           On entry, ALPHA specifies the scalar alpha. */
84 /*           Unchanged on exit. */
85
86 /*  A      - REAL             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      - REAL             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   - REAL            . */
117 /*           On entry, BETA specifies the scalar beta. */
118 /*           Unchanged on exit. */
119
120 /*  C      - REAL             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_("SSYR2K", &info);
202         return 0;
203     }
204
205 /*     Quick return if possible. */
206
207     if (*n == 0 || (*alpha == 0.f || *k == 0) && *beta == 1.f) {
208         return 0;
209     }
210
211 /*     And when  alpha.eq.zero. */
212
213     if (*alpha == 0.f) {
214         if (upper) {
215             if (*beta == 0.f) {
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.f;
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.f) {
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.f;
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.f) {
272                     i__2 = j;
273                     for (i__ = 1; i__ <= i__2; ++i__) {
274                         c__[i__ + j * c_dim1] = 0.f;
275 /* L90: */
276                     }
277                 } else if (*beta != 1.f) {
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.f || b[j + l * b_dim1] != 0.f) 
287                             {
288                         temp1 = *alpha * b[j + l * b_dim1];
289                         temp2 = *alpha * a[j + l * a_dim1];
290                         i__3 = j;
291                         for (i__ = 1; i__ <= i__3; ++i__) {
292                             c__[i__ + j * c_dim1] = c__[i__ + j * c_dim1] + a[
293                                     i__ + l * a_dim1] * temp1 + b[i__ + l * 
294                                     b_dim1] * temp2;
295 /* L110: */
296                         }
297                     }
298 /* L120: */
299                 }
300 /* L130: */
301             }
302         } else {
303             i__1 = *n;
304             for (j = 1; j <= i__1; ++j) {
305                 if (*beta == 0.f) {
306                     i__2 = *n;
307                     for (i__ = j; i__ <= i__2; ++i__) {
308                         c__[i__ + j * c_dim1] = 0.f;
309 /* L140: */
310                     }
311                 } else if (*beta != 1.f) {
312                     i__2 = *n;
313                     for (i__ = j; i__ <= i__2; ++i__) {
314                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1];
315 /* L150: */
316                     }
317                 }
318                 i__2 = *k;
319                 for (l = 1; l <= i__2; ++l) {
320                     if (a[j + l * a_dim1] != 0.f || b[j + l * b_dim1] != 0.f) 
321                             {
322                         temp1 = *alpha * b[j + l * b_dim1];
323                         temp2 = *alpha * a[j + l * a_dim1];
324                         i__3 = *n;
325                         for (i__ = j; i__ <= i__3; ++i__) {
326                             c__[i__ + j * c_dim1] = c__[i__ + j * c_dim1] + a[
327                                     i__ + l * a_dim1] * temp1 + b[i__ + l * 
328                                     b_dim1] * temp2;
329 /* L160: */
330                         }
331                     }
332 /* L170: */
333                 }
334 /* L180: */
335             }
336         }
337     } else {
338
339 /*        Form  C := alpha*A'*B + alpha*B'*A + C. */
340
341         if (upper) {
342             i__1 = *n;
343             for (j = 1; j <= i__1; ++j) {
344                 i__2 = j;
345                 for (i__ = 1; i__ <= i__2; ++i__) {
346                     temp1 = 0.f;
347                     temp2 = 0.f;
348                     i__3 = *k;
349                     for (l = 1; l <= i__3; ++l) {
350                         temp1 += a[l + i__ * a_dim1] * b[l + j * b_dim1];
351                         temp2 += b[l + i__ * b_dim1] * a[l + j * a_dim1];
352 /* L190: */
353                     }
354                     if (*beta == 0.f) {
355                         c__[i__ + j * c_dim1] = *alpha * temp1 + *alpha * 
356                                 temp2;
357                     } else {
358                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1] 
359                                 + *alpha * temp1 + *alpha * temp2;
360                     }
361 /* L200: */
362                 }
363 /* L210: */
364             }
365         } else {
366             i__1 = *n;
367             for (j = 1; j <= i__1; ++j) {
368                 i__2 = *n;
369                 for (i__ = j; i__ <= i__2; ++i__) {
370                     temp1 = 0.f;
371                     temp2 = 0.f;
372                     i__3 = *k;
373                     for (l = 1; l <= i__3; ++l) {
374                         temp1 += a[l + i__ * a_dim1] * b[l + j * b_dim1];
375                         temp2 += b[l + i__ * b_dim1] * a[l + j * a_dim1];
376 /* L220: */
377                     }
378                     if (*beta == 0.f) {
379                         c__[i__ + j * c_dim1] = *alpha * temp1 + *alpha * 
380                                 temp2;
381                     } else {
382                         c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1] 
383                                 + *alpha * temp1 + *alpha * temp2;
384                     }
385 /* L230: */
386                 }
387 /* L240: */
388             }
389         }
390     }
391
392     return 0;
393
394 /*     End of SSYR2K. */
395
396 } /* ssyr2k_ */