001 /*
002 * $Id: FactorComplex.java 3364 2010-10-24 12:56:06Z 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.poly.AlgebraicNumber;
014 import edu.jas.poly.AlgebraicNumberRing;
015 import edu.jas.poly.Complex;
016 import edu.jas.poly.ComplexRing;
017 import edu.jas.poly.GenPolynomial;
018 import edu.jas.poly.GenPolynomialRing;
019 import edu.jas.poly.TermOrder;
020 import edu.jas.poly.PolyUtil;
021 import edu.jas.structure.GcdRingElem;
022 import edu.jas.structure.RingFactory;
023
024
025 /**
026 * Complex coefficients factorization algorithms. This class implements
027 * factorization methods for polynomials over Complex numbers via the algebraic
028 * number C(i) over rational numbers or over (prime) modular integers. <b>Note:</b>
029 * Decomposition to linear factors is only via absolute factorization since
030 * Complex are not the analytic complex numbers.
031 * @author Heinz Kredel
032 * @param <C> coefficient type
033 */
034
035 public class FactorComplex<C extends GcdRingElem<C>> extends FactorAbsolute<Complex<C>> {
036
037
038 private static final Logger logger = Logger.getLogger(FactorComplex.class);
039
040
041 private final boolean debug = logger.isDebugEnabled();
042
043
044 /**
045 * Factorization engine for algebraic coefficients.
046 */
047 public final FactorAbstract<AlgebraicNumber<C>> factorAlgeb;
048
049
050 /**
051 * Complex algebraic factory.
052 */
053 public final AlgebraicNumberRing<C> afac;
054
055
056 /**
057 * No argument constructor. <b>Note:</b> can't use this constructor.
058 */
059 protected FactorComplex() {
060 throw new IllegalArgumentException("don't use this constructor");
061 }
062
063
064 /**
065 * Constructor.
066 * @param fac complex number factory.
067 */
068 public FactorComplex(RingFactory<Complex<C>> fac) { // why is this constructor required?
069 this((ComplexRing<C>) fac);
070 }
071
072
073 /**
074 * Constructor.
075 * @param fac complex number factory.
076 */
077 public FactorComplex(ComplexRing<C> fac) {
078 super(fac);
079 GenPolynomialRing<C> pfac = new GenPolynomialRing<C>(fac.ring, 1, new TermOrder(TermOrder.INVLEX),
080 new String[] { "I" });
081 GenPolynomial<C> I = pfac.univariate(0, 2L).sum(pfac.getONE());
082 afac = new AlgebraicNumberRing<C>(I, true); // must indicate field
083 this.factorAlgeb = FactorFactory.<C> getImplementation(afac);
084 }
085
086
087 /**
088 * GenPolynomial base factorization of a squarefree polynomial.
089 * @param P squarefree GenPolynomial<AlgebraicNumber<C>>.
090 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i.
091 */
092 @Override
093 public List<GenPolynomial<Complex<C>>> baseFactorsSquarefree(GenPolynomial<Complex<C>> P) {
094 if (P == null) {
095 throw new IllegalArgumentException(this.getClass().getName() + " P == null");
096 }
097 List<GenPolynomial<Complex<C>>> factors = new ArrayList<GenPolynomial<Complex<C>>>();
098 if (P.isZERO()) {
099 return factors;
100 }
101 if (P.isONE()) {
102 factors.add(P);
103 return factors;
104 }
105 GenPolynomialRing<Complex<C>> pfac = P.ring; // CC[x]
106 if (pfac.nvar > 1) {
107 throw new IllegalArgumentException("only for univariate polynomials");
108 }
109 ComplexRing<C> cfac = (ComplexRing<C>) pfac.coFac;
110 if (!afac.ring.coFac.equals(cfac.ring)) {
111 throw new IllegalArgumentException("coefficient rings do not match");
112 }
113 Complex<C> ldcf = P.leadingBaseCoefficient();
114 if (!ldcf.isONE()) {
115 P = P.monic();
116 factors.add(pfac.getONE().multiply(ldcf));
117 }
118 //System.out.println("\nP = " + P);
119 GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, pfac);
120 GenPolynomial<AlgebraicNumber<C>> A = PolyUtil.<C> algebraicFromComplex(pafac, P);
121 //System.out.println("A = " + A);
122 List<GenPolynomial<AlgebraicNumber<C>>> afactors = factorAlgeb.baseFactorsSquarefree(A);
123 if (debug) {
124 // System.out.println("complex afactors = " + afactors);
125 logger.info("complex afactors = " + afactors);
126 }
127 for (GenPolynomial<AlgebraicNumber<C>> pa : afactors) {
128 GenPolynomial<Complex<C>> pc = PolyUtil.<C> complexFromAlgebraic(pfac, pa);
129 factors.add(pc);
130 }
131 //System.out.println("cfactors = " + factors);
132 return factors;
133 }
134
135 }