001/* 002 * $Id: FactorComplex.java 5975 2019-04-14 11:26:03Z kredel $ 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 // System.out.println("complex afactors = " + afactors); 135 logger.info("complex afactors = " + afactors); 136 } 137 for (GenPolynomial<AlgebraicNumber<C>> pa : afactors) { 138 GenPolynomial<Complex<C>> pc = PolyUtil.<C> complexFromAlgebraic(pfac, pa); 139 factors.add(pc); 140 } 141 //System.out.println("cfactors = " + factors); 142 return factors; 143 } 144 145 146 /** 147 * GenPolynomial factorization of a squarefree polynomial. 148 * @param P squarefree GenPolynomial<AlgebraicNumber<C>>. 149 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 150 */ 151 @Override 152 public List<GenPolynomial<Complex<C>>> factorsSquarefree(GenPolynomial<Complex<C>> P) { 153 if (P == null) { 154 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 155 } 156 List<GenPolynomial<Complex<C>>> factors = new ArrayList<GenPolynomial<Complex<C>>>(); 157 if (P.isZERO()) { 158 return factors; 159 } 160 if (P.isONE()) { 161 factors.add(P); 162 return factors; 163 } 164 GenPolynomialRing<Complex<C>> pfac = P.ring; // CC[x] 165 if (pfac.nvar <= 1) { 166 throw new IllegalArgumentException("only for multivariate polynomials"); 167 } 168 ComplexRing<C> cfac = (ComplexRing<C>) pfac.coFac; 169 if (!afac.ring.coFac.equals(cfac.ring)) { 170 throw new IllegalArgumentException("coefficient rings do not match"); 171 } 172 Complex<C> ldcf = P.leadingBaseCoefficient(); 173 if (!ldcf.isONE()) { 174 P = P.monic(); 175 factors.add(pfac.getONE().multiply(ldcf)); 176 } 177 //System.out.println("\nP = " + P); 178 GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, pfac); 179 GenPolynomial<AlgebraicNumber<C>> A = PolyUtil.<C> algebraicFromComplex(pafac, P); 180 //System.out.println("A = " + A); 181 List<GenPolynomial<AlgebraicNumber<C>>> afactors = factorAlgeb.factorsSquarefree(A); 182 if (debug) { 183 // System.out.println("complex afactors = " + afactors); 184 logger.info("complex afactors = " + afactors); 185 } 186 for (GenPolynomial<AlgebraicNumber<C>> pa : afactors) { 187 GenPolynomial<Complex<C>> pc = PolyUtil.<C> complexFromAlgebraic(pfac, pa); 188 factors.add(pc); 189 } 190 //System.out.println("cfactors = " + factors); 191 return factors; 192 } 193 194}