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 }