001 /*
002 * $Id: GCDProxy.java 3222 2010-07-10 14:41:18Z kredel $
003 */
004
005 package edu.jas.ufd;
006
007
008 import java.util.ArrayList;
009 import java.util.List;
010 import java.util.concurrent.Callable;
011 import java.util.concurrent.ExecutionException;
012 import java.util.concurrent.ExecutorService;
013
014 import org.apache.log4j.Logger;
015
016 import edu.jas.kern.ComputerThreads;
017 import edu.jas.kern.PreemptingException;
018 import edu.jas.poly.GenPolynomial;
019 import edu.jas.structure.GcdRingElem;
020
021
022 /**
023 * Greatest common divisor parallel proxy.
024 * @author Heinz Kredel
025 */
026
027 public class GCDProxy<C extends GcdRingElem<C>> extends GreatestCommonDivisorAbstract<C> {
028
029
030 // implements GreatestCommonDivisor<C> {
031
032 private static final Logger logger = Logger.getLogger(GCDProxy.class);
033
034
035 private final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
036
037
038 /**
039 * GCD engines.
040 */
041 public final GreatestCommonDivisorAbstract<C> e1;
042
043
044 public final GreatestCommonDivisorAbstract<C> e2;
045
046
047 /**
048 * Thread pool.
049 */
050 protected ExecutorService pool;
051
052
053 /**
054 * Proxy constructor.
055 */
056 public GCDProxy(GreatestCommonDivisorAbstract<C> e1, GreatestCommonDivisorAbstract<C> e2) {
057 this.e1 = e1;
058 this.e2 = e2;
059 if (pool == null) {
060 pool = ComputerThreads.getPool();
061 //System.out.println("pool 2 = "+pool);
062 }
063 }
064
065
066 /**
067 * Get the String representation with gcd engines.
068 * @see java.lang.Object#toString()
069 */
070 @Override
071 public String toString() {
072 return "GCDProxy[ " + e1.getClass().getName() + ", " + e2.getClass().getName() + " ]";
073 }
074
075
076 /**
077 * Univariate GenPolynomial greatest common divisor. Uses pseudoRemainder for
078 * remainder.
079 * @param P univariate GenPolynomial.
080 * @param S univariate GenPolynomial.
081 * @return gcd(P,S).
082 */
083 @Override
084 public GenPolynomial<C> baseGcd(final GenPolynomial<C> P, final GenPolynomial<C> S) {
085 if ( debug ) {
086 if ( ComputerThreads.NO_THREADS ) {
087 throw new RuntimeException("this should not happen");
088 }
089 }
090 if (S == null || S.isZERO()) {
091 return P;
092 }
093 if (P == null || P.isZERO()) {
094 return S;
095 }
096 // parallel case
097 GenPolynomial<C> g = null;
098 //Callable<GenPolynomial<C>> c0;
099 //Callable<GenPolynomial<C>> c1;
100 List<Callable<GenPolynomial<C>>> cs = new ArrayList<Callable<GenPolynomial<C>>>(2);
101 cs.add(new Callable<GenPolynomial<C>>() {
102
103
104 public GenPolynomial<C> call() {
105 try {
106 //System.out.println("starting e1 " + e1.getClass().getName());
107 GenPolynomial<C> g = e1.baseGcd(P, S);
108 if (debug) {
109 logger.info("GCDProxy done e1 " + e1.getClass().getName());
110 }
111 return g;
112 } catch (PreemptingException e) {
113 throw new RuntimeException("GCDProxy e1 pre " + e);
114 //return P.ring.getONE();
115 } catch (Exception e) {
116 //e.printStackTrace();
117 logger.info("GCDProxy e1 " + e);
118 logger.info("GCDProxy P = " + P);
119 logger.info("GCDProxy S = " + S);
120 throw new RuntimeException("GCDProxy e1 " + e);
121 //return P.ring.getONE();
122 }
123 }
124 });
125 cs.add(new Callable<GenPolynomial<C>>() {
126
127
128 public GenPolynomial<C> call() {
129 try {
130 //System.out.println("starting e2 " + e2.getClass().getName());
131 GenPolynomial<C> g = e2.baseGcd(P, S);
132 if (debug) {
133 logger.info("GCDProxy done e2 " + e2.getClass().getName());
134 }
135 return g;
136 } catch (PreemptingException e) {
137 throw new RuntimeException("GCDProxy e2 pre " + e);
138 //return P.ring.getONE();
139 } catch (Exception e) {
140 //e.printStackTrace();
141 logger.info("GCDProxy e2 " + e);
142 logger.info("GCDProxy P = " + P);
143 logger.info("GCDProxy S = " + S);
144 throw new RuntimeException("GCDProxy e2 " + e);
145 //return P.ring.getONE();
146 }
147 }
148 });
149 try {
150 g = pool.invokeAny(cs);
151 } catch (InterruptedException ignored) {
152 logger.info("InterruptedException " + ignored);
153 Thread.currentThread().interrupt();
154 } catch (ExecutionException e) {
155 logger.info("ExecutionException " + e);
156 Thread.currentThread().interrupt();
157 }
158 return g;
159 }
160
161
162 /**
163 * Univariate GenPolynomial recursive greatest common divisor. Uses
164 * pseudoRemainder for remainder.
165 * @param P univariate recursive GenPolynomial.
166 * @param S univariate recursive GenPolynomial.
167 * @return gcd(P,S).
168 */
169 @Override
170 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateGcd(final GenPolynomial<GenPolynomial<C>> P,
171 final GenPolynomial<GenPolynomial<C>> S) {
172 if ( debug ) {
173 if ( ComputerThreads.NO_THREADS ) {
174 throw new RuntimeException("this should not happen");
175 }
176 }
177 if (S == null || S.isZERO()) {
178 return P;
179 }
180 if (P == null || P.isZERO()) {
181 return S;
182 }
183 // parallel case
184 GenPolynomial<GenPolynomial<C>> g = null;
185 //Callable<GenPolynomial<GenPolynomial<C>>> c0;
186 //Callable<GenPolynomial<GenPolynomial<C>>> c1;
187 List<Callable<GenPolynomial<GenPolynomial<C>>>> cs = new ArrayList<Callable<GenPolynomial<GenPolynomial<C>>>>(
188 2);
189 cs.add(new Callable<GenPolynomial<GenPolynomial<C>>>() {
190
191
192 public GenPolynomial<GenPolynomial<C>> call() {
193 try {
194 GenPolynomial<GenPolynomial<C>> g = e1.recursiveUnivariateGcd(P, S);
195 if (debug) {
196 logger.info("GCDProxy done e1 " + e1.getClass().getName());
197 }
198 return g;
199 } catch (PreemptingException e) {
200 throw new RuntimeException("GCDProxy e1 pre " + e);
201 //return P.ring.getONE();
202 } catch (Exception e) {
203 //e.printStackTrace();
204 logger.info("GCDProxy e1 " + e);
205 logger.info("GCDProxy P = " + P);
206 logger.info("GCDProxy S = " + S);
207 throw new RuntimeException("GCDProxy e1 " + e);
208 //return P.ring.getONE();
209 }
210 }
211 });
212 cs.add(new Callable<GenPolynomial<GenPolynomial<C>>>() {
213
214
215 public GenPolynomial<GenPolynomial<C>> call() {
216 try {
217 GenPolynomial<GenPolynomial<C>> g = e2.recursiveUnivariateGcd(P, S);
218 if (debug) {
219 logger.info("GCDProxy done e2 " + e2.getClass().getName());
220 }
221 return g;
222 } catch (PreemptingException e) {
223 throw new RuntimeException("GCDProxy e2 pre " + e);
224 //return P.ring.getONE();
225 } catch (Exception e) {
226 //e.printStackTrace();
227 logger.info("GCDProxy e2 " + e);
228 logger.info("GCDProxy P = " + P);
229 logger.info("GCDProxy S = " + S);
230 throw new RuntimeException("GCDProxy e2 " + e);
231 //return P.ring.getONE();
232 }
233 }
234 });
235 try {
236 g = pool.invokeAny(cs);
237 } catch (InterruptedException ignored) {
238 logger.info("InterruptedException " + ignored);
239 Thread.currentThread().interrupt();
240 } catch (ExecutionException e) {
241 logger.info("ExecutionException " + e);
242 Thread.currentThread().interrupt();
243 }
244 return g;
245 }
246
247
248 /**
249 * GenPolynomial greatest common divisor. Main entry driver method.
250 * @param P GenPolynomial.
251 * @param S GenPolynomial.
252 * @return gcd(P,S).
253 */
254 @Override
255 public GenPolynomial<C> gcd(final GenPolynomial<C> P, final GenPolynomial<C> S) {
256 if ( debug ) {
257 if ( ComputerThreads.NO_THREADS ) {
258 throw new RuntimeException("this should not happen");
259 }
260 }
261 if (S == null || S.isZERO()) {
262 return P;
263 }
264 if (P == null || P.isZERO()) {
265 return S;
266 }
267 // parallel case
268 GenPolynomial<C> g = null;
269 //Callable<GenPolynomial<C>> c0;
270 //Callable<GenPolynomial<C>> c1;
271 List<Callable<GenPolynomial<C>>> cs = new ArrayList<Callable<GenPolynomial<C>>>(2);
272 cs.add(new Callable<GenPolynomial<C>>() {
273
274
275 public GenPolynomial<C> call() {
276 try {
277 //System.out.println("starting e1 " + e1.getClass().getName());
278 GenPolynomial<C> g = e1.gcd(P, S);
279 if (debug) {
280 logger.info("GCDProxy done e1 " + e1.getClass().getName());
281 }
282 return g;
283 } catch (PreemptingException e) {
284 throw new RuntimeException("GCDProxy e1 pre " + e);
285 //return P.ring.getONE();
286 } catch (Exception e) {
287 //e.printStackTrace();
288 logger.info("GCDProxy e1 " + e);
289 logger.info("GCDProxy P = " + P);
290 logger.info("GCDProxy S = " + S);
291 throw new RuntimeException("GCDProxy e1 " + e);
292 //return P.ring.getONE();
293 }
294 }
295 });
296 cs.add(new Callable<GenPolynomial<C>>() {
297
298
299 public GenPolynomial<C> call() {
300 try {
301 //System.out.println("starting e2 " + e2.getClass().getName());
302 GenPolynomial<C> g = e2.gcd(P, S);
303 if (debug) {
304 logger.info("GCDProxy done e2 " + e2.getClass().getName());
305 }
306 return g;
307 } catch (PreemptingException e) {
308 throw new RuntimeException("GCDProxy e2 pre " + e);
309 //return P.ring.getONE();
310 } catch (Exception e) {
311 //e.printStackTrace();
312 logger.info("GCDProxy e2 " + e);
313 logger.info("GCDProxy P = " + P);
314 logger.info("GCDProxy S = " + S);
315 throw new RuntimeException("GCDProxy e2 " + e);
316 //return P.ring.getONE();
317 }
318 }
319 });
320 try {
321 g = pool.invokeAny(cs);
322 } catch (InterruptedException ignored) {
323 logger.info("InterruptedException " + ignored);
324 Thread.currentThread().interrupt();
325 } catch (ExecutionException e) {
326 logger.info("ExecutionException " + e);
327 Thread.currentThread().interrupt();
328 }
329 return g;
330 }
331
332 }