001/*
002 * $Id: FactorComplex.java 3883 2012-02-05 18:43:31Z kredel $
003 */
004
005package edu.jas.ufd;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import org.apache.log4j.Logger;
012
013import edu.jas.poly.AlgebraicNumber;
014import edu.jas.poly.AlgebraicNumberRing;
015import edu.jas.poly.Complex;
016import edu.jas.poly.ComplexRing;
017import edu.jas.poly.GenPolynomial;
018import edu.jas.poly.GenPolynomialRing;
019import edu.jas.poly.TermOrder;
020import edu.jas.poly.PolyUtil;
021import edu.jas.structure.GcdRingElem;
022import edu.jas.structure.RingFactory;
023
024
025/**
026 * Complex coefficients factorization algorithms. This class implements
027 * factorization methods for polynomials over Complex numbers via the algebraic
028 * number C(i) over rational numbers or over (prime) modular integers. <b>Note:</b>
029 * Decomposition to linear factors is only via absolute factorization since
030 * Complex are not the analytic complex numbers.
031 * @author Heinz Kredel
032 * @param <C> coefficient type
033 */
034
035public class FactorComplex<C extends GcdRingElem<C>> extends FactorAbsolute<Complex<C>> {
036
037
038    private static final Logger logger = Logger.getLogger(FactorComplex.class);
039
040
041    private final boolean debug = logger.isDebugEnabled();
042
043
044    /**
045     * Factorization engine for algebraic coefficients.
046     */
047    public final FactorAbstract<AlgebraicNumber<C>> factorAlgeb;
048
049
050    /**
051     * Complex algebraic factory.
052     */
053    public final AlgebraicNumberRing<C> afac;
054
055
056    /**
057     * No argument constructor. <b>Note:</b> can't use this constructor.
058     */
059    protected FactorComplex() {
060        throw new IllegalArgumentException("don't use this constructor");
061    }
062
063
064    /**
065     * Constructor.
066     * @param fac complex number factory.
067     */
068    public FactorComplex(RingFactory<Complex<C>> fac) { // why is this constructor required?
069        this((ComplexRing<C>) fac);
070    }
071
072
073    /**
074     * Constructor.
075     * @param fac complex number factory.
076     */
077    public FactorComplex(ComplexRing<C> fac) {
078        super(fac);
079        this.afac = fac.algebraicRing();
080        this.factorAlgeb = FactorFactory.<C> getImplementation(afac);
081    }
082
083
084    /**
085     * Constructor.
086     * @param fac complex number factory.
087     * @param factorAlgeb factorization engine for polynomials over algebraic coefficients.
088     */
089    public FactorComplex(ComplexRing<C> fac, FactorAbstract<AlgebraicNumber<C>> factorAlgeb) {
090        super(fac);
091        this.afac = fac.algebraicRing();
092        this.factorAlgeb = factorAlgeb;
093    }
094
095
096    /**
097     * GenPolynomial base factorization of a squarefree polynomial.
098     * @param P squarefree GenPolynomial&lt;AlgebraicNumber&lt;C&gt;&gt;.
099     * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i.
100     */
101    @Override
102    public List<GenPolynomial<Complex<C>>> baseFactorsSquarefree(GenPolynomial<Complex<C>> P) {
103        if (P == null) {
104            throw new IllegalArgumentException(this.getClass().getName() + " P == null");
105        }
106        List<GenPolynomial<Complex<C>>> factors = new ArrayList<GenPolynomial<Complex<C>>>();
107        if (P.isZERO()) {
108            return factors;
109        }
110        if (P.isONE()) {
111            factors.add(P);
112            return factors;
113        }
114        GenPolynomialRing<Complex<C>> pfac = P.ring; // CC[x]
115        if (pfac.nvar > 1) {
116            throw new IllegalArgumentException("only for univariate polynomials");
117        }
118        ComplexRing<C> cfac = (ComplexRing<C>) pfac.coFac;
119        if (!afac.ring.coFac.equals(cfac.ring)) {
120            throw new IllegalArgumentException("coefficient rings do not match");
121        }
122        Complex<C> ldcf = P.leadingBaseCoefficient();
123        if (!ldcf.isONE()) {
124            P = P.monic();
125            factors.add(pfac.getONE().multiply(ldcf));
126        }
127        //System.out.println("\nP = " + P);
128        GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, pfac);
129        GenPolynomial<AlgebraicNumber<C>> A = PolyUtil.<C> algebraicFromComplex(pafac, P);
130        //System.out.println("A = " + A);
131        List<GenPolynomial<AlgebraicNumber<C>>> afactors = factorAlgeb.baseFactorsSquarefree(A);
132        if (debug) {
133            // System.out.println("complex afactors = " + afactors);
134            logger.info("complex afactors = " + afactors);
135        }
136        for (GenPolynomial<AlgebraicNumber<C>> pa : afactors) {
137            GenPolynomial<Complex<C>> pc = PolyUtil.<C> complexFromAlgebraic(pfac, pa);
138            factors.add(pc);
139        }
140        //System.out.println("cfactors = " + factors);
141        return factors;
142    }
143
144}