// simeq_thread.java multiple threads with await() // construct with desired number of threads // then execute with choice of simeq arguments // solve real linear equations for X where Y = A * X // method: Gauss-Jordan elimination using maximum pivot // usage: simeq(A,Y,X); or simeq(n,A,Y,X) // First written by Jon Squire December 1959 for IBM 650, translated to // other languages e.g. Fortran converted to Ada converted to C // then converted to java, then threads August 2009 // // use: simeq_thread ST = new simeq_thread(8); number of threads // ST.simeq(A,X,Y); or ST.simeq(n,A,X,Y) etc. import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class simeq_thread { int nthreads; // obviously, the number of threads Thread t[]; // threads double pivots[]; // index is thread id, largest diagonal int ipivots[]; // index is thread id, index of largest diagonal int i1[]; // index is thread id, starting row in row[] int i2[]; // index is thread id, ending row+1 in row[] CyclicBarrier barrier; // for nthreads int n; // number of linear equations double B[][]; // n rows, n+1 columns, column n+1 is Y double X[]; // computed solution int row[]; // index of permuted row interchange double gpivot; // global pivot value int igpivot; // index of row that has global pivot simeq_thread(int nthreads) { System.out.println("simeq_thread running with nthreads="+nthreads); this.nthreads = nthreads; t = new Thread[nthreads]; pivots = new double[nthreads]; ipivots = new int[nthreads]; i1 = new int[nthreads]; i2 = new int[nthreads]; } // end simeq_thread that set number of threads public void simeq(final double A[][], final double Y[], double X[]) { n = A.length; B = new double[n][n+1]; // working matrix this.X = X; if(A[0].length!=n || Y.length!=n || X.length!=n) { System.out.println("Error in simeq, inconsistent array sizes."); } // build working data structure for(int i=0; in) i2[i] = n; else i2[i] = j+inc; // < ending row j = j+inc; if((nthreads-i-1)*(inc-1)+j>=n) inc--; // at most once and last } // create and start the threads Interchanger interchange = new Interchanger(); barrier = new CyclicBarrier(nthreads, interchange); for(int i=0; i=k && Math.abs(B[row[i]][k]) > abs_pivot) { I_pivot = i; abs_pivot = Math.abs(B[row[i]][k]); } } // have pivot, interchange row indicies pivots[id] = abs_pivot; ipivots[id] = I_pivot; barrier.await(); // let interchanger do interchange // inner reduction loop for(int i=i1[id]; igpivot) { igpivot =ipivots[i]; // from tsolve threads gpivot = pivots[i]; // from tsolve threads } } if(igpivot<0 || gpivot < 0.0) { System.out.println("simeq_thread.java internal error"); System.out.println("n="+n+", nthreads="+nthreads); System.out.println("k="+k+", igpivot="+igpivot+", gpivot="+gpivot); // System.exit(1); } hold = row[k]; row[k] = row[igpivot]; row[igpivot] = hold; // check for near singular if(gpivot < 1.0E-15) { for(int j=k+1; jn simeq_thread.java internal error"); } } // end interchanger run() } // end class Interchanger } // end class simeq_thread