dmmul.c

Go to the documentation of this file.
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 

Generated on Sun Mar 4 15:03:59 2007 for Scilab [trunk] by  doxygen 1.5.1