KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > LU


1
2 import EDU.oswego.cs.dl.util.concurrent.*;
3
4 /**
5  * LU matrix decomposition demo
6  * Based on those in Cilk and Hood
7  **/

8
9 public class LU {
10
11   // granularity is hard-wired as compile-time constant here
12
static final int BLOCK_SIZE = 16;
13
14   static final boolean CHECK = false; // set true to check answer
15

16   public static void main(String JavaDoc[] args) {
17
18     final String JavaDoc usage = "Usage: java LU <threads> <matrix size (must be a power of two)> [runs] \n For example, try java LU 2 512";
19
20     try {
21       int procs;
22       int n;
23       int runs = 1;
24       try {
25         procs = Integer.parseInt(args[0]);
26         n = Integer.parseInt(args[1]);
27         if (args.length > 2) runs = Integer.parseInt(args[2]);
28
29       }
30
31       catch (Exception JavaDoc e) {
32         System.out.println(usage);
33         return;
34       }
35
36       if ( ((n & (n - 1)) != 0)) {
37         System.out.println(usage);
38         return;
39       }
40
41       for (int run = 0; run < runs; ++run) {
42         
43         double[][] m = new double[n][n];
44         randomInit(m, n);
45         
46         
47         double[][] copy = null;
48         if (CHECK) {
49           copy = new double[n][n];
50           for (int i = 0; i < n; ++i) {
51             for (int j = 0; j < n; ++j) {
52               copy[i][j] = m[i][j];
53             }
54           }
55         }
56         
57         Block M = new Block(m, 0, 0);
58         
59         FJTaskRunnerGroup g = new FJTaskRunnerGroup(procs);
60         g.invoke(new LowerUpper(n, M));
61         g.stats();
62         g.interruptAll();
63         if (CHECK) check(m, copy, n);
64       }
65     }
66     catch (InterruptedException JavaDoc ex) {}
67   }
68
69
70   static void randomInit(double[][] M, int n) {
71
72     java.util.Random JavaDoc rng = new java.util.Random JavaDoc();
73
74     for (int i = 0; i < n; ++i)
75       for (int j = 0; j < n; ++j)
76         M[i][j] = rng.nextDouble();
77
78     // for compatibility with hood demo, force larger diagonals
79
for (int k = 0; k < n; ++k)
80       M[k][k] *= 10.0;
81   }
82
83   static void check(double[][] LU, double[][] M, int n) {
84
85     double maxDiff = 0.0; // track max difference
86

87     for (int i = 0; i < n; ++i) {
88       for (int j = 0; j < n; ++j) {
89         double v = 0.0;
90         int k;
91         for (k = 0; k < i && k <= j; k++ ) v += LU[i][k] * LU[k][j];
92         if (k == i && k <= j ) v += LU[k][j];
93         double diff = M[i][j] - v;
94         if (diff < 0) diff = -diff;
95         if (diff > 0.001) {
96           System.out.println("large diff at[" + i + "," + j + "]: " + M[i][j] + " vs " + v);
97         }
98         if (diff > maxDiff) maxDiff = diff;
99       }
100     }
101
102     System.out.println("Max difference = " + maxDiff);
103   }
104
105
106   // Blocks record underlying matrix, and offsets into current block
107
static class Block {
108     final double[][] m;
109     final int loRow;
110     final int loCol;
111
112     Block(double[][] mat, int lr, int lc) {
113       m = mat; loRow = lr; loCol = lc;
114     }
115   }
116
117   static class Schur extends FJTask {
118     final int size;
119     final Block V;
120     final Block W;
121     final Block M;
122
123     Schur(int size, Block V, Block W, Block M) {
124       this.size = size; this.V = V; this.W = W; this.M = M;
125     }
126
127     void schur() { // base case
128
for (int j = 0; j < BLOCK_SIZE; ++j) {
129         for (int i = 0; i < BLOCK_SIZE; ++i) {
130           double s = M.m[i+M.loRow][j+M.loCol];
131           for (int k = 0; k < BLOCK_SIZE; ++k) {
132             s -= V.m[i+V.loRow][k+V.loCol] * W.m[k+W.loRow][j+W.loCol];
133           }
134           M.m[i+M.loRow][j+M.loCol] = s;
135         }
136       }
137     }
138
139     public void run() {
140       if (size == BLOCK_SIZE) {
141         schur();
142       }
143       else {
144         int h = size / 2;
145
146         Block M00 = new Block(M.m, M.loRow, M.loCol);
147         Block M01 = new Block(M.m, M.loRow, M.loCol+h);
148         Block M10 = new Block(M.m, M.loRow+h, M.loCol);
149         Block M11 = new Block(M.m, M.loRow+h, M.loCol+h);
150
151         Block V00 = new Block(V.m, V.loRow, V.loCol);
152         Block V01 = new Block(V.m, V.loRow, V.loCol+h);
153         Block V10 = new Block(V.m, V.loRow+h, V.loCol);
154         Block V11 = new Block(V.m, V.loRow+h, V.loCol+h);
155
156         Block W00 = new Block(W.m, W.loRow, W.loCol);
157         Block W01 = new Block(W.m, W.loRow, W.loCol+h);
158         Block W10 = new Block(W.m, W.loRow+h, W.loCol);
159         Block W11 = new Block(W.m, W.loRow+h, W.loCol+h);
160         
161         coInvoke(new FJTask[] {
162           seq(new Schur(h, V00, W00, M00),
163               new Schur(h, V01, W10, M00)),
164           seq(new Schur(h, V00, W01, M01),
165               new Schur(h, V01, W11, M01)),
166           seq(new Schur(h, V10, W00, M10),
167               new Schur(h, V11, W10, M10)),
168           seq(new Schur(h, V10, W01, M11),
169               new Schur(h, V11, W11, M11))
170         });
171           
172       }
173     }
174   }
175
176   static class Lower extends FJTask {
177
178     final int size;
179     final Block L;
180     final Block M;
181
182     Lower(int size, Block L, Block M) {
183       this.size = size; this.L = L; this.M = M;
184     }
185
186
187     void lower() { // base case
188
for (int i = 1; i < BLOCK_SIZE; ++i) {
189         for (int k = 0; k < i; ++k) {
190           double a = L.m[i+L.loRow][k+L.loCol];
191           double[] x = M.m[k+M.loRow];
192           double[] y = M.m[i+M.loRow];
193           int n = BLOCK_SIZE;
194           for (int p = n-1; p >= 0; --p) {
195             y[p+M.loCol] -= a * x[p+M.loCol];
196           }
197         }
198       }
199     }
200
201     public void run() {
202       if (size == BLOCK_SIZE) {
203         lower();
204       }
205       else {
206         int h = size / 2;
207
208         Block M00 = new Block(M.m, M.loRow, M.loCol);
209         Block M01 = new Block(M.m, M.loRow, M.loCol+h);
210         Block M10 = new Block(M.m, M.loRow+h, M.loCol);
211         Block M11 = new Block(M.m, M.loRow+h, M.loCol+h);
212
213         Block L00 = new Block(L.m, L.loRow, L.loCol);
214         Block L01 = new Block(L.m, L.loRow, L.loCol+h);
215         Block L10 = new Block(L.m, L.loRow+h, L.loCol);
216         Block L11 = new Block(L.m, L.loRow+h, L.loCol+h);
217
218         coInvoke(
219                  new Seq(new FJTask[] {
220                    new Lower(h, L00, M00),
221                    new Schur(h, L10, M00, M10),
222                    new Lower(h, L11, M10)
223                  }),
224                  new Seq(new FJTask[] {
225                    new Lower(h, L00, M01),
226                    new Schur(h, L10, M01, M11),
227                    new Lower(h, L11, M11)
228                  })
229                  );
230       }
231     }
232   }
233
234
235   static class Upper extends FJTask {
236
237     final int size;
238     final Block U;
239     final Block M;
240
241     Upper(int size, Block U, Block M) {
242       this.size = size; this.U = U; this.M = M;
243     }
244
245     void upper() { // base case
246
for (int i = 0; i < BLOCK_SIZE; ++i) {
247         for (int k = 0; k < BLOCK_SIZE; ++k) {
248           double a = M.m[i+M.loRow][k+M.loCol] / U.m[k+U.loRow][k+U.loCol];
249           M.m[i+M.loRow][k+M.loCol] = a;
250           double[] x = U.m[k+U.loRow];
251           double[] y = M.m[i+M.loRow];
252           int n = BLOCK_SIZE - k - 1;
253           for (int p = n - 1; p >= 0; --p) {
254             y[p+k+1+M.loCol] -= a * x[p+k+1+U.loCol];
255           }
256         }
257       }
258     }
259
260
261     public void run() {
262       if (size == BLOCK_SIZE) {
263         upper();
264       }
265       else {
266         int h = size / 2;
267
268         Block M00 = new Block(M.m, M.loRow, M.loCol);
269         Block M01 = new Block(M.m, M.loRow, M.loCol+h);
270         Block M10 = new Block(M.m, M.loRow+h, M.loCol);
271         Block M11 = new Block(M.m, M.loRow+h, M.loCol+h);
272
273         Block U00 = new Block(U.m, U.loRow, U.loCol);
274         Block U01 = new Block(U.m, U.loRow, U.loCol+h);
275         Block U10 = new Block(U.m, U.loRow+h, U.loCol);
276         Block U11 = new Block(U.m, U.loRow+h, U.loCol+h);
277
278         coInvoke(
279                  new Seq(new FJTask[] {
280                    new Upper(h, U00, M00),
281                    new Schur(h, M00, U01, M01),
282                    new Upper(h, U11, M01)
283                  }),
284                  new Seq(new FJTask[] {
285                    new Upper(h, U00, M10),
286                    new Schur(h, M10, U01, M11),
287                    new Upper(h, U11, M11)
288                  })
289                  );
290       }
291     }
292   }
293     
294
295   static class LowerUpper extends FJTask {
296
297     final int size;
298     final Block M;
299
300     LowerUpper(int size, Block M) {
301       this.size = size; this.M = M;
302     }
303
304     void lu() { // base case
305
for (int k = 0; k < BLOCK_SIZE; ++k) {
306         for (int i = k+1; i < BLOCK_SIZE; ++i) {
307           double b = M.m[k+M.loRow][k+M.loCol];
308           double a = M.m[i+M.loRow][k+M.loCol] / b;
309           M.m[i+M.loRow][k+M.loCol] = a;
310           double[] x = M.m[k+M.loRow];
311           double[] y = M.m[i+M.loRow];
312           int n = BLOCK_SIZE-k-1;
313           for (int p = n-1; p >= 0; --p) {
314             y[k+1+p+M.loCol] -= a * x[k+1+p+M.loCol];
315           }
316         }
317       }
318     }
319
320     public void run() {
321       if (size == BLOCK_SIZE) {
322         lu();
323       }
324       else {
325         int h = size / 2;
326
327         Block M00 = new Block(M.m, M.loRow, M.loCol);
328         Block M01 = new Block(M.m, M.loRow, M.loCol+h);
329         Block M10 = new Block(M.m, M.loRow+h, M.loCol);
330         Block M11 = new Block(M.m, M.loRow+h, M.loCol+h);
331
332         
333         invoke(new LowerUpper(h, M00));
334
335         coInvoke(new Lower(h, M00, M01),
336                  new Upper(h, M00, M10));
337
338         invoke(new Schur(h, M10, M01, M11));
339
340         invoke(new LowerUpper(h, M11));
341
342       }
343     }
344   }
345 }
346   
347
Popular Tags