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