001/* 002 * $Id: FactorRational.java 5754 2017-05-28 15:07:12Z kredel $ 003 */ 004 005package edu.jas.ufd; 006 007 008import java.util.ArrayList; 009import java.util.List; 010import java.util.SortedMap; 011import java.util.TreeMap; 012import java.util.Map; 013 014import org.apache.log4j.Logger; 015 016import edu.jas.arith.BigInteger; 017import edu.jas.arith.BigRational; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.PolyUtil; 021 022 023/** 024 * Rational number coefficients factorization algorithms. This class implements 025 * factorization methods for polynomials over rational numbers. 026 * @author Heinz Kredel 027 */ 028 029public class FactorRational extends FactorAbsolute<BigRational> { 030 031 032 private static final Logger logger = Logger.getLogger(FactorRational.class); 033 034 035 private static final boolean debug = logger.isInfoEnabled(); 036 037 038 /** 039 * Factorization engine for integer base coefficients. 040 */ 041 protected final FactorAbstract<BigInteger> iengine; 042 043 044 /** 045 * No argument constructor. 046 */ 047 protected FactorRational() { 048 super(BigRational.ONE); 049 iengine = FactorFactory.getImplementation(BigInteger.ONE); 050 } 051 052 053 /** 054 * GenPolynomial base factorization of a squarefree polynomial. 055 * @param P squarefree GenPolynomial. 056 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 057 */ 058 @Override 059 public List<GenPolynomial<BigRational>> baseFactorsSquarefree(GenPolynomial<BigRational> P) { 060 if (P == null) { 061 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 062 } 063 List<GenPolynomial<BigRational>> factors = new ArrayList<GenPolynomial<BigRational>>(); 064 if (P.isZERO()) { 065 return factors; 066 } 067 if (P.isONE()) { 068 factors.add(P); 069 return factors; 070 } 071 GenPolynomialRing<BigRational> pfac = P.ring; 072 if (pfac.nvar > 1) { 073 throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials"); 074 } 075 GenPolynomial<BigRational> Pr = P; 076 BigRational ldcf = P.leadingBaseCoefficient(); 077 if (!ldcf.isONE()) { 078 //System.out.println("ldcf = " + ldcf); 079 Pr = Pr.monic(); 080 } 081 BigInteger bi = BigInteger.ONE; 082 GenPolynomialRing<BigInteger> ifac = new GenPolynomialRing<BigInteger>(bi, pfac); 083 GenPolynomial<BigInteger> Pi = PolyUtil.integerFromRationalCoefficients(ifac, Pr); 084 if (debug) { 085 logger.info("Pi = " + Pi); 086 } 087 List<GenPolynomial<BigInteger>> ifacts = iengine.baseFactorsSquarefree(Pi); 088 if (logger.isInfoEnabled()) { 089 logger.info("ifacts = " + ifacts); 090 } 091 if (ifacts.size() <= 1) { 092 factors.add(P); 093 return factors; 094 } 095 List<GenPolynomial<BigRational>> rfacts = PolyUtil.fromIntegerCoefficients(pfac, ifacts); 096 //System.out.println("rfacts = " + rfacts); 097 rfacts = PolyUtil.monic(rfacts); 098 //System.out.println("rfacts = " + rfacts); 099 if (!ldcf.isONE()) { 100 GenPolynomial<BigRational> r = rfacts.get(0); 101 rfacts.remove(r); 102 r = r.multiply(ldcf); 103 rfacts.set(0, r); 104 } 105 if (logger.isInfoEnabled()) { 106 logger.info("rfacts = " + rfacts); 107 } 108 factors.addAll(rfacts); 109 return factors; 110 } 111 112 113 /** 114 * GenPolynomial factorization of a squarefree polynomial. 115 * @param P squarefree GenPolynomial. 116 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 117 */ 118 @Override 119 public List<GenPolynomial<BigRational>> factorsSquarefree(GenPolynomial<BigRational> P) { 120 if (P == null) { 121 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 122 } 123 List<GenPolynomial<BigRational>> factors = new ArrayList<GenPolynomial<BigRational>>(); 124 if (P.isZERO()) { 125 return factors; 126 } 127 if (P.isONE()) { 128 factors.add(P); 129 return factors; 130 } 131 GenPolynomialRing<BigRational> pfac = P.ring; 132 if (pfac.nvar == 1) { 133 return baseFactorsSquarefree(P); 134 } 135 GenPolynomial<BigRational> Pr = P; 136 BigRational ldcf = P.leadingBaseCoefficient(); 137 if (!ldcf.isONE()) { 138 //System.out.println("ldcf = " + ldcf); 139 Pr = Pr.monic(); 140 } 141 BigInteger bi = BigInteger.ONE; 142 GenPolynomialRing<BigInteger> ifac = new GenPolynomialRing<BigInteger>(bi, pfac); 143 GenPolynomial<BigInteger> Pi = PolyUtil.integerFromRationalCoefficients(ifac, Pr); 144 if (debug) { 145 logger.info("Pi = " + Pi); 146 } 147 List<GenPolynomial<BigInteger>> ifacts = iengine.factorsSquarefree(Pi); 148 if (logger.isInfoEnabled()) { 149 logger.info("ifacts = " + ifacts); 150 } 151 if (ifacts.size() <= 1) { 152 factors.add(P); 153 return factors; 154 } 155 List<GenPolynomial<BigRational>> rfacts = PolyUtil.fromIntegerCoefficients(pfac, ifacts); 156 //System.out.println("rfacts = " + rfacts); 157 rfacts = PolyUtil.monic(rfacts); 158 //System.out.println("rfacts = " + rfacts); 159 if (!ldcf.isONE()) { 160 GenPolynomial<BigRational> r = rfacts.get(0); 161 rfacts.remove(r); 162 r = r.multiply(ldcf); 163 rfacts.set(0, r); 164 } 165 if (logger.isInfoEnabled()) { 166 logger.info("rfacts = " + rfacts); 167 } 168 factors.addAll(rfacts); 169 return factors; 170 } 171 172 173 /** 174 * GenPolynomial factorization of a polynomial. 175 * @param P GenPolynomial. 176 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 177 * p_i**e_i and p_i irreducible. 178 */ 179 @Override 180 public SortedMap<GenPolynomial<BigRational>, Long> factors(GenPolynomial<BigRational> P) { 181 if (P == null) { 182 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 183 } 184 GenPolynomialRing<BigRational> pfac = P.ring; 185 SortedMap<GenPolynomial<BigRational>, Long> factors = new TreeMap<GenPolynomial<BigRational>, Long>(pfac.getComparator()); 186 if (P.isZERO()) { 187 return factors; 188 } 189 if (P.isONE()) { 190 factors.put(P, 1L); 191 return factors; 192 } 193 if (pfac.nvar == 1) { 194 return baseFactors(P); 195 } 196 GenPolynomial<BigRational> Pr = P; 197 BigInteger bi = BigInteger.ONE; 198 GenPolynomialRing<BigInteger> ifac = new GenPolynomialRing<BigInteger>(bi, pfac); 199 GenPolynomial<BigInteger> Pi = PolyUtil.integerFromRationalCoefficients(ifac, Pr); 200 if (debug) { 201 logger.info("Pi = " + Pi); 202 } 203 SortedMap<GenPolynomial<BigInteger>, Long> ifacts = iengine.factors(Pi); 204 if (logger.isInfoEnabled()) { 205 logger.info("ifacts = " + ifacts); 206 } 207 for (Map.Entry<GenPolynomial<BigInteger>, Long> me : ifacts.entrySet()) { 208 GenPolynomial<BigInteger> g = me.getKey(); 209 if (g.isONE()) { // skip 1 210 continue; 211 } 212 Long d = me.getValue(); // facs.get(g); 213 GenPolynomial<BigRational> rp = PolyUtil.fromIntegerCoefficients(pfac, g); 214 factors.put(rp, d); 215 } 216 return factors; 217 } 218 219}