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