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

  1. /////////////////////////////////////////////////////////////////
  2. // tstmat4.cpp: This program compares using static 2-d matrices
  3. // with the more general SimpleMatrix and Matrix objects when
  4. // it comes to doing matrix multiplies.
  5. // Copyright(c) 1993 Azarona Software. All rights reserved.
  6. //
  7. // Usage: tstmat4 [num_iter]
  8. //
  9. // Meant to be used with a stop-watch to time the algorithms.
  10. //
  11. // Test 1: Uses statically allocated matrices -- fast!
  12. // Test 2: Uses dynamically allocated SimpleMatrix objects,
  13. //         with m[i][j] style of subscripting.
  14. // Test 3: Uses fast vector pointer form for SimpleMatrix objects
  15. // Test 4: Uses Matrix objects with m[i][j] subscripting. (Slow!)
  16. // Test 5: Uses Matrix objects with m(i,j) subscripting.
  17. // Test 6: Uses fastest form possible for Matrix objects, using
  18. //         fast vector pointers.
  19. /////////////////////////////////////////////////////////////////
  20. #include <iostream.h>
  21. #include <iomanip.h>
  22. #include <stdlib.h>
  23. #include <conio.h>
  24. #include "simpmat.h"
  25. #include "matrix.h"
  26.  
  27. typedef double Number;
  28.  
  29. INITNULLVEC(Number);
  30.  
  31. const int d1 = 30;
  32. const int d2 = 30;
  33.  
  34. Number raw_a[d1][d2];
  35. Number raw_b[d2][d1];
  36. Number raw_c[d1][d1];
  37.  
  38. SimpleMatrix<Number> simp_a(d1, d2);
  39. SimpleMatrix<Number> simp_b(d2, d1);
  40. SimpleMatrix<Number> simp_c(d1, d1);
  41.  
  42. Matrix<Number> a(d1, d2);
  43. Matrix<Number> b(d2, d1);
  44. Matrix<Number> c(d1, d1);
  45.  
  46.  
  47. void Test1(Number (*c)[d1], const Number (*a)[d2], const Number (*b)[d1])
  48. // Fastest, cause it uses statically allocated matrices, with constant
  49. // dimensions. However, very inflexible.
  50. {
  51.   unsigned i, j, k;
  52.   for (i = 0; i < d1; i++) {
  53.       for (j = 0; j < d1; j++) {
  54.           Number sum = 0;
  55.           for (k = 0; k < d2; k++) sum += a[i][k] * b[k][j];
  56.           c[i][j] = sum;
  57.       }
  58.   }
  59. }
  60.  
  61. template<class TYPE>
  62. void Test2(SimpleMatrix<TYPE> &c, 
  63.   const SimpleMatrix<TYPE> &a, const SimpleMatrix<TYPE> &b)
  64. // Uses dynamically allocated SimpleMatrix objects with subscripting.
  65. // Kind of slow.
  66. {
  67.   unsigned i, j, k;
  68.   for (i = 0; i < a.NRows(); i++) {
  69.       for (j = 0; j < b.NCols(); j++) {
  70.           TYPE sum = 0;
  71.           for (k = 0; k < b.NRows(); k++) sum += a[i][k] * b[k][j];
  72.           c[i][j] = sum;
  73.       }
  74.   }
  75. }
  76.  
  77. template<class TYPE>
  78. void Test3(SimpleMatrix<TYPE> &c, 
  79.    const SimpleMatrix<TYPE> &a, const SimpleMatrix<TYPE> &b)
  80. // Fastest form for SimpleMatrices, by assuming row vectors 
  81. // have a stride of 1, thus using ordinary pointers instead
  82. {
  83.   unsigned i, j, k;
  84.  
  85. #ifdef SUPPOSEDLYFASTEST
  86.   const TYPE *ar        = a.RowPtr();
  87. #else
  88.   VecPtr<const TYPE> ar = a.RowPtr();
  89. #endif
  90.   VecPtr<const TYPE> ac = a.ColPtr();
  91. #ifdef SUPPOSEDLYFASTEST
  92.   const TYPE *br        = b.RowPtr();
  93. #else
  94.   VecPtr<const TYPE> br = b.RowPtr();
  95. #endif
  96.   VecPtr<const TYPE> bc = b.ColPtr();
  97. #ifdef SUPPOSEDLYFASTEST
  98.   TYPE *cr              = c.RowPtr();
  99. #else
  100.   VecPtr<TYPE> cr       = c.RowPtr();
  101. #endif
  102.   VecPtr<TYPE> cc       = c.ColPtr();
  103.  
  104.   const TYPE *bstart = br;
  105.  
  106.   for (i = 0; i < a.NRows(); i++) {
  107.       cr = cc; // Point to start of row i
  108.       br = bstart;
  109.       for (j = 0; j < b.NCols(); j++) {
  110.           TYPE sum = 0;
  111.           ar = ac; // Point to start of row i.
  112.           bc = br; // Point to start of col j.
  113.           for (k = 0; k < b.NRows(); k++) {
  114.                sum += *ar * *bc;
  115.                ar++; // Next col
  116.                bc++; // Next row
  117.           }
  118.           br++; // Next col
  119.           *cr = sum;
  120.           cr++; // Next col
  121.       }
  122.       ac++; // Next row
  123.       cc++; // Next row
  124.   }
  125. }
  126.  
  127. template<class TYPE>
  128. void Test4(Matrix<TYPE> &c, const Matrix<TYPE> &a, const Matrix<TYPE> &b)
  129. // Uses dynamically allocated Matrix objects with double-subscripting.
  130. // Really S--L--O--W.
  131. {
  132.   unsigned i, j, k;
  133.   for (i = 0; i < a.NRows(); i++) {
  134.       for (j = 0; j < b.NCols(); j++) {
  135.           TYPE sum = 0;
  136.           for (k = 0; k < b.NRows(); k++) sum += a[i][k] * b[k][j];
  137.           c[i][j] = sum;
  138.       }
  139.   }
  140. }
  141.  
  142. template<class TYPE>
  143. void Test5(Matrix<TYPE> &c, const Matrix<TYPE> &a, const Matrix<TYPE> &b)
  144. // Uses dynamically allocated Matrix objects with 2-d subscripting.
  145. // Better than Test4, but still slow.
  146. {
  147.   unsigned i, j, k;
  148.  
  149.   for (i = 0; i < a.NRows(); i++) {
  150.       for (j = 0; j < b.NCols(); j++) {
  151.           TYPE sum = 0;
  152.           for (k = 0; k < b.NRows(); k++) sum += a(i,k) * b(k,j);
  153.           c(i,j) = sum;
  154.       }
  155.   }
  156. }
  157.  
  158.  
  159. template<class TYPE>
  160. void Test6(Matrix<TYPE> &c, const Matrix<TYPE> &a, const Matrix<TYPE> &b)
  161. // Fastest routine for Matrix objects, using vector pointers.
  162. // Should be pretty decent.
  163. {
  164.   unsigned i, j, k;
  165.  
  166.   VecPtr<const TYPE> ar = a.RowPtr();
  167.   VecPtr<const TYPE> ac = a.ColPtr();
  168.   VecPtr<const TYPE> br = b.RowPtr();
  169.   VecPtr<const TYPE> bc = b.ColPtr();
  170.   VecPtr<TYPE> cr = c.RowPtr();
  171.   VecPtr<TYPE> cc = c.ColPtr();
  172.   
  173.   const TYPE *bstart = b.PtrToAll();
  174.  
  175.   for (i = 0; i < a.NRows(); i++) {
  176.       cr = cc; // Point to start of row i
  177.       br = bstart;
  178.       for (j = 0; j < b.NCols(); j++) {
  179.           TYPE sum = 0;
  180.           ar = ac; // Point to start of row i
  181.           bc = br; // Point to start of col j
  182.           for (k = 0; k < b.NRows(); k++) {
  183.                sum += *ar * *bc;
  184.                ar++; // Next col
  185.                bc++; // Next row
  186.           }
  187.           br++; // Next col
  188.           *cr = sum;
  189.           cr++; // Next col
  190.       }
  191.       ac++; // Next row
  192.       cc++; // Next row
  193.   }
  194. }
  195.  
  196.  
  197. void testn(int n, unsigned unsigned num_iter)
  198. {
  199.   unsigned i;
  200.  
  201.   cout << "Press return to start test " << n;
  202.   getch();
  203.   cout << '\n';
  204.   switch(n) {
  205.     case 1: for(i = 0; i<num_iter; i++) Test1(raw_c, raw_a, raw_b);
  206.     break;
  207.     case 2: for(i = 0; i<num_iter; i++) Test2(simp_c, simp_a, simp_b);
  208.     break;
  209.     case 3: for(i = 0; i<num_iter; i++) Test3(simp_c, simp_a, simp_b);
  210.     break;
  211.     case 4: for(i = 0; i<num_iter; i++) Test4(c, a, b);
  212.     break;
  213.     case 5: for(i = 0; i<num_iter; i++) Test5(c, a, b);
  214.     break;
  215.     case 6: for(i = 0; i<num_iter; i++) Test6(c, a, b);
  216.     break;
  217.   }
  218.   cout << "Finished\n";
  219. }
  220.  
  221. main(int argc, char *argv[])
  222. {
  223.   unsigned n = 1;
  224.  
  225.   if (argc <= 1) {
  226.      cout << "Usage: tstmat4 [num_iter]\n";
  227.      return 1;
  228.   }
  229.  
  230.   n = (unsigned)atoi(argv[1]);
  231.  
  232.   unsigned i, j, k;
  233.  
  234.   for(i = 0, k = 1; i<d1; i++)
  235.      for(j = 0; j<d2; j++) raw_a[i][j] = k++;
  236.  
  237.   for(i = 0, k = 2; i<d2; i++)
  238.      for(j = 0; j<d1; j++) raw_b[i][j] = k++;
  239.  
  240.  
  241.   for(i = 0, k = 1; i<d1; i++)
  242.      for(j = 0; j<d2; j++) simp_a[i][j] = k++;
  243.  
  244.   for(i = 0, k = 2; i<d2; i++)
  245.      for(j = 0; j<d1; j++) simp_b[i][j] = k++;
  246.  
  247.   for(i = 0, k = 1; i<d1; i++)
  248.      for(j = 0; j<d2; j++) a[i][j] = k++;
  249.  
  250.   for(i = 0, k = 2; i<d2; i++)
  251.      for(j = 0; j<d1; j++) b[i][j] = k++;
  252.  
  253.   testn(1, n);
  254.   testn(2, n);
  255.   testn(3, n);
  256.   testn(4, n);
  257.   testn(5, n);
  258.   testn(6, n);
  259.   return 0;
  260. }
  261.  
  262.