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 }