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<RealAlgebraicNumber<C>>.
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 }