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