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.LogManager; 012import org.apache.logging.log4j.Logger; 013 014import edu.jas.poly.GenPolynomial; 015import edu.jas.poly.GenPolynomialRing; 016import edu.jas.structure.GcdRingElem; 017 018 019/** 020 * Rational function coefficients factorization algorithms. This class 021 * implements factorization methods for polynomials over rational functions, 022 * that is, with coefficients from class <code>application.Quotient</code>. 023 * @author Heinz Kredel 024 */ 025 026public class FactorQuotient<C extends GcdRingElem<C>> extends FactorAbstract<Quotient<C>> { 027 028 029 private static final Logger logger = LogManager.getLogger(FactorQuotient.class); 030 031 032 //private static final boolean debug = logger.isInfoEnabled(); 033 034 035 /** 036 * Factorization engine for normal coefficients. 037 */ 038 protected final FactorAbstract<C> nengine; 039 040 041 /** 042 * No argument constructor. 043 */ 044 protected FactorQuotient() { 045 throw new IllegalArgumentException("don't use this constructor"); 046 } 047 048 049 /** 050 * Constructor. 051 * @param fac coefficient quotient ring factory. 052 */ 053 public FactorQuotient(QuotientRing<C> fac) { 054 this(fac, FactorFactory.<C> getImplementation(fac.ring.coFac)); 055 } 056 057 058 /** 059 * Constructor. 060 * @param fac coefficient quotient ring factory. 061 * @param nengine factorization engine for polynomials over base 062 * coefficients. 063 */ 064 public FactorQuotient(QuotientRing<C> fac, FactorAbstract<C> nengine) { 065 super(fac); 066 this.nengine = nengine; 067 } 068 069 070 /** 071 * GenPolynomial base factorization of a squarefree polynomial. 072 * @param P squarefree GenPolynomial. 073 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 074 */ 075 @Override 076 public List<GenPolynomial<Quotient<C>>> baseFactorsSquarefree(GenPolynomial<Quotient<C>> P) { 077 return factorsSquarefree(P); 078 } 079 080 081 /** 082 * GenPolynomial factorization of a squarefree polynomial. 083 * @param P squarefree GenPolynomial. 084 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 085 */ 086 @Override 087 public List<GenPolynomial<Quotient<C>>> factorsSquarefree(GenPolynomial<Quotient<C>> P) { 088 if (P == null) { 089 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 090 } 091 //System.out.println("factorsSquarefree, P = " + P); 092 List<GenPolynomial<Quotient<C>>> factors = new ArrayList<GenPolynomial<Quotient<C>>>(); 093 if (P.isZERO()) { 094 return factors; 095 } 096 if (P.isONE()) { 097 factors.add(P); 098 return factors; 099 } 100 GenPolynomialRing<Quotient<C>> pfac = P.ring; 101 GenPolynomial<Quotient<C>> Pr = P; 102 Quotient<C> ldcf = P.leadingBaseCoefficient(); 103 if (!ldcf.isONE()) { 104 //System.out.println("ldcf = " + ldcf); 105 Pr = Pr.monic(); 106 } 107 QuotientRing<C> qi = (QuotientRing<C>) pfac.coFac; 108 GenPolynomialRing<C> ci = qi.ring; 109 GenPolynomialRing<GenPolynomial<C>> ifac = new GenPolynomialRing<GenPolynomial<C>>(ci, pfac); 110 GenPolynomial<GenPolynomial<C>> Pi = PolyUfdUtil.<C> integralFromQuotientCoefficients(ifac, Pr); 111 //System.out.println("Pi = " + Pi); 112 113 // factor in C[x_1,...,x_n][y_1,...,y_m] 114 List<GenPolynomial<GenPolynomial<C>>> irfacts = nengine.recursiveFactorsSquarefree(Pi); 115 logger.info("irfacts = {}", irfacts); 116 if (irfacts.size() <= 1) { 117 factors.add(P); 118 return factors; 119 } 120 List<GenPolynomial<Quotient<C>>> qfacts = PolyUfdUtil.<C> quotientFromIntegralCoefficients(pfac, 121 irfacts); 122 //System.out.println("qfacts = " + qfacts); 123 //qfacts = PolyUtil.monic(qfacts); 124 //System.out.println("qfacts = " + qfacts); 125 if (!ldcf.isONE()) { 126 GenPolynomial<Quotient<C>> r = qfacts.get(0); 127 qfacts.remove(r); 128 r = r.multiply(ldcf); 129 qfacts.add(0, r); 130 } 131 logger.info("qfacts = {}", qfacts); 132 factors.addAll(qfacts); 133 return factors; 134 } 135 136}