001/* 002 * $Id$ 003 */ 004 005package edu.jas.ufd; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import org.apache.logging.log4j.Logger; 012import org.apache.logging.log4j.LogManager; 013 014import edu.jas.poly.AlgebraicNumber; 015import edu.jas.poly.AlgebraicNumberRing; 016import edu.jas.poly.Complex; 017import edu.jas.poly.ComplexRing; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.TermOrder; 021import edu.jas.poly.PolyUtil; 022import edu.jas.structure.GcdRingElem; 023import edu.jas.structure.RingFactory; 024 025 026/** 027 * Complex coefficients factorization algorithms. This class implements 028 * factorization methods for polynomials over Complex numbers via the algebraic 029 * number C(i) over rational numbers or over (prime) modular integers. <b>Note:</b> 030 * Decomposition to linear factors is only via absolute factorization since 031 * Complex are not the analytic complex numbers. 032 * @author Heinz Kredel 033 * @param <C> coefficient type 034 */ 035 036public class FactorComplex<C extends GcdRingElem<C>> extends FactorAbsolute<Complex<C>> { 037 038 039 private static final Logger logger = LogManager.getLogger(FactorComplex.class); 040 041 042 private static final boolean debug = logger.isDebugEnabled(); 043 044 045 /** 046 * Factorization engine for algebraic coefficients. 047 */ 048 public final FactorAbstract<AlgebraicNumber<C>> factorAlgeb; 049 050 051 /** 052 * Complex algebraic factory. 053 */ 054 public final AlgebraicNumberRing<C> afac; 055 056 057 /** 058 * No argument constructor. <b>Note:</b> can't use this constructor. 059 */ 060 protected FactorComplex() { 061 throw new IllegalArgumentException("don't use this constructor"); 062 } 063 064 065 /** 066 * Constructor. 067 * @param fac complex number factory. 068 */ 069 public FactorComplex(RingFactory<Complex<C>> fac) { // why is this constructor required? 070 this((ComplexRing<C>) fac); 071 } 072 073 074 /** 075 * Constructor. 076 * @param fac complex number factory. 077 */ 078 public FactorComplex(ComplexRing<C> fac) { 079 super(fac); 080 this.afac = fac.algebraicRing(); 081 this.factorAlgeb = FactorFactory.<C> getImplementation(afac); 082 } 083 084 085 /** 086 * Constructor. 087 * @param fac complex number factory. 088 * @param factorAlgeb factorization engine for polynomials over algebraic coefficients. 089 */ 090 public FactorComplex(ComplexRing<C> fac, FactorAbstract<AlgebraicNumber<C>> factorAlgeb) { 091 super(fac); 092 this.afac = fac.algebraicRing(); 093 this.factorAlgeb = factorAlgeb; 094 } 095 096 097 /** 098 * GenPolynomial base factorization of a squarefree polynomial. 099 * @param P squarefree GenPolynomial<AlgebraicNumber<C>>. 100 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 101 */ 102 @Override 103 public List<GenPolynomial<Complex<C>>> baseFactorsSquarefree(GenPolynomial<Complex<C>> P) { 104 if (P == null) { 105 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 106 } 107 List<GenPolynomial<Complex<C>>> factors = new ArrayList<GenPolynomial<Complex<C>>>(); 108 if (P.isZERO()) { 109 return factors; 110 } 111 if (P.isONE()) { 112 factors.add(P); 113 return factors; 114 } 115 GenPolynomialRing<Complex<C>> pfac = P.ring; // CC[x] 116 if (pfac.nvar > 1) { 117 throw new IllegalArgumentException("only for univariate polynomials"); 118 } 119 ComplexRing<C> cfac = (ComplexRing<C>) pfac.coFac; 120 if (!afac.ring.coFac.equals(cfac.ring)) { 121 throw new IllegalArgumentException("coefficient rings do not match"); 122 } 123 Complex<C> ldcf = P.leadingBaseCoefficient(); 124 if (!ldcf.isONE()) { 125 P = P.monic(); 126 factors.add(pfac.getONE().multiply(ldcf)); 127 } 128 //System.out.println("\nP = " + P); 129 GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, pfac); 130 GenPolynomial<AlgebraicNumber<C>> A = PolyUtil.<C> algebraicFromComplex(pafac, P); 131 //System.out.println("A = " + A); 132 List<GenPolynomial<AlgebraicNumber<C>>> afactors = factorAlgeb.baseFactorsSquarefree(A); 133 if (debug) { 134 logger.info("complex afactors = {}", afactors); 135 } 136 for (GenPolynomial<AlgebraicNumber<C>> pa : afactors) { 137 GenPolynomial<Complex<C>> pc = PolyUtil.<C> complexFromAlgebraic(pfac, pa); 138 factors.add(pc); 139 } 140 //System.out.println("cfactors = " + factors); 141 return factors; 142 } 143 144 145 /** 146 * GenPolynomial factorization of a squarefree polynomial. 147 * @param P squarefree GenPolynomial<AlgebraicNumber<C>>. 148 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 149 */ 150 @Override 151 public List<GenPolynomial<Complex<C>>> factorsSquarefree(GenPolynomial<Complex<C>> P) { 152 if (P == null) { 153 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 154 } 155 List<GenPolynomial<Complex<C>>> factors = new ArrayList<GenPolynomial<Complex<C>>>(); 156 if (P.isZERO()) { 157 return factors; 158 } 159 if (P.isONE()) { 160 factors.add(P); 161 return factors; 162 } 163 GenPolynomialRing<Complex<C>> pfac = P.ring; // CC[x] 164 if (pfac.nvar <= 1) { 165 throw new IllegalArgumentException("only for multivariate polynomials"); 166 } 167 ComplexRing<C> cfac = (ComplexRing<C>) pfac.coFac; 168 if (!afac.ring.coFac.equals(cfac.ring)) { 169 throw new IllegalArgumentException("coefficient rings do not match"); 170 } 171 Complex<C> ldcf = P.leadingBaseCoefficient(); 172 if (!ldcf.isONE()) { 173 P = P.monic(); 174 factors.add(pfac.getONE().multiply(ldcf)); 175 } 176 //System.out.println("\nP = " + P); 177 GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, pfac); 178 GenPolynomial<AlgebraicNumber<C>> A = PolyUtil.<C> algebraicFromComplex(pafac, P); 179 //System.out.println("A = " + A); 180 List<GenPolynomial<AlgebraicNumber<C>>> afactors = factorAlgeb.factorsSquarefree(A); 181 if (debug) { 182 logger.info("complex afactors = {}", afactors); 183 } 184 for (GenPolynomial<AlgebraicNumber<C>> pa : afactors) { 185 GenPolynomial<Complex<C>> pc = PolyUtil.<C> complexFromAlgebraic(pfac, pa); 186 factors.add(pc); 187 } 188 //System.out.println("cfactors = " + factors); 189 return factors; 190 } 191 192}