001 /* 002 * $Id: FactorRational.java 3733 2011-08-13 20:08:25Z 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.arith.BigInteger; 014 import edu.jas.arith.BigRational; 015 import edu.jas.poly.GenPolynomial; 016 import edu.jas.poly.GenPolynomialRing; 017 import edu.jas.poly.PolyUtil; 018 019 020 /** 021 * Rational number coefficients factorization algorithms. 022 * This class implements factorization methods for polynomials over rational numbers. 023 * @author Heinz Kredel 024 */ 025 026 public class FactorRational extends FactorAbsolute<BigRational> { 027 028 029 private static final Logger logger = Logger.getLogger(FactorRational.class); 030 031 032 private final boolean debug = true || logger.isInfoEnabled(); 033 034 035 /** 036 * Factorization engine for integer base coefficients. 037 */ 038 protected final FactorAbstract<BigInteger> iengine; 039 040 041 /** 042 * No argument constructor. 043 */ 044 protected FactorRational() { 045 super( BigRational.ONE ); 046 iengine = FactorFactory.getImplementation( BigInteger.ONE ); 047 } 048 049 050 /** 051 * GenPolynomial base factorization of a squarefree polynomial. 052 * @param P squarefree GenPolynomial. 053 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 054 */ 055 @Override 056 public List<GenPolynomial<BigRational>> baseFactorsSquarefree(GenPolynomial<BigRational> P) { 057 if (P == null) { 058 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 059 } 060 List<GenPolynomial<BigRational>> factors = new ArrayList<GenPolynomial<BigRational>>(); 061 if (P.isZERO()) { 062 return factors; 063 } 064 if (P.isONE()) { 065 factors.add(P); 066 return factors; 067 } 068 GenPolynomialRing<BigRational> pfac = P.ring; 069 if (pfac.nvar > 1) { 070 throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials"); 071 } 072 GenPolynomial<BigRational> Pr = P; 073 BigRational ldcf = P.leadingBaseCoefficient(); 074 if (!ldcf.isONE()) { 075 //System.out.println("ldcf = " + ldcf); 076 Pr = Pr.monic(); 077 } 078 BigInteger bi = BigInteger.ONE; 079 GenPolynomialRing<BigInteger> ifac = new GenPolynomialRing<BigInteger>(bi, pfac); 080 GenPolynomial<BigInteger> Pi = PolyUtil.integerFromRationalCoefficients(ifac, Pr); 081 if (debug) { 082 logger.info("Pi = " + Pi); 083 } 084 List<GenPolynomial<BigInteger>> ifacts = iengine.baseFactorsSquarefree(Pi); 085 if (logger.isInfoEnabled()) { 086 logger.info("ifacts = " + ifacts); 087 } 088 if (ifacts.size() <= 1) { 089 factors.add(P); 090 return factors; 091 } 092 List<GenPolynomial<BigRational>> rfacts = PolyUtil.fromIntegerCoefficients(pfac, ifacts); 093 //System.out.println("rfacts = " + rfacts); 094 rfacts = PolyUtil.monic(rfacts); 095 //System.out.println("rfacts = " + rfacts); 096 if ( !ldcf.isONE() ) { 097 GenPolynomial<BigRational> r = rfacts.get(0); 098 rfacts.remove(r); 099 r = r.multiply(ldcf); 100 rfacts.set(0, r); 101 } 102 if (logger.isInfoEnabled()) { 103 logger.info("rfacts = " + rfacts); 104 } 105 factors.addAll(rfacts); 106 return factors; 107 } 108 109 110 /** 111 * GenPolynomial factorization of a squarefree polynomial. 112 * @param P squarefree GenPolynomial. 113 * @return [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i. 114 */ 115 @Override 116 public List<GenPolynomial<BigRational>> factorsSquarefree(GenPolynomial<BigRational> P) { 117 if (P == null) { 118 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 119 } 120 List<GenPolynomial<BigRational>> factors = new ArrayList<GenPolynomial<BigRational>>(); 121 if (P.isZERO()) { 122 return factors; 123 } 124 if (P.isONE()) { 125 factors.add(P); 126 return factors; 127 } 128 GenPolynomialRing<BigRational> pfac = P.ring; 129 if (pfac.nvar == 1) { 130 return baseFactorsSquarefree(P); 131 } 132 GenPolynomial<BigRational> Pr = P; 133 BigRational ldcf = P.leadingBaseCoefficient(); 134 if (!ldcf.isONE()) { 135 //System.out.println("ldcf = " + ldcf); 136 Pr = Pr.monic(); 137 } 138 BigInteger bi = BigInteger.ONE; 139 GenPolynomialRing<BigInteger> ifac = new GenPolynomialRing<BigInteger>(bi, pfac); 140 GenPolynomial<BigInteger> Pi = PolyUtil.integerFromRationalCoefficients(ifac, Pr); 141 if (debug) { 142 logger.info("Pi = " + Pi); 143 } 144 List<GenPolynomial<BigInteger>> ifacts = iengine.factorsSquarefree(Pi); 145 if (logger.isInfoEnabled()) { 146 logger.info("ifacts = " + ifacts); 147 } 148 if (ifacts.size() <= 1) { 149 factors.add(P); 150 return factors; 151 } 152 List<GenPolynomial<BigRational>> rfacts = PolyUtil.fromIntegerCoefficients(pfac, ifacts); 153 //System.out.println("rfacts = " + rfacts); 154 rfacts = PolyUtil.monic(rfacts); 155 //System.out.println("rfacts = " + rfacts); 156 if ( !ldcf.isONE() ) { 157 GenPolynomial<BigRational> r = rfacts.get(0); 158 rfacts.remove(r); 159 r = r.multiply(ldcf); 160 rfacts.set(0, r); 161 } 162 if (logger.isInfoEnabled()) { 163 logger.info("rfacts = " + rfacts); 164 } 165 factors.addAll(rfacts); 166 return factors; 167 } 168 169 }