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 }