001/*
002 * $Id: FactorRealReal.java 5868 2018-07-20 15:44:13Z kredel $
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: check if is absolute possible? and what does it mean? 
040    // absolute not possible since factorization over reals leads to factors of degree 2
041    //FactorAbsolute<AlgebraicNumber<C>>
042    //FactorAbstract<AlgebraicNumber<C>>
043
044
045    private static final Logger logger = LogManager.getLogger(FactorRealReal.class);
046
047
048    private static final boolean debug = logger.isInfoEnabled();
049
050
051    /**
052     * Factorization engine for base coefficients.
053     */
054    public final FactorAbstract<edu.jas.root.RealAlgebraicNumber<C>> factorAlgebraic;
055
056
057    /**
058     * No argument constructor. <b>Note:</b> can't use this constructor.
059     */
060    protected FactorRealReal() {
061        throw new IllegalArgumentException("don't use this constructor");
062    }
063
064
065    /**
066     * Constructor.
067     * @param fac algebraic number factory.
068     */
069    @SuppressWarnings("unchecked")
070    public FactorRealReal(RealAlgebraicRing<C> fac) {
071        // ignore recursion, as it is handled in FactorRealAlgebraic:
072        this(fac, FactorFactory.<edu.jas.root.RealAlgebraicNumber<C>> getImplementation(
073                        (edu.jas.root.RealAlgebraicRing<C>) (Object) fac.realRing));
074    }
075
076
077    /**
078     * Constructor.
079     * @param fac algebraic number factory.
080     * @param factorAlgebraic factorization engine for polynomials over base
081     *            coefficients.
082     */
083    public FactorRealReal(RealAlgebraicRing<C> fac,
084                    FactorAbstract<edu.jas.root.RealAlgebraicNumber<C>> factorAlgebraic) {
085        super(fac);
086        this.factorAlgebraic = factorAlgebraic;
087    }
088
089
090    /**
091     * GenPolynomial base factorization of a squarefree polynomial.
092     * @param P squarefree GenPolynomial&lt;RealAlgebraicNumber&lt;C&gt;&gt;.
093     * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i.
094     */
095    @Override
096    @SuppressWarnings("unchecked")
097    public List<GenPolynomial<RealAlgebraicNumber<C>>> baseFactorsSquarefree(
098                    GenPolynomial<RealAlgebraicNumber<C>> P) {
099        if (P == null) {
100            throw new IllegalArgumentException(this.getClass().getName() + " P == null");
101        }
102        List<GenPolynomial<RealAlgebraicNumber<C>>> factors = new ArrayList<GenPolynomial<RealAlgebraicNumber<C>>>();
103        if (P.isZERO()) {
104            return factors;
105        }
106        if (P.isONE()) {
107            factors.add(P);
108            return factors;
109        }
110        GenPolynomialRing<RealAlgebraicNumber<C>> pfac = P.ring; // Q(alpha)[x]
111        if (pfac.nvar > 1) {
112            throw new IllegalArgumentException("only for univariate polynomials");
113        }
114        RealAlgebraicRing<C> rere = (RealAlgebraicRing<C>) pfac.coFac;
115        edu.jas.root.RealAlgebraicRing<C> rfac = (edu.jas.root.RealAlgebraicRing<C>) (Object) rere.realRing;
116
117        RealAlgebraicNumber<C> ldcf = P.leadingBaseCoefficient();
118        if (!ldcf.isONE()) {
119            P = P.monic();
120            factors.add(pfac.getONE().multiply(ldcf));
121        }
122        //System.out.println("\nP = " + P);
123        GenPolynomialRing<edu.jas.root.RealAlgebraicNumber<C>> arfac = new GenPolynomialRing<edu.jas.root.RealAlgebraicNumber<C>>(
124                        rfac, pfac);
125        GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> A = PolyUtilApp
126                        .<C> realAlgFromRealCoefficients(arfac, P);
127        // factor A:
128        List<GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>>> afactors = factorAlgebraic
129                        .baseFactorsSquarefree(A);
130        for (GenPolynomial<edu.jas.root.RealAlgebraicNumber<C>> a : afactors) {
131            GenPolynomial<RealAlgebraicNumber<C>> p = PolyUtilApp.<C> realFromRealAlgCoefficients(pfac, a);
132            factors.add(p);
133        }
134        if (debug) {
135            logger.info("rafactors = " + factors);
136        }
137        return factors;
138    }
139
140}