home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / bcpp / file19 / tstsmat2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  4.5 KB  |  177 lines

  1. //////////////////////////////////////////////////////////////
  2. // tstsmat2.cpp: Timing test program for matrix multiplies
  3. // of SimpleMatrix objects.
  4. // Copyright(c) 1993 Azarona Software. All rights reserved.
  5. //////////////////////////////////////////////////////////////
  6.  
  7. #include <iostream.h>
  8. #include <iomanip.h>
  9. #include <stdlib.h>
  10. #include <conio.h>
  11. #include "simpmat.h"
  12.  
  13. typedef double Number;
  14.  
  15. const int d1 = 30;  // We'll do 30x30 matrices
  16. const int d2 = 30;
  17.  
  18. SimpleMatrix<Number> a(d1, d2);
  19. SimpleMatrix<Number> b(d2, d1);
  20. SimpleMatrix<Number> c(d1, d1);
  21.  
  22. void Test1(SimpleMatrix<Number> &c, 
  23.   const SimpleMatrix<Number> &a, const SimpleMatrix<Number> &b)
  24. // Uses double subscripting
  25. {
  26.   unsigned i, j, k;
  27.  
  28.   for (i = 0; i < a.NRows(); i++) {
  29.       for (j = 0; j < b.NCols(); j++) {
  30.           Number sum = 0;
  31.           for (k = 0; k < b.NRows(); k++) sum += a[i][k] * b[k][j];
  32.           c[i][j] = sum;
  33.       }
  34.   }
  35. }
  36.  
  37. void Test2(SimpleMatrix<Number> &c, 
  38.   const SimpleMatrix<Number> &a, const SimpleMatrix<Number> &b)
  39. // Factors some of the vector construction out of the loops
  40. {
  41.   unsigned i, j, k;
  42.  
  43.   for (i = 0; i < a.NRows(); i++) {
  44.       VecPtr<const Number> ar = a.RowPtr(i);
  45.       VecPtr<Number> cr = c.RowPtr(i);
  46.       for (j = 0; j < b.NCols(); j++) {
  47.           Number sum = 0;
  48.           VecPtr<const Number> bc = b.ColPtr(j);
  49.           for (k = 0; k < b.NRows(); k++) {
  50.                sum += ar[k] * bc[k];
  51.           }
  52.           cr[j] = sum;
  53.       }
  54.   }
  55. }
  56.  
  57. void Test3(SimpleMatrix<Number> &c, 
  58.   const SimpleMatrix<Number> &a, const SimpleMatrix<Number> &b)
  59. // Fastest form using vector pointers
  60. {
  61.   unsigned i, j, k;
  62.  
  63.   VecPtr<const Number> ar = a.RowPtr();
  64.   VecPtr<const Number> ac = a.ColPtr();
  65.   VecPtr<const Number> br = b.RowPtr();
  66.   VecPtr<const Number> bc = b.ColPtr();
  67.   VecPtr<Number> cr = c.RowPtr();
  68.   VecPtr<Number> cc = c.ColPtr();
  69.  
  70.   Number const *bstart = br;
  71.  
  72.   for (i = 0; i < a.NRows(); i++) {
  73.       cr = cc; // Point to start of row i. Note: stride not copied
  74.       br = bstart;
  75.       for (j = 0; j < b.NCols(); j++) {
  76.           Number sum = 0;
  77.           ar = ac; // Point to start of row i. Note: stride not copied
  78.           bc = br; // Point to start of col j. Note: stride not copied
  79.           for (k = 0; k < b.NRows(); k++) {
  80.                sum += *ar * *bc;
  81.                ar++; // Next col
  82.                bc++; // Next row
  83.           }
  84.           br++; // Next col
  85.           *cr = sum;
  86.           cr++; // Next col
  87.       }
  88.       ac++; // Next row
  89.       cc++; // Next row
  90.   }
  91. }
  92.  
  93. void Test4(SimpleMatrix<Number> &c, 
  94.    const SimpleMatrix<Number> &a, const SimpleMatrix<Number> &b)
  95. // Possibly, fastest of all, by assuming row vectors have stride
  96. // of 1, and thus using ordinary pointers instead
  97. {
  98.   unsigned i, j, k;
  99.  
  100.   const Number *ar        = a.RowPtr();
  101.   VecPtr<const Number> ac = a.ColPtr();
  102.   const Number *br        = b.RowPtr();
  103.   VecPtr<const Number> bc = b.ColPtr();
  104.   Number *cr              = c.RowPtr();
  105.   VecPtr<Number> cc       = c.ColPtr();
  106.  
  107.   const Number *bstart = br;
  108.  
  109.   for (i = 0; i < a.NRows(); i++) {
  110.       cr = cc; // Point to start of row i
  111.       br = bstart;
  112.       for (j = 0; j < b.NCols(); j++) {
  113.           Number sum = 0;
  114.           ar = ac; // Point to start of row i.
  115.           bc = br; // Point to start of col j.
  116.           for (k = 0; k < b.NRows(); k++) {
  117.                sum += *ar * *bc;
  118.                ar++; // Next col
  119.                bc++; // Next row
  120.           }
  121.           br++; // Next col
  122.           *cr = sum;
  123.           cr++; // Next col
  124.       }
  125.       ac++; // Next row
  126.       cc++; // Next row
  127.   }
  128. }
  129.  
  130. void testn(int n, unsigned unsigned num_iter)
  131. {
  132.   unsigned i;
  133.  
  134.   cout << "Press return to start test " << n;
  135.   getch();
  136.   cout << '\n';
  137.   switch(n) {
  138.     case 1: for(i = 0; i<num_iter; i++) Test1(c, a, b);
  139.     break;
  140.     case 2: for(i = 0; i<num_iter; i++) Test2(c, a, b);
  141.     break;
  142.     case 3: for(i = 0; i<num_iter; i++) Test3(c, a, b);
  143.     break;
  144.     case 4: for(i = 0; i<num_iter; i++) Test4(c, a, b);
  145.     break;
  146.   }
  147.   cout << "Finished\n";
  148. }
  149.  
  150. main(int argc, char *argv[])
  151. {
  152.   unsigned n = 1;
  153.  
  154.   if (argc <= 1) {
  155.      cout << "Usage: tstmat2 [num_iter]\n";
  156.      return 1;
  157.   }
  158.  
  159.   n = (unsigned)atoi(argv[1]);
  160.  
  161.   unsigned i, j, k;
  162.  
  163.  
  164.   for(i = 0, k = 1; i<d1; i++)
  165.      for(j = 0; j<d2; j++) a[i][j] = k++;
  166.  
  167.   for(i = 0, k = 2; i<d2; i++)
  168.      for(j = 0; j<d1; j++) b[i][j] = k++;
  169.  
  170.   testn(1, n);
  171.   testn(2, n);
  172.   testn(3, n);
  173.   testn(4, n);
  174.   return 0;
  175. }
  176.  
  177.