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