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