00001 #include <stdio.h> /* printf */ 00002 /* Table of constant values */ 00003 00004 static double c_b4 = 1.; 00005 static double c_b5 = 0.; 00006 00007 #define max(a,b) ((a) >= (b) ? (a) : (b)) 00008 int dgemm(); 00009 int dmmul(double *a, int *na, double *b, int *nb, double *c__, 00010 int *nc, int *l, int *m, int *n) 00011 { 00012 int a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset; 00013 00014 /* PURPOSE */ 00015 /* computes the matrix product C = A * B */ 00016 /* C = A * B */ 00017 /* (l,n) (l,m) * (m,n) */ 00018 00019 /* PARAMETERS */ 00020 /* input */ 00021 /* ----- */ 00022 /* A : (double) array (l, m) with leading dim na */ 00023 00024 /* B : (double) array (m, n) with leading dim nb */ 00025 00026 /* na, nb, nc, l, m, n : integers */ 00027 00028 /* output */ 00029 /* ------ */ 00030 /* C : (double) array (l, n) with leading dim nc */ 00031 00032 /* NOTE */ 00033 /* (original version substituted by a call to the blas dgemm) */ 00034 /* Parameter adjustments */ 00035 a_dim1 = *na; 00036 a_offset = 1 + a_dim1 * 1; 00037 a -= a_offset; 00038 c_dim1 = *nc; 00039 c_offset = 1 + c_dim1 * 1; 00040 c__ -= c_offset; 00041 b_dim1 = *nb; 00042 b_offset = 1 + b_dim1 * 1; 00043 b -= b_offset; 00044 00045 /* Function Body */ 00046 dgemm("n", "n", l, n, m, &c_b4, &a[a_offset], na, &b[b_offset], nb, & 00047 c_b5, &c__[c_offset], nc); 00048 return 0; 00049 } /* dmmul */ 00050 00051 int dgemm(char *transa, char *transb, int *m, int *n, int *k, double *alpha, 00052 double *a, int *lda, double *b, int *ldb,double *beta, double *c, 00053 int *ldc) 00054 { 00055 /* System generated locals */ 00056 int i__1, i__2, i__3; 00057 /* Local variables */ 00058 static int info; 00059 static long int nota, notb; 00060 static double temp; 00061 static int i, j, l, ncola; 00062 long int lsame(char *, char *); 00063 static int nrowa, nrowb; 00064 int xerbla(char *, int *); 00065 00066 /* .. Scalar Arguments .. */ 00067 /* .. Array Arguments .. */ 00068 /* .. */ 00069 00070 /* Purpose */ 00071 /* ======= */ 00072 00073 /* DGEMM performs one of the matrix-matrix operations */ 00074 00075 /* C := alpha*op( A )*op( B ) + beta*C, */ 00076 00077 /* where op( X ) is one of */ 00078 00079 /* op( X ) = X or op( X ) = X', */ 00080 00081 /* alpha and beta are scalars, and A, B and C are matrices, with op( A ) */ 00082 /* an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. */ 00083 00084 /* Parameters */ 00085 /* ========== */ 00086 00087 /* TRANSA - CHARACTER*1. */ 00088 /* On entry, TRANSA specifies the form of op( A ) to be used in */ 00089 /* the matrix multiplication as follows: */ 00090 00091 /* TRANSA = 'N' or 'n', op( A ) = A. */ 00092 00093 /* TRANSA = 'T' or 't', op( A ) = A'. */ 00094 00095 /* TRANSA = 'C' or 'c', op( A ) = A'. */ 00096 00097 /* Unchanged on exit. */ 00098 00099 /* TRANSB - CHARACTER*1. */ 00100 /* On entry, TRANSB specifies the form of op( B ) to be used in */ 00101 /* the matrix multiplication as follows: */ 00102 00103 /* TRANSB = 'N' or 'n', op( B ) = B. */ 00104 00105 /* TRANSB = 'T' or 't', op( B ) = B'. */ 00106 00107 /* TRANSB = 'C' or 'c', op( B ) = B'. */ 00108 00109 /* Unchanged on exit. */ 00110 00111 /* M - INTEGER. */ 00112 /* On entry, M specifies the number of rows of the matrix */ 00113 /* op( A ) and of the matrix C. M must be at least zero. */ 00114 /* Unchanged on exit. */ 00115 00116 /* N - INTEGER. */ 00117 /* On entry, N specifies the number of columns of the matrix */ 00118 /* op( B ) and the number of columns of the matrix C. N must be */ 00119 /* at least zero. */ 00120 /* Unchanged on exit. */ 00121 00122 /* K - INTEGER. */ 00123 /* On entry, K specifies the number of columns of the matrix */ 00124 /* op( A ) and the number of rows of the matrix op( B ). K must */ 00125 /* be at least zero. */ 00126 /* Unchanged on exit. */ 00127 00128 /* ALPHA - DOUBLE PRECISION. */ 00129 /* On entry, ALPHA specifies the scalar alpha. */ 00130 /* Unchanged on exit. */ 00131 00132 /* A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is */ 00133 /* k when TRANSA = 'N' or 'n', and is m otherwise. */ 00134 /* Before entry with TRANSA = 'N' or 'n', the leading m by k */ 00135 /* part of the array A must contain the matrix A, otherwise */ 00136 /* the leading k by m part of the array A must contain the */ 00137 /* matrix A. */ 00138 /* Unchanged on exit. */ 00139 00140 /* LDA - INTEGER. */ 00141 /* On entry, LDA specifies the first dimension of A as declared */ 00142 /* in the calling (sub) program. When TRANSA = 'N' or 'n' then */ 00143 /* LDA must be at least max( 1, m ), otherwise LDA must be at */ 00144 /* least max( 1, k ). */ 00145 /* Unchanged on exit. */ 00146 00147 /* B - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is */ 00148 /* n when TRANSB = 'N' or 'n', and is k otherwise. */ 00149 /* Before entry with TRANSB = 'N' or 'n', the leading k by n */ 00150 /* part of the array B must contain the matrix B, otherwise */ 00151 /* the leading n by k part of the array B must contain the */ 00152 /* matrix B. */ 00153 /* Unchanged on exit. */ 00154 00155 /* LDB - INTEGER. */ 00156 /* On entry, LDB specifies the first dimension of B as declared */ 00157 /* in the calling (sub) program. When TRANSB = 'N' or 'n' then */ 00158 /* LDB must be at least max( 1, k ), otherwise LDB must be at */ 00159 /* least max( 1, n ). */ 00160 /* Unchanged on exit. */ 00161 00162 /* BETA - DOUBLE PRECISION. */ 00163 /* On entry, BETA specifies the scalar beta. When BETA is */ 00164 /* supplied as zero then C need not be set on input. */ 00165 /* Unchanged on exit. */ 00166 00167 /* C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). */ 00168 /* Before entry, the leading m by n part of the array C must */ 00169 /* contain the matrix C, except when beta is zero, in which */ 00170 /* case C need not be set on entry. */ 00171 /* On exit, the array C is overwritten by the m by n matrix */ 00172 /* ( alpha*op( A )*op( B ) + beta*C ). */ 00173 00174 /* LDC - INTEGER. */ 00175 /* On entry, LDC specifies the first dimension of C as declared */ 00176 /* in the calling (sub) program. LDC must be at least */ 00177 /* max( 1, m ). */ 00178 /* Unchanged on exit. */ 00179 00180 00181 /* Level 3 Blas routine. */ 00182 00183 /* -- Written on 8-February-1989. */ 00184 /* Jack Dongarra, Argonne National Laboratory. */ 00185 /* Iain Duff, AERE Harwell. */ 00186 /* Jeremy Du Croz, Numerical Algorithms Group Ltd. */ 00187 /* Sven Hammarling, Numerical Algorithms Group Ltd. */ 00188 00189 00190 /* .. External Functions .. */ 00191 /* .. External Subroutines .. */ 00192 /* .. Intrinsic Functions .. */ 00193 /* .. Local Scalars .. */ 00194 /* .. Parameters .. */ 00195 /* .. */ 00196 /* .. Executable Statements .. */ 00197 00198 /* Set NOTA and NOTB as true if A and B respectively are not */ 00199 /* transposed and set NROWA, NCOLA and NROWB as the number of rows */ 00200 /* and columns of A and the number of rows of B respectively. */ 00201 00202 #define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] 00203 #define B(I,J) b[(I)-1 + ((J)-1)* ( *ldb)] 00204 #define C(I,J) c[(I)-1 + ((J)-1)* ( *ldc)] 00205 00206 nota = lsame(transa, "N"); 00207 notb = lsame(transb, "N"); 00208 if (nota) { 00209 nrowa = *m; 00210 ncola = *k; 00211 } else { 00212 nrowa = *k; 00213 ncola = *m; 00214 } 00215 if (notb) { 00216 nrowb = *k; 00217 } else { 00218 nrowb = *n; 00219 } 00220 00221 /* Test the input parameters. */ 00222 00223 info = 0; 00224 if (! nota && ! lsame(transa, "C") && ! lsame(transa, "T")) { 00225 info = 1; 00226 } else if (! notb && ! lsame(transb, "C") && ! lsame(transb,"T")) { 00227 info = 2; 00228 } else if (*m < 0) { 00229 info = 3; 00230 } else if (*n < 0) { 00231 info = 4; 00232 } else if (*k < 0) { 00233 info = 5; 00234 } else if (*lda < max(1,nrowa)) { 00235 info = 8; 00236 } else if (*ldb < max(1,nrowb)) { 00237 info = 10; 00238 } else if (*ldc < max(1,*m)) { 00239 info = 13; 00240 } 00241 if (info != 0) { 00242 xerbla("DGEMM ", &info); 00243 return 0; 00244 } 00245 00246 /* Quick return if possible. */ 00247 00248 if (*m == 0 || *n == 0 || (*alpha == 0. || *k == 0) && *beta == 1.) { 00249 return 0; 00250 } 00251 00252 /* And if alpha.eq.zero. */ 00253 00254 if (*alpha == 0.) { 00255 if (*beta == 0.) { 00256 i__1 = *n; 00257 for (j = 1; j <= *n; ++j) { 00258 i__2 = *m; 00259 for (i = 1; i <= *m; ++i) { 00260 C(i,j) = 0.; 00261 /* L10: */ 00262 } 00263 /* L20: */ 00264 } 00265 } else { 00266 i__1 = *n; 00267 for (j = 1; j <= *n; ++j) { 00268 i__2 = *m; 00269 for (i = 1; i <= *m; ++i) { 00270 C(i,j) = *beta * C(i,j); 00271 /* L30: */ 00272 } 00273 /* L40: */ 00274 } 00275 } 00276 return 0; 00277 } 00278 00279 /* Start the operations. */ 00280 00281 if (notb) { 00282 if (nota) { 00283 00284 /* Form C := alpha*A*B + beta*C. */ 00285 00286 i__1 = *n; 00287 for (j = 1; j <= *n; ++j) { 00288 if (*beta == 0.) { 00289 i__2 = *m; 00290 for (i = 1; i <= *m; ++i) { 00291 C(i,j) = 0.; 00292 /* L50: */ 00293 } 00294 } else if (*beta != 1.) { 00295 i__2 = *m; 00296 for (i = 1; i <= *m; ++i) { 00297 C(i,j) = *beta * C(i,j); 00298 /* L60: */ 00299 } 00300 } 00301 i__2 = *k; 00302 for (l = 1; l <= *k; ++l) { 00303 if (B(l,j) != 0.) { 00304 temp = *alpha * B(l,j); 00305 i__3 = *m; 00306 for (i = 1; i <= *m; ++i) { 00307 C(i,j) += temp * A(i,l); 00308 /* L70: */ 00309 } 00310 } 00311 /* L80: */ 00312 } 00313 /* L90: */ 00314 } 00315 } else { 00316 00317 /* Form C := alpha*A'*B + beta*C */ 00318 00319 i__1 = *n; 00320 for (j = 1; j <= *n; ++j) { 00321 i__2 = *m; 00322 for (i = 1; i <= *m; ++i) { 00323 temp = 0.; 00324 i__3 = *k; 00325 for (l = 1; l <= *k; ++l) { 00326 temp += A(l,i) * B(l,j); 00327 /* L100: */ 00328 } 00329 if (*beta == 0.) { 00330 C(i,j) = *alpha * temp; 00331 } else { 00332 C(i,j) = *alpha * temp + *beta * C(i,j); 00333 } 00334 /* L110: */ 00335 } 00336 /* L120: */ 00337 } 00338 } 00339 } else { 00340 if (nota) { 00341 00342 /* Form C := alpha*A*B' + beta*C */ 00343 00344 i__1 = *n; 00345 for (j = 1; j <= *n; ++j) { 00346 if (*beta == 0.) { 00347 i__2 = *m; 00348 for (i = 1; i <= *m; ++i) { 00349 C(i,j) = 0.; 00350 /* L130: */ 00351 } 00352 } else if (*beta != 1.) { 00353 i__2 = *m; 00354 for (i = 1; i <= *m; ++i) { 00355 C(i,j) = *beta * C(i,j); 00356 /* L140: */ 00357 } 00358 } 00359 i__2 = *k; 00360 for (l = 1; l <= *k; ++l) { 00361 if (B(j,l) != 0.) { 00362 temp = *alpha * B(j,l); 00363 i__3 = *m; 00364 for (i = 1; i <= *m; ++i) { 00365 C(i,j) += temp * A(i,l); 00366 /* L150: */ 00367 } 00368 } 00369 /* L160: */ 00370 } 00371 /* L170: */ 00372 } 00373 } else { 00374 00375 /* Form C := alpha*A'*B' + beta*C */ 00376 00377 i__1 = *n; 00378 for (j = 1; j <= *n; ++j) { 00379 i__2 = *m; 00380 for (i = 1; i <= *m; ++i) { 00381 temp = 0.; 00382 i__3 = *k; 00383 for (l = 1; l <= *k; ++l) { 00384 temp += A(l,i) * B(j,l); 00385 /* L180: */ 00386 } 00387 if (*beta == 0.) { 00388 C(i,j) = *alpha * temp; 00389 } else { 00390 C(i,j) = *alpha * temp + *beta * C(i,j); 00391 } 00392 /* L190: */ 00393 } 00394 /* L200: */ 00395 } 00396 } 00397 } 00398 00399 return 0; 00400 00401 /* End of DGEMM . */ 00402 00403 } /* dgemm */ 00404 00405 long int lsame(char *ca, char *cb) 00406 { 00407 /* System generated locals */ 00408 long int ret_val; 00409 00410 /* Local variables */ 00411 static int inta, intb, zcode; 00412 00413 00414 /* -- LAPACK auxiliary routine (version 2.0) -- */ 00415 /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ 00416 /* Courant Institute, Argonne National Lab, and Rice University */ 00417 /* January 31, 1994 */ 00418 00419 /* .. Scalar Arguments .. */ 00420 /* .. */ 00421 00422 /* Purpose */ 00423 /* ======= */ 00424 00425 /* LSAME returns .TRUE. if CA is the same letter as CB regardless of */ 00426 /* case. */ 00427 00428 /* Arguments */ 00429 /* ========= */ 00430 00431 /* CA (input) CHARACTER*1 */ 00432 /* CB (input) CHARACTER*1 */ 00433 /* CA and CB specify the single characters to be compared. */ 00434 00435 /* ===================================================================== */ 00436 00437 /* .. Intrinsic Functions .. */ 00438 /* .. */ 00439 /* .. Local Scalars .. */ 00440 /* .. */ 00441 /* .. Executable Statements .. */ 00442 00443 /* Test if the characters are equal */ 00444 00445 ret_val = *(unsigned char *)ca == *(unsigned char *)cb; 00446 if (ret_val) { 00447 return ret_val; 00448 } 00449 00450 /* Now test for equivalence if both characters are alphabetic. */ 00451 00452 zcode = 'Z'; 00453 00454 /* Use 'Z' rather than 'A' so that ASCII can be detected on Prime */ 00455 /* machines, on which ICHAR returns a value with bit 8 set. */ 00456 /* ICHAR('A') on Prime machines returns 193 which is the same as */ 00457 /* ICHAR('A') on an EBCDIC machine. */ 00458 00459 inta = *(unsigned char *)ca; 00460 intb = *(unsigned char *)cb; 00461 00462 if (zcode == 90 || zcode == 122) { 00463 00464 /* ASCII is assumed - ZCODE is the ASCII code of either lower or */ 00465 /* upper case 'Z'. */ 00466 00467 if (inta >= 97 && inta <= 122) { 00468 inta += -32; 00469 } 00470 if (intb >= 97 && intb <= 122) { 00471 intb += -32; 00472 } 00473 00474 } else if (zcode == 233 || zcode == 169) { 00475 00476 /* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or */ 00477 /* upper case 'Z'. */ 00478 00479 if (inta >= 129 && inta <= 137 || inta >= 145 && inta <= 153 || inta 00480 >= 162 && inta <= 169) { 00481 inta += 64; 00482 } 00483 if (intb >= 129 && intb <= 137 || intb >= 145 && intb <= 153 || intb 00484 >= 162 && intb <= 169) { 00485 intb += 64; 00486 } 00487 00488 } else if (zcode == 218 || zcode == 250) { 00489 00490 /* ASCII is assumed, on Prime machines - ZCODE is the ASCII code */ 00491 /* plus 128 of either lower or upper case 'Z'. */ 00492 00493 if (inta >= 225 && inta <= 250) { 00494 inta += -32; 00495 } 00496 if (intb >= 225 && intb <= 250) { 00497 intb += -32; 00498 } 00499 } 00500 ret_val = inta == intb; 00501 00502 /* RETURN */ 00503 00504 /* End of LSAME */ 00505 00506 return ret_val; 00507 } /* lsame */ 00508 00509 int xerbla(char *srname, int *info) 00510 { 00511 00512 /* -- LAPACK auxiliary routine (version 3.0) -- */ 00513 /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */ 00514 /* Courant Institute, Argonne National Lab, and Rice University */ 00515 /* September 30, 1994 */ 00516 00517 /* .. Scalar Arguments .. */ 00518 /* .. */ 00519 00520 /* Purpose */ 00521 /* ======= */ 00522 00523 /* XERBLA is an error handler for the LAPACK routines. */ 00524 /* It is called by an LAPACK routine if an input parameter has an */ 00525 /* invalid value. A message is printed and execution stops. */ 00526 00527 /* Installers may consider modifying the STOP statement in order to */ 00528 /* call system-specific exception-handling facilities. */ 00529 00530 /* Arguments */ 00531 /* ========= */ 00532 00533 /* SRNAME (input) CHARACTER*6 */ 00534 /* The name of the routine which called XERBLA. */ 00535 00536 /* INFO (input) INTEGER */ 00537 /* The position of the invalid parameter in the parameter list */ 00538 /* of the calling routine. */ 00539 00540 /* ===================================================================== */ 00541 00542 printf("** On entry to %6s, parameter number %2i had an illegal value\n", 00543 srname, *info); 00544 00545 00546 /* End of XERBLA */ 00547 return 0; 00548 } /* xerbla */ 00549
1.5.1