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    }