001
002 /**
003 * Parallel Vector Scalar Multiplication.
004 * @author Heinz Kredel.
005 */
006
007 public class ParVSMult implements VSMInf {
008
009 int anzahl = 1;
010
011 public ParVSMult(int threads) {
012 anzahl = threads;
013 }
014
015
016
017 /**
018 * Compute the scalar multiplication of two vectors.
019 * @param A vector.
020 * @param B vector.
021 */
022 public double multiply(double[] A, double[] B) {
023 Thread[] t = new Thread[anzahl];
024 System.out.print("Starting " + anzahl + " threads ...");
025 DoubleStore c = new DoubleStore(0.0);
026 for (int i=0; i < anzahl; i++) {
027 t[i] = new VSpMult(c,A,B,i,anzahl);
028 t[i].start();
029 }
030 System.out.print(" ... started ...");
031 for (int i=0; i < anzahl; i++) {
032 try { t[i].join(); }
033 catch (InterruptedException e) { }
034 }
035 System.out.println(" ... done");
036 return c.get();
037 }
038
039 /**
040 * Compute the norm of a vector.
041 * @param A vector.
042 */
043 public double norm(double[] A) {
044 Thread[] t = new Thread[anzahl];
045 System.out.print("Starting " + anzahl + " threads ...");
046 DoubleStore c = new DoubleStore(0.0);
047 for (int i=0; i < anzahl; i++) {
048 t[i] = new VSpNorm(c,A,i,anzahl);
049 t[i].start();
050 }
051 System.out.print(" ... started ...");
052 for (int i=0; i < anzahl; i++) {
053 try { t[i].join(); }
054 catch (InterruptedException e) { }
055 }
056 System.out.println(" ... done");
057 return Math.sqrt( c.get() );
058 }
059
060 }
061
062
063 /**
064 * Synchronized storage of a double.
065 */
066 class DoubleStore {
067
068 protected double d = 0.0;
069
070 public DoubleStore(double d) {
071 this.d = d;
072 }
073
074 public synchronized double get() {
075 return d;
076 }
077
078 public synchronized void add(double c) {
079 d += c;
080 }
081
082 }
083
084
085 /**
086 * This class is derived from the class Thread.
087 * It performs a scalar multiplication.
088 */
089 class VSpMult extends Thread {
090
091 double[] A;
092 double[] B;
093 DoubleStore c;
094 int i;
095 int anzahl;
096
097 /**
098 * Constructor.
099 * @param Ap one dimensional matrix.
100 * @param Bp one dimensional matrix.
101 */
102 VSpMult(DoubleStore cp, double[] Ap, double[] Bp, int ip, int a) {
103 A = Ap; B = Bp; c = cp; i = ip; anzahl = a;
104 }
105
106 /**
107 * Runs the multiplication.
108 */
109 public void run() {
110 int schritte = A.length / anzahl;
111 if ( (A.length % anzahl) != 0 ) {
112 schritte++; // ceiling
113 }
114 double s = 0.0;
115 for (int ii = i*schritte; ii < Math.min((i+1)*schritte,Math.min(A.length,B.length)); ii++ ) {
116 s += A[ii] * B[ii];
117 }
118 c.add(s);
119 }
120
121 }
122
123
124 /**
125 * This class is derived from the class Thread.
126 * It performs a scalar multiplication of a part.
127 */
128 class VSpNorm extends Thread {
129
130 double[] A;
131 DoubleStore c;
132 int i;
133 int anzahl;
134
135 /**
136 * Constructor.
137 * @param Ap One dimensional matrix.
138 */
139 VSpNorm(DoubleStore cp, double[] Ap, int ip, int a) {
140 A = Ap; c = cp; i = ip; anzahl = a;
141 }
142
143 /**
144 * Runs the multiplication.
145 */
146 public void run() {
147 int schritte = A.length / anzahl;
148 if ( (A.length % anzahl) != 0 ) {
149 schritte++; // ceiling
150 }
151 double s = 0.0;
152 for (int ii = i*schritte; ii < Math.min((i+1)*schritte,A.length); ii++ ) {
153 s += A[ii] * A[ii];
154 }
155 c.add(s);
156 }
157
158 }