001    
002    /** 
003     * Matrix Multiplication main class.
004     * @author Heinz Kredel.
005     */
006    
007    public class MatMult {
008    
009    
010    /** 
011     * Performs a subtraction operation between two arrays sequentially.
012     * @param C result matrix = A-B.
013     * @param A left matrix.
014     * @param B right matirx.
015     */
016      public void seqdiff(double[][] C, double[][] A, double[][] B) {
017          for (int i=0; i < C.length; i++) {
018              for (int j=0; j < C[0].length; j++) {
019                  C[i][j] = A[i][j] - B[i][j];
020              }
021          }
022      }
023    
024    
025    /** 
026     * Performs a transpose operation of the matrix.
027     * Must be a square matrix.
028     * @param A matrix.
029     */
030      public void transposeInplace(double[][] A) {
031          for (int i=0; i < A.length; i++) {
032              for (int j=i+1; j < A[0].length; j++) {
033                  double aij = A[i][j];
034                  A[i][j] = A[j][i];
035                  A[j][i] = aij;
036              }
037          }
038      }
039    
040    
041    /** 
042     * Performs a transpose operation of the matrix.
043     * If A is n x m then B must be m x n.
044     * @param A Array.
045     * @param B Array transpose(A).
046     */
047        public void transpose(double[][] B, double[][] A) {
048          for (int i=0; i < A.length; i++) {
049              for (int j=i+1; j < A[0].length; j++) {
050                  B[j][i] = A[i][j];
051              }
052          }
053      }
054    
055    
056    /**
057     * Generates a matrix.
058     * Creates a two dimensional array <CODE>A</CODE> with the dimension n, m.
059     * The method <CODE>random</CODE> returns a 
060     * random number within the intervall [0,1].
061     * @param n dimension of matrix.
062     * @param m dimension of matrix.
063     */
064      public double[][] matgen(int n, int m) {
065          double A[][] = new double[n][m];
066          for (int i=0; i < n; i++) {
067              for (int j=0; j < m; j++) {
068                  A[i][j] = Math.random();
069              }
070          }
071          return A;
072      }
073    
074    
075    /** 
076     * Generates the null-matrix.
077     * @param n dimension of matrix.
078     * @param m dimension of matrix.
079     */
080      public double[][] matgen0(int n, int m) {
081          double A[][] = new double[n][m];
082          for (int i=0; i < n; i++) {
083              for (int j=0; j < m; j++) {
084                  A[i][j] = 0.0;
085              }
086          }
087          return A;
088      }
089    
090    
091    /** 
092     * Generates the unit-matrix.
093     * @param n dimension of matrix.
094     * @param m dimension of matrix.
095     */
096      public double[][] matgen1(int n, int m) {
097          double A[][] = new double[n][m];
098          for (int i=0; i < n; i++) {
099              for (int j=0; j < m; j++) {
100                  if (i == j) A[i][j] = 1.0; else A[i][j]= 0.0;
101              }
102          }
103          return A;
104      }
105    
106    
107    /** 
108     * Prints out the rows of matrix.
109     * @param A Array. 
110     */
111      public void matprint(double[][] A) {
112          for (int i=0; i < A.length; i++) {
113              for (int j=0; j < A[0].length; j++) {
114                  System.out.print(A[i][j] + " ");
115              }
116              System.out.println();
117          }
118      }
119    
120    
121    /** 
122     * Checks if the matrix is approximatly zero.
123     * Checks if the absolut value of the matrix's elements are less than
124     * the production of the smallest positive value and 1000.
125     * @param A Two dimensional array.
126     */ 
127      public boolean matcheck0(double[][] A) {
128          double eps = Double.MIN_VALUE*1000.0;
129          for (int i=0; i < A.length; i++) {
130              for (int j=0; j < A[0].length; j++) {
131                  if ( Math.abs(A[i][j]) > eps) { 
132                      System.out.println("(i,j)=("+i+","+j+") = "+ A[i][j]);
133                     return false;
134                  }
135              }
136          }
137          return true;
138      }
139    
140    
141    /**
142     * main
143     */
144      public static void main(String[] args) {
145    
146            int m = 2, // rows of A
147                n = 4, // columns of B 
148                p = 3; // columns of A = rows of B
149            boolean prnt = false;
150    
151            try { m = Integer.parseInt(args[0]); 
152            } catch (Exception e) { }
153            try { n = Integer.parseInt(args[1]); 
154            } catch (Exception e) { }
155            try { p = Integer.parseInt(args[2]); 
156            } catch (Exception e) { }
157            try { prnt = Boolean.valueOf(args[3]).booleanValue(); 
158            } catch (Exception e) { }
159    
160            MatMult x = new MatMult();
161    
162            MMInf seq    = new SeqMult();
163            MMInf seqb1  = new SeqMultBlock(15);
164            MMInf seqb2  = new SeqMultBlock(20);
165            MMInf seqb3  = new SeqMultBlock(25);
166            MMInf seqt   = new SeqMultTrans();
167            MMInf seqbt  = new SeqMultBlockTrans(20);
168            MMInf seq3   = new SeqMult3();
169            MMInf seq4   = new SeqMult4(30);
170            MMInf par    = new ParMult();
171            MMInf parp   = new ParMultProc(4);
172            MMInf parpb  = new ParMultProcBlock(4,20);
173            MMInf parpb1 = new ParMultProcBlock(4,10);
174            MMInf parpt  = new ParMultProcTrans(4);
175            MMInf parpbt = new ParMultProcBlockTrans(4,20);
176            MMInf con    = new ConMult(4);
177            MMInf conpbt = new ConMultProcBlockTrans(4,20);
178    
179            //double[][] A = x.matgen1(m,p);
180            double[][] A = x.matgen(m,p);
181            double[][] B = x.matgen(p,n);
182            //double[][] B = x.matgen1(p,n);
183            double[][] C  = x.matgen0(m,n);
184            double[][] Cs = x.matgen0(m,n);
185            double[][] D  = x.matgen0(m,n);
186     
187            if (prnt) {
188               System.out.println("A = ");
189               x.matprint(A);
190               System.out.println("");
191            }
192    
193            if (prnt) {
194               System.out.println("B = ");
195               x.matprint(B);
196               System.out.println("");
197            }
198    
199            long tm;
200            tm = System.currentTimeMillis();
201            seq.multiply(C,A,B);
202            tm = System.currentTimeMillis() - tm; 
203            System.out.println(tm + " ms");
204    
205            C = x.matgen0(m,n);
206            tm = System.currentTimeMillis();
207            seqb2.multiply(C,A,B);
208            tm = System.currentTimeMillis() - tm; 
209            System.out.println(tm + " ms");
210    
211            if ( n == p ) {
212               C = x.matgen0(m,n);
213               tm = System.currentTimeMillis();
214               x.transposeInplace(B);
215               seqt.multiply(C,A,B);
216               tm = System.currentTimeMillis() - tm; 
217               System.out.println(tm + " ms");
218               x.transposeInplace(B); // required to count in next case
219    
220               tm = System.currentTimeMillis();
221               x.transposeInplace(B);
222               seqbt.multiply(C,A,B);
223               tm = System.currentTimeMillis() - tm; 
224               System.out.println(tm + " ms");
225    
226    
227            }
228    
229            /* 
230            tm = System.currentTimeMillis();
231            seq4.multiply(C,A,B);
232            tm = System.currentTimeMillis() - tm; 
233            System.out.println(tm + " ms");
234    
235            tm = System.currentTimeMillis();
236            seq3.multiply(C,A,B);
237            tm = System.currentTimeMillis() - tm; 
238            System.out.println(tm + " ms");
239    
240            tm = System.currentTimeMillis();
241            seqb1.multiply(C,A,B);
242            tm = System.currentTimeMillis() - tm; 
243            System.out.println(tm + " ms");
244    
245            tm = System.currentTimeMillis();
246            seqb3.multiply(C,A,B);
247            tm = System.currentTimeMillis() - tm; 
248            System.out.println(tm + " ms");
249            */
250    
251            Cs = (double[][])C.clone();
252    
253            C = x.matgen0(m,n);
254            tm = System.currentTimeMillis();
255            par.multiply(C,A,B);
256            tm = System.currentTimeMillis() - tm; 
257            System.out.println(tm + " ms");
258    
259            tm = System.currentTimeMillis();
260            parp.multiply(C,A,B);
261            tm = System.currentTimeMillis() - tm; 
262            System.out.println(tm + " ms");
263    
264            tm = System.currentTimeMillis();
265            parpb.multiply(C,A,B);
266            tm = System.currentTimeMillis() - tm; 
267            System.out.println(tm + " ms");
268    
269            /*
270            tm = System.currentTimeMillis();
271            parpb1.multiply(C,A,B);
272            tm = System.currentTimeMillis() - tm; 
273            System.out.println(tm + " ms");
274            */
275    
276            if ( n == p ) {
277               tm = System.currentTimeMillis();
278               x.transposeInplace(B);
279               parpt.multiply(C,A,B);
280               tm = System.currentTimeMillis() - tm; 
281               System.out.println(tm + " ms");
282               x.transposeInplace(B); // required to count in next case
283    
284               tm = System.currentTimeMillis();
285               x.transposeInplace(B);
286               parpbt.multiply(C,A,B);
287               tm = System.currentTimeMillis() - tm; 
288               System.out.println(tm + " ms");
289            }
290    
291            tm = System.currentTimeMillis();
292            con.multiply(C,A,B);
293            tm = System.currentTimeMillis() - tm; 
294            System.out.println(tm + " ms");
295            
296            if ( n == p ) {
297               tm = System.currentTimeMillis();
298               x.transposeInplace(B);
299               conpbt.multiply(C,A,B);
300               tm = System.currentTimeMillis() - tm; 
301               System.out.println(tm + " ms");
302            }
303            
304    
305            if (prnt) {
306               System.out.println("Cs = ");
307               x.matprint(Cs);
308               System.out.println("");
309            }
310    
311            if (prnt) {
312               System.out.println("C = ");
313               x.matprint(C);
314               System.out.println("");
315            }
316    
317            x.seqdiff(D,Cs,C); 
318            if (prnt) {
319               System.out.println("D = ");
320               x.matprint(D);
321               System.out.println("");
322            }
323            System.out.println("D is zero = " + x.matcheck0(D) );
324        }
325    
326    }