001/* 002 * $Id$ 003 */ 004 005package edu.jas.ufd; 006 007 008import java.util.Map; 009import java.util.SortedMap; 010import java.util.TreeMap; 011 012import org.apache.logging.log4j.LogManager; 013import org.apache.logging.log4j.Logger; 014 015import edu.jas.poly.ExpVector; 016import edu.jas.poly.GenPolynomial; 017import edu.jas.poly.GenPolynomialRing; 018import edu.jas.poly.PolyUtil; 019import edu.jas.structure.GcdRingElem; 020import edu.jas.structure.RingFactory; 021 022 023/** 024 * Squarefree decomposition for coefficient fields of characteristic 0, 025 * algorithm of Yun. 026 * @author Heinz Kredel 027 */ 028 029public class SquarefreeFieldChar0Yun<C extends GcdRingElem<C>> extends SquarefreeFieldChar0<C> { 030 031 032 private static final Logger logger = LogManager.getLogger(SquarefreeFieldChar0Yun.class); 033 034 035 //private static final boolean debug = logger.isDebugEnabled(); 036 037 038 /** 039 * Constructor. 040 */ 041 public SquarefreeFieldChar0Yun(RingFactory<C> fac) { 042 super(fac); 043 } 044 045 046 /** 047 * Get the String representation. 048 * @see java.lang.Object#toString() 049 */ 050 @Override 051 public String toString() { 052 return getClass().getName() + " with " + engine + " over " + coFac; 053 } 054 055 056 /** 057 * GenPolynomial polynomial squarefree factorization. 058 * @param A GenPolynomial. 059 * @return [p_1 -> e_1, ..., p_k -> e_k] with A = prod_{i=1,...,k} 060 * p_i^{e_i} and p_i squarefree and gcd(p_i, p_j) = 1, for i != j. 061 */ 062 @Override 063 public SortedMap<GenPolynomial<C>, Long> baseSquarefreeFactors(GenPolynomial<C> A) { 064 SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); 065 if (A == null || A.isZERO()) { 066 return sfactors; 067 } 068 if (A.isConstant()) { 069 sfactors.put(A, 1L); 070 return sfactors; 071 } 072 GenPolynomialRing<C> pfac = A.ring; 073 if (pfac.nvar > 1) { 074 throw new IllegalArgumentException( 075 this.getClass().getName() + " only for univariate polynomials"); 076 } 077 C ldbcf = A.leadingBaseCoefficient(); 078 if (!ldbcf.isONE()) { 079 A = A.divide(ldbcf); 080 GenPolynomial<C> f1 = pfac.getONE().multiply(ldbcf); 081 //System.out.println("gcda sqf f1 = " + f1); 082 sfactors.put(f1, 1L); 083 ldbcf = pfac.coFac.getONE(); 084 } 085 // divide by trailing term 086 ExpVector et = A.trailingExpVector(); 087 if (!et.isZERO()) { 088 GenPolynomial<C> tr = pfac.valueOf(et); 089 if (logger.isInfoEnabled()) { 090 logger.info("trailing term = " + tr); 091 } 092 A = PolyUtil.<C> basePseudoDivide(A, tr); 093 long ep = et.getVal(0); // univariate 094 et = et.subst(0, 1); 095 tr = pfac.valueOf(et); 096 if (logger.isInfoEnabled()) { 097 logger.info("tr, ep = " + tr + ", " + ep); 098 } 099 sfactors.put(tr, ep); 100 if (A.length() == 1) { 101 return sfactors; 102 } 103 } 104 GenPolynomial<C> Tp, T, W, Y, Z; 105 long k = 1L; //0L 106 Tp = PolyUtil.<C> baseDeriviative(A); 107 T = engine.baseGcd(A, Tp); 108 T = T.monic(); 109 if (T.isConstant()) { 110 sfactors.put(A, k); 111 return sfactors; 112 } 113 W = PolyUtil.<C> basePseudoDivide(A, T); 114 //if (W.isConstant()) { 115 // return sfactors; 116 //} 117 Y = PolyUtil.<C> basePseudoDivide(Tp, T); 118 GenPolynomial<C> Wp = PolyUtil.<C> baseDeriviative(W); 119 Z = Y.subtract(Wp); 120 while (!Z.isZERO()) { 121 GenPolynomial<C> g = engine.baseGcd(W, Z); 122 g = g.monic(); 123 if (!g.isONE()) { 124 sfactors.put(g, k); 125 } 126 W = PolyUtil.<C> basePseudoDivide(W, g); 127 //System.out.println("W = " + W); 128 //System.out.println("g = " + g); 129 Y = PolyUtil.<C> basePseudoDivide(Z, g); 130 Wp = PolyUtil.<C> baseDeriviative(W); 131 Z = Y.subtract(Wp); 132 k++; 133 } 134 logger.info("W, k = " + W + ", " + k); 135 if (!W.isONE()) { 136 sfactors.put(W, k); 137 } 138 return normalizeFactorization(sfactors); 139 } 140 141 142 /** 143 * GenPolynomial recursive univariate polynomial squarefree factorization. 144 * @param P recursive univariate GenPolynomial. 145 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 146 * p_i^{e_i} and p_i squarefree and gcd(p_i, p_j) = 1, for i != j. 147 */ 148 @Override 149 public SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveUnivariateSquarefreeFactors( 150 GenPolynomial<GenPolynomial<C>> P) { 151 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> sfactors = new TreeMap<GenPolynomial<GenPolynomial<C>>, Long>(); 152 if (P == null || P.isZERO()) { 153 return sfactors; 154 } 155 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 156 if (pfac.nvar > 1) { 157 // recursiveContent not possible by return type 158 throw new IllegalArgumentException( 159 this.getClass().getName() + " only for univariate polynomials"); 160 } 161 // if base coefficient ring is a field, make monic 162 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac; 163 C ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); 164 if (!ldbcf.isONE()) { 165 GenPolynomial<C> lc = cfac.getONE().multiply(ldbcf); 166 GenPolynomial<GenPolynomial<C>> pl = pfac.getONE().multiply(lc); 167 sfactors.put(pl, 1L); 168 C li = ldbcf.inverse(); 169 //System.out.println("li = " + li); 170 P = P.multiply(cfac.getONE().multiply(li)); 171 //System.out.println("P,monic = " + P); 172 ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); 173 } 174 // factors of content 175 GenPolynomial<C> Pc = engine.recursiveContent(P); 176 if (logger.isInfoEnabled()) { 177 logger.info("recursiveContent = " + Pc); 178 } 179 Pc = Pc.monic(); 180 if (!Pc.isONE()) { 181 P = PolyUtil.<C> coefficientPseudoDivide(P, Pc); 182 } 183 SortedMap<GenPolynomial<C>, Long> rsf = squarefreeFactors(Pc); 184 if (logger.isInfoEnabled()) { 185 logger.info("squarefreeFactors = " + rsf); 186 } 187 // add factors of content 188 for (Map.Entry<GenPolynomial<C>, Long> me : rsf.entrySet()) { 189 GenPolynomial<C> c = me.getKey(); 190 if (!c.isONE()) { 191 GenPolynomial<GenPolynomial<C>> cr = pfac.getONE().multiply(c); 192 Long rk = me.getValue(); 193 sfactors.put(cr, rk); 194 } 195 } 196 // divide by trailing term 197 ExpVector et = P.trailingExpVector(); 198 if (!et.isZERO()) { 199 GenPolynomial<GenPolynomial<C>> tr = pfac.valueOf(et); 200 if (logger.isInfoEnabled()) { 201 logger.info("trailing term = " + tr); 202 } 203 P = PolyUtil.<C> recursivePseudoDivide(P, tr); 204 long ep = et.getVal(0); // univariate 205 et = et.subst(0, 1); 206 tr = pfac.valueOf(et); 207 sfactors.put(tr, ep); 208 //P.length == 1 ?? 209 } 210 // factors of recursive polynomial 211 GenPolynomial<GenPolynomial<C>> Tp, T, W, Y, Z; 212 long k = 1L; //0L 213 Tp = PolyUtil.<C> recursiveDeriviative(P); 214 T = engine.recursiveUnivariateGcd(P, Tp); 215 T = PolyUtil.<C> monic(T); 216 if (T.isConstant()) { 217 sfactors.put(P, k); 218 return sfactors; 219 } 220 W = PolyUtil.<C> recursivePseudoDivide(P, T); 221 //if (W.isConstant()) { 222 // return sfactors; 223 //} 224 Y = PolyUtil.<C> recursivePseudoDivide(Tp, T); 225 GenPolynomial<GenPolynomial<C>> Wp = PolyUtil.<C> recursiveDeriviative(W); 226 Z = Y.subtract(Wp); 227 228 while (!Z.isZERO()) { 229 GenPolynomial<GenPolynomial<C>> g = engine.recursiveGcd(W, Z); 230 g = PolyUtil.<C> monic(g); 231 if (!g.isONE()) { 232 sfactors.put(g, k); 233 } 234 W = PolyUtil.<C> recursivePseudoDivide(W, g); 235 //System.out.println("W = " + W); 236 //System.out.println("g = " + g); 237 Y = PolyUtil.<C> recursivePseudoDivide(Z, g); 238 Wp = PolyUtil.<C> recursiveDeriviative(W); 239 Z = Y.subtract(Wp); 240 k++; 241 } 242 logger.info("W, k = " + W + ", " + k); 243 if (!W.isONE()) { 244 sfactors.put(W, k); 245 } 246 return sfactors; //normalizeFactorization(sfactors); 247 } 248 249}