001/* 002 * $Id: SGCDFactory.java 5502 2016-05-12 21:58:10Z kredel $ 003 */ 004 005package edu.jas.fd; 006 007 008import org.apache.log4j.Logger; 009 010import edu.jas.arith.BigInteger; 011import edu.jas.arith.BigRational; 012import edu.jas.arith.ModInteger; 013import edu.jas.arith.ModIntegerRing; 014import edu.jas.arith.ModLong; 015import edu.jas.arith.ModLongRing; 016import edu.jas.kern.ComputerThreads; 017import edu.jas.structure.GcdRingElem; 018import edu.jas.structure.RingFactory; 019 020 021/** 022 * Solvable greatest common divisor algorithms factory. Select appropriate SGCD 023 * engine based on the coefficient types. 024 * @author Heinz Kredel 025 * @usage To create objects that implement the 026 * <code>GreatestCommonDivisor</code> interface use the 027 * <code>GCDFactory</code>. It will select an appropriate implementation 028 * based on the types of polynomial coefficients C. There are two methods 029 * to obtain an implementation: <code>getProxy()</code> and 030 * <code>getImplementation()</code>. <code>getImplementation()</code> 031 * returns an object of a class which implements the 032 * <code>GreatestCommonDivisor</code> interface. <code>getProxy()</code> 033 * returns a proxy object of a class which implements the 034 * <code>GreatestCommonDivisor</code> interface. The proxy will run two 035 * implementations in parallel, return the first computed result and 036 * cancel the second running task. On systems with one CPU the computing 037 * time will be two times the time of the fastest algorithm 038 * implementation. On systems with more than two CPUs the computing time 039 * will be the time of the fastest algorithm implementation. 040 * 041 * <pre> 042 * GreatestCommonDivisor<CT> engine; 043 * engine = SGCDFactory.<CT> getImplementation(cofac); 044 * or engine = SGCDFactory.<CT> getProxy(cofac); 045 * c = engine.leftGcd(a, b); 046 * </pre> 047 * 048 * For example, if the coefficient type is <code>BigInteger</code>, the 049 * usage looks like 050 * 051 * <pre> 052 * BigInteger cofac = new BigInteger(); 053 * GreatestCommonDivisor<BigInteger> engine; 054 * engine = SGCDFactory.getImplementation(cofac); 055 * or engine = SGCDFactory.getProxy(cofac); 056 * c = engine.leftGcd(a, b); 057 * </pre> 058 * 059 * @see edu.jas.fd.GreatestCommonDivisor#leftGcd(edu.jas.poly.GenSolvablePolynomial 060 * P, edu.jas.poly.GenSolvablePolynomial S) 061 */ 062 063public class SGCDFactory { 064 065 066 private static final Logger logger = Logger.getLogger(SGCDFactory.class); 067 068 069 /** 070 * Protected factory constructor. 071 */ 072 protected SGCDFactory() { 073 } 074 075 076 /** 077 * Determine suitable implementation of gcd algorithms, case ModLong. 078 * @param fac ModLongRing. 079 * @return gcd algorithm implementation. 080 */ 081 public static GreatestCommonDivisorAbstract<ModLong> getImplementation(ModLongRing fac) { 082 GreatestCommonDivisorAbstract<ModLong> ufd; 083 if (fac.isField()) { 084 ufd = new GreatestCommonDivisorSimple<ModLong>(fac); 085 return ufd; 086 } 087 ufd = new GreatestCommonDivisorPrimitive<ModLong>(fac); 088 return ufd; 089 } 090 091 092 /** 093 * Determine suitable proxy for gcd algorithms, case ModLong. 094 * @param fac ModLongRing. 095 * @return gcd algorithm implementation. 096 */ 097 public static GreatestCommonDivisorAbstract<ModLong> getProxy(ModLongRing fac) { 098 GreatestCommonDivisorAbstract<ModLong> ufd1, ufd2; 099 ufd1 = new GreatestCommonDivisorPrimitive<ModLong>(fac); 100 if (fac.isField()) { 101 ufd2 = new GreatestCommonDivisorSimple<ModLong>(fac); 102 } else { 103 ufd2 = new GreatestCommonDivisorSyzygy<ModLong>(fac); 104 } 105 return new SGCDParallelProxy<ModLong>(fac, ufd1, ufd2); 106 } 107 108 109 /** 110 * Determine suitable implementation of gcd algorithms, case ModInteger. 111 * @param fac ModIntegerRing. 112 * @return gcd algorithm implementation. 113 */ 114 public static GreatestCommonDivisorAbstract<ModInteger> getImplementation(ModIntegerRing fac) { 115 GreatestCommonDivisorAbstract<ModInteger> ufd; 116 if (fac.isField()) { 117 ufd = new GreatestCommonDivisorSimple<ModInteger>(fac); 118 return ufd; 119 } 120 ufd = new GreatestCommonDivisorPrimitive<ModInteger>(fac); 121 return ufd; 122 } 123 124 125 /** 126 * Determine suitable proxy for gcd algorithms, case ModInteger. 127 * @param fac ModIntegerRing. 128 * @return gcd algorithm implementation. 129 */ 130 public static GreatestCommonDivisorAbstract<ModInteger> getProxy(ModIntegerRing fac) { 131 GreatestCommonDivisorAbstract<ModInteger> ufd1, ufd2; 132 ufd1 = new GreatestCommonDivisorPrimitive<ModInteger>(fac); 133 if (fac.isField()) { 134 ufd2 = new GreatestCommonDivisorSimple<ModInteger>(fac); 135 } else { 136 ufd2 = new GreatestCommonDivisorSyzygy<ModInteger>(fac); 137 } 138 return new SGCDParallelProxy<ModInteger>(fac, ufd1, ufd2); 139 } 140 141 142 /** 143 * Determine suitable implementation of gcd algorithms, case BigInteger. 144 * @param fac BigInteger. 145 * @return gcd algorithm implementation. 146 */ 147 @SuppressWarnings("unused") 148 public static GreatestCommonDivisorAbstract<BigInteger> getImplementation(BigInteger fac) { 149 GreatestCommonDivisorAbstract<BigInteger> ufd; 150 if (true) { 151 ufd = new GreatestCommonDivisorPrimitive<BigInteger>(fac); 152 } else { 153 ufd = new GreatestCommonDivisorSimple<BigInteger>(fac); 154 } 155 return ufd; 156 } 157 158 159 /** 160 * Determine suitable proxy for gcd algorithms, case BigInteger. 161 * @param fac BigInteger. 162 * @return gcd algorithm implementation. 163 */ 164 public static GreatestCommonDivisorAbstract<BigInteger> getProxy(BigInteger fac) { 165 if (fac == null) { 166 throw new IllegalArgumentException("fac == null not supported"); 167 } 168 GreatestCommonDivisorAbstract<BigInteger> ufd1, ufd2; 169 ufd1 = new GreatestCommonDivisorPrimitive<BigInteger>(fac); 170 ufd2 = new GreatestCommonDivisorSyzygy<BigInteger>(fac); 171 return new SGCDParallelProxy<BigInteger>(fac, ufd1, ufd2); 172 } 173 174 175 /** 176 * Determine suitable implementation of gcd algorithms, case BigRational. 177 * @param fac BigRational. 178 * @return gcd algorithm implementation. 179 */ 180 public static GreatestCommonDivisorAbstract<BigRational> getImplementation(BigRational fac) { 181 if (fac == null) { 182 throw new IllegalArgumentException("fac == null not supported"); 183 } 184 GreatestCommonDivisorAbstract<BigRational> ufd; 185 ufd = new GreatestCommonDivisorPrimitive<BigRational>(fac); 186 return ufd; 187 } 188 189 190 /** 191 * Determine suitable proxy for gcd algorithms, case BigRational. 192 * @param fac BigRational. 193 * @return gcd algorithm implementation. 194 */ 195 public static GreatestCommonDivisorAbstract<BigRational> getProxy(BigRational fac) { 196 if (fac == null) { 197 throw new IllegalArgumentException("fac == null not supported"); 198 } 199 GreatestCommonDivisorAbstract<BigRational> ufd1, ufd2; 200 ufd1 = new GreatestCommonDivisorPrimitive<BigRational>(fac); 201 ufd2 = new GreatestCommonDivisorSimple<BigRational>(fac); 202 return new SGCDParallelProxy<BigRational>(fac, ufd1, ufd2); 203 } 204 205 206 /** 207 * Determine suitable implementation of gcd algorithms, other cases. 208 * @param fac RingFactory<C>. 209 * @return gcd algorithm implementation. 210 */ 211 @SuppressWarnings("unchecked") 212 public static <C extends GcdRingElem<C>> GreatestCommonDivisorAbstract<C> getImplementation( 213 RingFactory<C> fac) { 214 GreatestCommonDivisorAbstract/*raw type<C>*/ ufd; 215 logger.debug("fac = " + fac.getClass().getName()); 216 Object ofac = fac; 217 if (ofac instanceof BigInteger) { 218 ufd = new GreatestCommonDivisorPrimitive<C>(fac); 219 } else if (ofac instanceof ModIntegerRing) { 220 if (fac.isField()) { 221 ufd = new GreatestCommonDivisorSimple<C>(fac); 222 } else { 223 ufd = new GreatestCommonDivisorPrimitive<C>(fac); 224 } 225 } else if (ofac instanceof ModLongRing) { 226 if (fac.isField()) { 227 ufd = new GreatestCommonDivisorSimple<C>(fac); 228 } else { 229 ufd = new GreatestCommonDivisorPrimitive<C>(fac); 230 } 231 } else if (ofac instanceof BigRational) { 232 ufd = new GreatestCommonDivisorSimple<C>(fac); 233 } else { 234 if (fac.isField()) { 235 ufd = new GreatestCommonDivisorSimple<C>(fac); 236 } else { 237 ufd = new GreatestCommonDivisorPrimitive<C>(fac); 238 } 239 } 240 logger.debug("implementation = " + ufd); 241 return ufd; 242 } 243 244 245 /** 246 * Determine suitable proxy for gcd algorithms, other cases. 247 * @param fac RingFactory<C>. 248 * @return gcd algorithm implementation. <b>Note:</b> This method contains a 249 * hack for Google app engine to not use threads. 250 * @see edu.jas.kern.ComputerThreads#NO_THREADS 251 */ 252 @SuppressWarnings("unchecked") 253 public static <C extends GcdRingElem<C>> GreatestCommonDivisorAbstract<C> getProxy(RingFactory<C> fac) { 254 if (ComputerThreads.NO_THREADS) { // hack for Google app engine 255 return SGCDFactory.<C> getImplementation(fac); 256 } 257 GreatestCommonDivisorAbstract/*raw type<C>*/ ufd; 258 logger.debug("fac = " + fac.getClass().getName()); 259 Object ofac = fac; 260 if (ofac instanceof BigInteger) { 261 ufd = new SGCDParallelProxy<C>(fac, new GreatestCommonDivisorSimple<C>(fac), 262 new GreatestCommonDivisorPrimitive<C>(fac)); 263 } else if (ofac instanceof ModIntegerRing) { 264 ufd = new SGCDParallelProxy<C>(fac, new GreatestCommonDivisorSimple<C>(fac), 265 new GreatestCommonDivisorPrimitive<C>(fac)); 266 } else if (ofac instanceof ModLongRing) { 267 ufd = new SGCDParallelProxy<C>(fac, new GreatestCommonDivisorSimple<C>(fac), 268 new GreatestCommonDivisorPrimitive<C>(fac)); 269 } else if (ofac instanceof BigRational) { 270 ufd = new SGCDParallelProxy<C>(fac, new GreatestCommonDivisorPrimitive<C>(fac), 271 new GreatestCommonDivisorSimple<C>(fac)); 272 } else { 273 if (fac.isField()) { 274 ufd = new SGCDParallelProxy<C>(fac, new GreatestCommonDivisorSimple<C>(fac), 275 new GreatestCommonDivisorPrimitive<C>(fac)); 276 } else { 277 ufd = new SGCDParallelProxy<C>(fac, new GreatestCommonDivisorSyzygy<C>(fac), 278 new GreatestCommonDivisorPrimitive<C>(fac)); 279 } 280 } 281 logger.debug("ufd = " + ufd); 282 return ufd; 283 } 284 285}