001/*
002 * $Id: SquarefreeFactory.java 4067 2012-07-27 16:17:35Z 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&lt;CT&gt; engine;
037 * engine = SquarefreeFactory.&lt;CT&gt; 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&lt;BigInteger&gt; 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&lt;C&gt;.
114     * @param fac AlgebraicNumberRing&lt;C&gt;.
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&lt;C&gt;.
137     * @param fac QuotientRing&lt;C&gt;.
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&lt;C&gt;.
153     * @param fac GenPolynomialRing&lt;C&gt;.
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&lt;C&gt;.
165     * @param fac GenPolynomialRing&lt;C&gt;.
166     * @param <C> coefficient type, e.g. BigRational, ModInteger.
167     * @return squarefree factorization algorithm implementation.
168     */
169    @SuppressWarnings("unchecked")
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&lt;C&gt;.
203     * @return squarefree factorization algorithm implementation.
204     */
205    @SuppressWarnings("unchecked")
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}