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