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 }