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