001/*
002 * $Id$
003 */
004
005package edu.jas.application;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import org.apache.logging.log4j.Logger;
012import org.apache.logging.log4j.LogManager; 
013
014import edu.jas.arith.Rational;
015import edu.jas.poly.GenPolynomial;
016import edu.jas.poly.GenPolynomialRing;
017import edu.jas.structure.GcdRingElem;
018import edu.jas.ufd.FactorAbstract;
019
020
021/**
022 * Real algebraic number coefficients factorization algorithms. This class
023 * implements factorization methods for polynomials over bi-variate real
024 * algebraic numbers from package
025 * 
026 * <pre>
027 * edu.jas.application
028 * </pre>
029 * 
030 * .
031 * @param <C> coefficient type
032 * @author Heinz Kredel
033 */
034
035public class FactorRealReal<C extends GcdRingElem<C> & Rational>
036                extends FactorAbstract<RealAlgebraicNumber<C>> {
037
038
039    //TODO: absolute factorization would mean factorization to linear and quadratic factors
040    //FactorAbsolute<AlgebraicNumber<C>>
041    //FactorAbstract<AlgebraicNumber<C>>
042
043
044    private static final Logger logger = LogManager.getLogger(FactorRealReal.class);
045
046
047    private static final boolean debug = logger.isInfoEnabled();
048
049
050    /**
051     * Factorization engine for base coefficients.
052     */
053    public final FactorAbstract<edu.jas.root.RealAlgebraicNumber<C>> factorAlgebraic;
054
055
056    /**
057     * No argument constructor. <b>Note:</b> can't use this constructor.
058     */
059    protected FactorRealReal() {
060        throw new IllegalArgumentException("don't use this constructor");
061    }
062
063
064    /**
065     * Constructor.
066     * @param fac algebraic number factory.
067     */
068    @SuppressWarnings("unchecked")
069    public FactorRealReal(RealAlgebraicRing<C> fac) {
070        // ignore recursion, as it is handled in FactorRealAlgebraic:
071        this(fac, FactorFactory.<edu.jas.root.RealAlgebraicNumber<C>> getImplementation(
072                        (edu.jas.root.RealAlgebraicRing<C>) (Object) fac.realRing));
073    }
074
075
076    /**
077     * Constructor.
078     * @param fac algebraic number factory.
079     * @param factorAlgebraic factorization engine for polynomials over base
080     *            coefficients.
081     */
082    public FactorRealReal(RealAlgebraicRing<C> fac,
083                    FactorAbstract<edu.jas.root.RealAlgebraicNumber<C>> factorAlgebraic) {
084        super(fac);
085        this.factorAlgebraic = factorAlgebraic;
086    }
087
088
089    /**
090     * GenPolynomial base factorization of a squarefree polynomial.
091     * @param P squarefree GenPolynomial&lt;RealAlgebraicNumber&lt;C&gt;&gt;.
092     * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i.
093     */
094    @Override
095    @SuppressWarnings("unchecked")
096    public List<GenPolynomial<RealAlgebraicNumber<C>>> baseFactorsSquarefree(
097                    GenPolynomial<RealAlgebraicNumber<C>> P) {
098        if (P == null) {
099            throw new IllegalArgumentException(this.getClass().getName() + " P == null");
100        }
101        List<GenPolynomial<RealAlgebraicNumber<C>>> factors = new ArrayList<GenPolynomial<RealAlgebraicNumber<C>>>();
102        if (P.isZERO()) {
103            return factors;
104        }
105        if (P.isONE()) {
106            factors.add(P);
107            return factors;
108        }
109        GenPolynomialRing<RealAlgebraicNumber<C>> pfac = P.ring; // Q(alpha)[x]
110        if (pfac.nvar > 1) {
111            throw new IllegalArgumentException("only for univariate polynomials");
112        }
113        RealAlgebraicRing<C> rere = (RealAlgebraicRing<C>) pfac.coFac;
114        edu.jas.root.RealAlgebraicRing<C> rfac = (edu.jas.root.RealAlgebraicRing<C>) (Object) rere.realRing;
115
116        RealAlgebraicNumber<C> ldcf = P.leadingBaseCoefficient();
117        if (!ldcf.isONE()) {
118            P = P.monic();
119            factors.add(pfac.getONE().multiply(ldcf));
120        }
121        //System.out.println("\nP = " + P);
122        GenPolynomialRing<edu.jas.root.RealAlgebraicNumber<C>> arfac = new GenPolynomialRing<edu.jas.root.RealAlgebraicNumber<C>>(
123                        rfac, pfac);
124        GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> A = PolyUtilApp
125                        .<C> realAlgFromRealCoefficients(arfac, P);
126        // factor A:
127        List<GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>>> afactors = factorAlgebraic
128                        .baseFactorsSquarefree(A);
129        for (GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> a : afactors) {
130            GenPolynomial<RealAlgebraicNumber<C>> p = PolyUtilApp.<C> realFromRealAlgCoefficients(pfac, a);
131            factors.add(p);
132        }
133        if (debug) {
134            logger.info("rafactors = {}", factors);
135        }
136        return factors;
137    }
138
139}