001 /* 002 * $Id: SquarefreeFactory.java 3356 2010-10-23 16:41:01Z kredel $ 003 */ 004 005 package edu.jas.ufd; 006 007 008 import org.apache.log4j.Logger; 009 010 import edu.jas.arith.BigInteger; 011 import edu.jas.arith.BigRational; 012 import edu.jas.arith.ModInteger; 013 import edu.jas.arith.ModIntegerRing; 014 import edu.jas.arith.ModLong; 015 import edu.jas.arith.ModLongRing; 016 import edu.jas.poly.AlgebraicNumber; 017 import edu.jas.poly.AlgebraicNumberRing; 018 import edu.jas.poly.GenPolynomialRing; 019 import edu.jas.structure.GcdRingElem; 020 import edu.jas.structure.RingFactory; 021 022 023 /** 024 * Squarefree factorization algorithms factory. Select appropriate squarefree 025 * factorization engine based on the coefficient types. 026 * @author Heinz Kredel 027 * @usage To create objects that implement the <code>Squarefree</code> interface 028 * use the <code>SquarefreeFactory</code>. It will select an appropriate 029 * implementation based on the types of polynomial coefficients C. To 030 * obtain an implementation use <code>getImplementation()</code>, it 031 * returns an object of a class which extends the 032 * <code>SquarefreeAbstract</code> class which implements the 033 * <code>Squarefree</code> interface. 034 * 035 * <pre> 036 * Squarefree<CT> engine; 037 * engine = SquarefreeFactory.<CT> getImplementation(cofac); 038 * c = engine.squarefreeFactors(a); 039 * </pre> 040 * 041 * For example, if the coefficient type is BigInteger, the usage looks 042 * like 043 * 044 * <pre> 045 * BigInteger cofac = new BigInteger(); 046 * Squarefree<BigInteger> engine; 047 * engine = SquarefreeFactory.getImplementation(cofac); 048 * Sm = engine.sqaurefreeFactors(poly); 049 * </pre> 050 * 051 * @see edu.jas.ufd.Squarefree#squarefreeFactors(edu.jas.poly.GenPolynomial P) 052 */ 053 054 public class SquarefreeFactory { 055 056 057 private static final Logger logger = Logger.getLogger(SquarefreeFactory.class); 058 059 060 /** 061 * Protected factory constructor. 062 */ 063 protected SquarefreeFactory() { 064 } 065 066 067 /** 068 * Determine suitable implementation of factorization algorithm, case 069 * ModInteger. 070 * @param fac ModIntegerRing. 071 * @return squarefree factorization algorithm implementation. 072 */ 073 public static SquarefreeAbstract<ModInteger> getImplementation(ModIntegerRing fac) { 074 return new SquarefreeFiniteFieldCharP<ModInteger>(fac); 075 } 076 077 078 /** 079 * Determine suitable implementation of factorization algorithm, case 080 * ModLong. 081 * @param fac ModLongRing. 082 * @return squarefree factorization algorithm implementation. 083 */ 084 public static SquarefreeAbstract<ModLong> getImplementation(ModLongRing fac) { 085 return new SquarefreeFiniteFieldCharP<ModLong>(fac); 086 } 087 088 089 /** 090 * Determine suitable implementation of squarefree factorization algorithm, 091 * case BigInteger. 092 * @param fac BigInteger. 093 * @return squarefree factorization algorithm implementation. 094 */ 095 public static SquarefreeAbstract<BigInteger> getImplementation(BigInteger fac) { 096 return new SquarefreeRingChar0<BigInteger>(fac); 097 } 098 099 100 /** 101 * Determine suitable implementation of squarefree factorization algorithms, 102 * case BigRational. 103 * @param fac BigRational. 104 * @return squarefree factorization algorithm implementation. 105 */ 106 public static SquarefreeAbstract<BigRational> getImplementation(BigRational fac) { 107 return new SquarefreeFieldChar0<BigRational>(fac); 108 } 109 110 111 /** 112 * Determine suitable implementation of squarefree factorization algorithms, 113 * case AlgebraicNumber<C>. 114 * @param fac AlgebraicNumberRing<C>. 115 * @param <C> coefficient type, e.g. BigRational, ModInteger. 116 * @return squarefree factorization algorithm implementation. 117 */ 118 public static <C extends GcdRingElem<C>> SquarefreeAbstract<AlgebraicNumber<C>> getImplementation( 119 AlgebraicNumberRing<C> fac) { 120 PolyUfdUtil.<C> ensureFieldProperty(fac); 121 if (fac.isField()) { 122 if (fac.characteristic().signum() == 0) { 123 return new SquarefreeFieldChar0<AlgebraicNumber<C>>(fac); 124 } else { 125 if (fac.isFinite()) { 126 return new SquarefreeFiniteFieldCharP<AlgebraicNumber<C>>(fac); 127 } else { 128 return new SquarefreeInfiniteAlgebraicFieldCharP<C>(fac); 129 //throw new RuntimeException("algebraic extension of infinite not implemented" 130 // + fac.getClass().getName()); 131 } 132 } 133 } else { 134 throw new ArithmeticException("eventually no integral domain " + fac.getClass().getName()); 135 } 136 } 137 138 139 /** 140 * Determine suitable implementation of squarefree factorization algorithms, 141 * case Quotient<C>. 142 * @param fac QuotientRing<C>. 143 * @param <C> coefficient type, e.g. BigRational, ModInteger. 144 * @return squarefree factorization algorithm implementation. 145 */ 146 public static <C extends GcdRingElem<C>> SquarefreeAbstract<Quotient<C>> getImplementation( 147 QuotientRing<C> fac) { 148 if (fac.characteristic().signum() == 0) { 149 return new SquarefreeFieldChar0<Quotient<C>>(fac); 150 } else { 151 return new SquarefreeInfiniteFieldCharP<C>(fac); 152 } 153 } 154 155 156 /** 157 * Determine suitable implementation of squarefree factorization algorithms, 158 * case GenPolynomial<C>. 159 * @param fac GenPolynomialRing<C>. 160 * @param <C> coefficient type, e.g. BigRational, ModInteger. 161 * @return squarefree factorization algorithm implementation. 162 */ 163 public static <C extends GcdRingElem<C>> SquarefreeAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 164 return getImplementationPoly(fac); 165 } 166 167 168 /* 169 * Determine suitable implementation of squarefree factorization algorithms, 170 * case GenPolynomial<C>. 171 * @param fac GenPolynomialRing<C>. 172 * @param <C> coefficient type, e.g. BigRational, ModInteger. 173 * @return squarefree factorization algorithm implementation. 174 */ 175 protected static <C extends GcdRingElem<C>> SquarefreeAbstract<C> getImplementationPoly( 176 GenPolynomialRing<C> fac) { 177 if (fac.characteristic().signum() == 0) { 178 if (fac.coFac.isField()) { 179 return new SquarefreeFieldChar0<C>(fac.coFac); 180 } else { 181 return new SquarefreeRingChar0<C>(fac.coFac); 182 } 183 } else { 184 if (fac.coFac.isFinite()) { 185 return new SquarefreeFiniteFieldCharP<C>(fac.coFac); 186 } else { 187 Object ocfac = fac.coFac; 188 SquarefreeAbstract saq = null; 189 if (ocfac instanceof QuotientRing) { 190 QuotientRing<C> qf = (QuotientRing<C>) ocfac; 191 saq = new SquarefreeInfiniteFieldCharP<C>(qf); 192 } else if (ocfac instanceof AlgebraicNumberRing) { 193 AlgebraicNumberRing<C> af = (AlgebraicNumberRing<C>) ocfac; 194 saq = new SquarefreeInfiniteAlgebraicFieldCharP<C>(af); 195 } 196 if (saq == null) { 197 throw new IllegalArgumentException("no squarefree factorization " + fac.coFac); 198 } 199 SquarefreeAbstract<C> sa = (SquarefreeAbstract<C>) saq; 200 return sa; 201 } 202 } 203 } 204 205 206 /** 207 * Determine suitable implementation of squarefree factorization algorithms, 208 * other cases. 209 * @param <C> coefficient type 210 * @param fac RingFactory<C>. 211 * @return squarefree factorization algorithm implementation. 212 */ 213 @SuppressWarnings("unchecked") 214 public static <C extends GcdRingElem<C>> SquarefreeAbstract<C> getImplementation(RingFactory<C> fac) { 215 //logger.info("fac = " + fac.getClass().getName()); 216 //System.out.println("fac_o = " + fac.getClass().getName()); 217 int t = 0; 218 SquarefreeAbstract/*raw type<C>*/ufd = null; 219 AlgebraicNumberRing afac = null; 220 QuotientRing qfac = null; 221 GenPolynomialRing pfac = null; 222 while (true) { // switch 223 Object ofac = fac; 224 if (ofac instanceof BigInteger) { 225 t = 1; 226 break; 227 } 228 if (ofac instanceof BigRational) { 229 t = 2; 230 break; 231 } 232 if (ofac instanceof ModIntegerRing) { 233 t = 3; 234 break; 235 } 236 if (ofac instanceof ModLongRing) { 237 t = 10; 238 break; 239 } 240 if (ofac instanceof AlgebraicNumberRing) { 241 //System.out.println("afac_o = " + ofac); 242 afac = (AlgebraicNumberRing) ofac; 243 ofac = afac.ring.coFac; 244 //System.out.println("o_afac = " + ofac); 245 t = 4; 246 break; 247 } 248 if (ofac instanceof QuotientRing) { 249 //System.out.println("qfac_o = " + ofac); 250 qfac = (QuotientRing) ofac; 251 t = 7; 252 break; 253 } 254 if (ofac instanceof GenPolynomialRing) { 255 //System.out.println("qfac_o = " + ofac); 256 pfac = (GenPolynomialRing) ofac; 257 t = 8; 258 break; 259 } 260 if (fac.isField()) { 261 //System.out.println("fac_field = " + fac); 262 t = 9; 263 break; 264 } else { 265 t = 11; 266 break; 267 } 268 //break; 269 } 270 //System.out.println("ft = " + t); 271 if (t == 1) { // BigInteger 272 ufd = new SquarefreeRingChar0/*raw*/(fac); 273 } 274 if (t == 2) { // BigRational 275 ufd = new SquarefreeFieldChar0/*raw*/(fac); 276 } 277 if (t == 3) { // ModInteger 278 ufd = new SquarefreeFiniteFieldCharP/*raw*/(fac); 279 } 280 if (t == 10) { // ModLong 281 ufd = new SquarefreeFiniteFieldCharP/*raw*/(fac); 282 } 283 if (t == 4) { // AlgebraicNumber 284 ufd = getImplementation(afac); 285 } 286 if (t == 7) { // Quotient 287 ufd = getImplementation(qfac); 288 } 289 if (t == 8) { // GenPolynomial 290 ufd = getImplementationPoly(pfac); 291 } 292 if (t == 9) { // other fields 293 if (fac.characteristic().signum() == 0) { 294 ufd = new SquarefreeFieldChar0/*raw*/(fac); 295 } else { 296 if (fac.isFinite()) { 297 ufd = new SquarefreeFiniteFieldCharP/*raw*/(fac); 298 } else { 299 ufd = new SquarefreeInfiniteFieldCharP/*raw*/(fac); 300 } 301 } 302 } 303 if (t == 11) { // other rings 304 if (fac.characteristic().signum() == 0) { 305 ufd = new SquarefreeRingChar0/*raw*/(fac); 306 } 307 // else fail 308 } 309 if (ufd == null) { 310 throw new IllegalArgumentException("no squarefree factorization implementation for " 311 + fac.getClass().getName()); 312 } 313 logger.debug("ufd = " + ufd); 314 //System.out.println("ufd = " + ufd); 315 return (SquarefreeAbstract<C>) ufd; 316 } 317 318 }