001/* 002 * $Id: SquarefreeFactory.java 4965 2014-10-17 20:07:51Z kredel $ 003 */ 004 005package edu.jas.ufd; 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.poly.AlgebraicNumber; 017import edu.jas.poly.AlgebraicNumberRing; 018import edu.jas.poly.GenPolynomialRing; 019import edu.jas.structure.GcdRingElem; 020import 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 054public 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 } 125 if (fac.isFinite()) { 126 return new SquarefreeFiniteFieldCharP<AlgebraicNumber<C>>(fac); 127 } 128 return new SquarefreeInfiniteAlgebraicFieldCharP<C>(fac); 129 } 130 throw new ArithmeticException("eventually no integral domain " + fac.getClass().getName()); 131 } 132 133 134 /** 135 * Determine suitable implementation of squarefree factorization algorithms, 136 * case Quotient<C>. 137 * @param fac QuotientRing<C>. 138 * @param <C> coefficient type, e.g. BigRational, ModInteger. 139 * @return squarefree factorization algorithm implementation. 140 */ 141 public static <C extends GcdRingElem<C>> SquarefreeAbstract<Quotient<C>> getImplementation( 142 QuotientRing<C> fac) { 143 if (fac.characteristic().signum() == 0) { 144 return new SquarefreeFieldChar0<Quotient<C>>(fac); 145 } 146 return new SquarefreeInfiniteFieldCharP<C>(fac); 147 } 148 149 150 /** 151 * Determine suitable implementation of squarefree factorization algorithms, 152 * case GenPolynomial<C>. 153 * @param fac GenPolynomialRing<C>. 154 * @param <C> coefficient type, e.g. BigRational, ModInteger. 155 * @return squarefree factorization algorithm implementation. 156 */ 157 public static <C extends GcdRingElem<C>> SquarefreeAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 158 return getImplementationPoly(fac); 159 } 160 161 162 /* 163 * Determine suitable implementation of squarefree factorization algorithms, 164 * case GenPolynomial<C>. 165 * @param fac GenPolynomialRing<C>. 166 * @param <C> coefficient type, e.g. BigRational, ModInteger. 167 * @return squarefree factorization algorithm implementation. 168 */ 169 @SuppressWarnings("cast") 170 protected static <C extends GcdRingElem<C>> SquarefreeAbstract<C> getImplementationPoly( 171 GenPolynomialRing<C> fac) { 172 if (fac.characteristic().signum() == 0) { 173 if (fac.coFac.isField()) { 174 return new SquarefreeFieldChar0<C>(fac.coFac); 175 } 176 return new SquarefreeRingChar0<C>(fac.coFac); 177 } 178 if (fac.coFac.isFinite()) { 179 return new SquarefreeFiniteFieldCharP<C>(fac.coFac); 180 } 181 Object ocfac = fac.coFac; 182 SquarefreeAbstract saq = null; 183 if (ocfac instanceof QuotientRing) { 184 QuotientRing<C> qf = (QuotientRing<C>) ocfac; 185 saq = new SquarefreeInfiniteFieldCharP<C>(qf); 186 } else if (ocfac instanceof AlgebraicNumberRing) { 187 AlgebraicNumberRing<C> af = (AlgebraicNumberRing<C>) ocfac; 188 saq = new SquarefreeInfiniteAlgebraicFieldCharP<C>(af); 189 } 190 if (saq == null) { 191 throw new IllegalArgumentException("no squarefree factorization " + fac.coFac); 192 } 193 SquarefreeAbstract<C> sa = (SquarefreeAbstract<C>) saq; 194 return sa; 195 } 196 197 198 /** 199 * Determine suitable implementation of squarefree factorization algorithms, 200 * other cases. 201 * @param <C> coefficient type 202 * @param fac RingFactory<C>. 203 * @return squarefree factorization algorithm implementation. 204 */ 205 @SuppressWarnings("cast") 206 public static <C extends GcdRingElem<C>> SquarefreeAbstract<C> getImplementation(RingFactory<C> fac) { 207 //logger.info("fac = " + fac.getClass().getName()); 208 //System.out.println("fac_o = " + fac.getClass().getName()); 209 SquarefreeAbstract/*raw type<C>*/ufd = null; 210 AlgebraicNumberRing afac = null; 211 QuotientRing qfac = null; 212 GenPolynomialRing pfac = null; 213 Object ofac = fac; 214 if (ofac instanceof BigInteger) { 215 ufd = new SquarefreeRingChar0<C>(fac); 216 } else if (ofac instanceof BigRational) { 217 ufd = new SquarefreeFieldChar0<C>(fac); 218 } else if (ofac instanceof ModIntegerRing) { 219 ufd = new SquarefreeFiniteFieldCharP<C>(fac); 220 } else if (ofac instanceof ModLongRing) { 221 ufd = new SquarefreeFiniteFieldCharP<C>(fac); 222 } else if (ofac instanceof AlgebraicNumberRing) { 223 afac = (AlgebraicNumberRing) ofac; 224 //ofac = afac.ring.coFac; 225 //System.out.println("o_afac = " + ofac); 226 ufd = getImplementation(afac); 227 } else if (ofac instanceof QuotientRing) { 228 qfac = (QuotientRing) ofac; 229 ufd = getImplementation(qfac); 230 } else if (ofac instanceof GenPolynomialRing) { 231 pfac = (GenPolynomialRing) ofac; 232 ufd = getImplementationPoly(pfac); 233 } else if (fac.isField()) { 234 //System.out.println("fac_field = " + fac); 235 if (fac.characteristic().signum() == 0) { 236 ufd = new SquarefreeFieldChar0<C>(fac); 237 } else { 238 if (fac.isFinite()) { 239 ufd = new SquarefreeFiniteFieldCharP<C>(fac); 240 } else { 241 ufd = new SquarefreeInfiniteFieldCharP/*raw*/(fac); 242 } 243 } 244 } else if (fac.characteristic().signum() == 0) { 245 ufd = new SquarefreeRingChar0<C>(fac); 246 } else { 247 throw new IllegalArgumentException("no squarefree factorization implementation for " 248 + fac.getClass().getName()); 249 } 250 logger.debug("ufd = " + ufd); 251 return (SquarefreeAbstract<C>) ufd; 252 } 253 254}