001    /*
002     * $Id: FactorQuotient.java 3356 2010-10-23 16:41:01Z kredel $
003     */
004    
005    package edu.jas.ufd;
006    
007    
008    import java.util.ArrayList;
009    import java.util.List;
010    
011    import org.apache.log4j.Logger;
012    
013    import edu.jas.poly.GenPolynomial;
014    import edu.jas.poly.GenPolynomialRing;
015    import edu.jas.structure.GcdRingElem;
016    
017    
018    /**
019     * Rational function coefficients factorization algorithms. This class
020     * implements factorization methods for polynomials over rational functions,
021     * that is, with coefficients from class <code>application.Quotient</code>.
022     * @author Heinz Kredel
023     */
024    
025    public class FactorQuotient<C extends GcdRingElem<C>> extends FactorAbstract<Quotient<C>> {
026    
027    
028        private static final Logger logger = Logger.getLogger(FactorQuotient.class);
029    
030    
031        private final boolean debug = true || logger.isInfoEnabled();
032    
033    
034        /**
035         * Factorization engine for normal coefficients.
036         */
037        protected final FactorAbstract<C> nengine;
038    
039    
040        /**
041         * No argument constructor.
042         */
043        protected FactorQuotient() {
044            throw new IllegalArgumentException("don't use this constructor");
045        }
046    
047    
048        /**
049         * Constructor.
050         * @param fac coefficient quotient ring factory.
051         */
052        public FactorQuotient(QuotientRing<C> fac) {
053            super(fac);
054            nengine = FactorFactory.<C> getImplementation(fac.ring.coFac);
055        }
056    
057    
058        /**
059         * GenPolynomial base factorization of a squarefree polynomial.
060         * @param P squarefree GenPolynomial.
061         * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i.
062         */
063        @Override
064        public List<GenPolynomial<Quotient<C>>> baseFactorsSquarefree(GenPolynomial<Quotient<C>> P) {
065            return factorsSquarefree(P);
066        }
067    
068    
069        /**
070         * GenPolynomial factorization of a squarefree polynomial.
071         * @param P squarefree GenPolynomial.
072         * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i.
073         */
074        @Override
075        public List<GenPolynomial<Quotient<C>>> factorsSquarefree(GenPolynomial<Quotient<C>> P) {
076            if (P == null) {
077                throw new IllegalArgumentException(this.getClass().getName() + " P == null");
078            }
079            //System.out.println("factorsSquarefree, P = " + P);
080            List<GenPolynomial<Quotient<C>>> factors = new ArrayList<GenPolynomial<Quotient<C>>>();
081            if (P.isZERO()) {
082                return factors;
083            }
084            if (P.isONE()) {
085                factors.add(P);
086                return factors;
087            }
088            GenPolynomialRing<Quotient<C>> pfac = P.ring;
089            GenPolynomial<Quotient<C>> Pr = P;
090            Quotient<C> ldcf = P.leadingBaseCoefficient();
091            if (!ldcf.isONE()) {
092                //System.out.println("ldcf = " + ldcf);
093                Pr = Pr.monic();
094            }
095            QuotientRing<C> qi = (QuotientRing<C>) pfac.coFac;
096            GenPolynomialRing<C> ci = qi.ring;
097            GenPolynomialRing<GenPolynomial<C>> ifac = new GenPolynomialRing<GenPolynomial<C>>(ci, pfac);
098            GenPolynomial<GenPolynomial<C>> Pi = PolyUfdUtil.<C> integralFromQuotientCoefficients(ifac, Pr);
099            //System.out.println("Pi = " + Pi);
100    
101            // factor in C[x_1,...,x_n][y_1,...,y_m]
102            List<GenPolynomial<GenPolynomial<C>>> irfacts = nengine.recursiveFactorsSquarefree(Pi);
103            if (logger.isInfoEnabled()) {
104                logger.info("irfacts = " + irfacts);
105            }
106            if (irfacts.size() <= 1) {
107                factors.add(P);
108                return factors;
109            }
110            List<GenPolynomial<Quotient<C>>> qfacts = PolyUfdUtil.<C> quotientFromIntegralCoefficients(pfac,
111                    irfacts);
112            //System.out.println("qfacts = " + qfacts);
113            //qfacts = PolyUtil.monic(qfacts);
114            //System.out.println("qfacts = " + qfacts);
115            if (!ldcf.isONE()) {
116                GenPolynomial<Quotient<C>> r = qfacts.get(0);
117                qfacts.remove(r);
118                r = r.multiply(ldcf);
119                qfacts.add(0, r);
120            }
121            if (logger.isInfoEnabled()) {
122                logger.info("qfacts = " + qfacts);
123            }
124            factors.addAll(qfacts);
125            return factors;
126        }
127    
128    }