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.Logger; 013import org.apache.logging.log4j.LogManager; 014 015import edu.jas.arith.BigInteger; 016import edu.jas.poly.ExpVector; 017import edu.jas.poly.GenPolynomial; 018import edu.jas.poly.GenPolynomialRing; 019import edu.jas.poly.Monomial; 020import edu.jas.structure.GcdRingElem; 021import edu.jas.structure.Power; 022import edu.jas.structure.RingFactory; 023 024 025/** 026 * Squarefree decomposition for finite coefficient fields of characteristic p. 027 * @author Heinz Kredel 028 */ 029 030public class SquarefreeFiniteFieldCharP<C extends GcdRingElem<C>> extends SquarefreeFieldCharP<C> { 031 032 033 private static final Logger logger = LogManager.getLogger(SquarefreeFiniteFieldCharP.class); 034 035 036 //private static final boolean debug = logger.isDebugEnabled(); 037 038 039 /** 040 * Constructor. 041 */ 042 public SquarefreeFiniteFieldCharP(RingFactory<C> fac) { 043 super(fac); 044 // isFinite() predicate now present 045 if (!fac.isFinite()) { 046 throw new IllegalArgumentException("fac must be finite"); 047 } 048 } 049 050 051 /* --------- char-th roots --------------------- */ 052 053 /** 054 * Characteristics root of a coefficient. <b>Note:</b> not needed at the 055 * moment. 056 * @param p coefficient. 057 * @return [p -> k] if exists k with e=k*charactristic(c) and c = p**e, 058 * else null. 059 */ 060 public SortedMap<C, Long> rootCharacteristic(C p) { 061 if (p == null) { 062 throw new IllegalArgumentException(this.getClass().getName() + " p == null"); 063 } 064 // already checked in constructor: 065 //java.math.BigInteger c = p.factory().characteristic(); 066 //if ( c.signum() == 0 ) { 067 // return null; 068 //} 069 SortedMap<C, Long> root = new TreeMap<C, Long>(); 070 if (p.isZERO()) { 071 return root; 072 } 073 // true for finite fields: 074 root.put(p, 1L); 075 return root; 076 } 077 078 079 /** 080 * Characteristics root of a coefficient. 081 * @param c coefficient. 082 * @return r with r**p == c, if such an r exists, else null. 083 */ 084 public C coeffRootCharacteristic(C c) { 085 if (c == null || c.isZERO()) { 086 return c; 087 } 088 C r = c; 089 if (aCoFac == null && qCoFac == null) { 090 // case ModInteger: c**p == c 091 return r; 092 } 093 if (aCoFac != null) { 094 // case AlgebraicNumber<ModInteger>: r = c**(p**(d-1)), r**p == c 095 long d = aCoFac.totalExtensionDegree(); 096 //System.out.println("d = " + d); 097 if (d <= 1) { 098 return r; 099 } 100 BigInteger p = new BigInteger(aCoFac.characteristic()); 101 BigInteger q = p.power(d - 1); 102 //System.out.println("p**(d-1) = " + q); 103 r = Power.<C> positivePower(r, q.getVal()); // r = r.power(q.getVal()); 104 //System.out.println("r**q = " + r); 105 return r; 106 } 107 if (qCoFac != null) { 108 throw new UnsupportedOperationException("case QuotientRing not yet implemented"); 109 } 110 return r; 111 } 112 113 114 /** 115 * Characteristics root of a polynomial. <b>Note:</b> call only in 116 * recursion. 117 * @param P polynomial. 118 * @return [p -> k] if exists k with e=k*charactristic(P) and P = p**e, 119 * else null. 120 */ 121 public SortedMap<GenPolynomial<C>, Long> rootCharacteristic(GenPolynomial<C> P) { 122 if (P == null) { 123 throw new IllegalArgumentException(this.getClass().getName() + " P == null"); 124 } 125 java.math.BigInteger c = P.ring.characteristic(); 126 if (c.signum() == 0) { 127 return null; 128 } 129 SortedMap<GenPolynomial<C>, Long> root = new TreeMap<GenPolynomial<C>, Long>(); 130 if (P.isZERO()) { 131 return root; 132 } 133 if (P.isONE()) { 134 root.put(P, 1L); 135 return root; 136 } 137 SortedMap<GenPolynomial<C>, Long> sf = squarefreeFactors(P); 138 logger.info("sf = {}", sf); 139 // better: test if sf.size() == 1 // not ok 140 Long k = null; 141 for (Map.Entry<GenPolynomial<C>, Long> me : sf.entrySet()) { 142 GenPolynomial<C> p = me.getKey(); 143 if (p.isConstant()) { 144 //System.out.println("p,const = " + p); 145 continue; 146 } 147 Long e = me.getValue(); //sf.get(p); 148 java.math.BigInteger E = new java.math.BigInteger(e.toString()); 149 java.math.BigInteger r = E.remainder(c); 150 if (!r.equals(java.math.BigInteger.ZERO)) { 151 //System.out.println("r = " + r); 152 return null; 153 } 154 if (k == null) { 155 k = e; 156 } else if (k.compareTo(e) >= 0) { 157 k = e; 158 } 159 } 160 // now c divides all exponents 161 long cl = c.longValueExact(); 162 GenPolynomial<C> rp = P.ring.getONE(); 163 for (Map.Entry<GenPolynomial<C>, Long> me : sf.entrySet()) { 164 GenPolynomial<C> q = me.getKey(); 165 Long e = me.getValue(); // sf.get(q); 166 if (q.isConstant()) { // ensure p-th root 167 C qc = q.leadingBaseCoefficient(); 168 //System.out.println("qc,const = " + qc + ", e = " + e); 169 if (e > 1L) { 170 qc = qc.power(e); //Power.<C> positivePower(qc, e); 171 //e = 1L; 172 } 173 C qr = coeffRootCharacteristic(qc); 174 //System.out.println("qr,const = " + qr); 175 q = P.ring.getONE().multiply(qr); 176 root.put(q, 1L); 177 continue; 178 } 179 if (e > k) { 180 long ep = e / cl; 181 q = q.power(ep); //Power.<GenPolynomial<C>> positivePower(q, ep); 182 } 183 rp = rp.multiply(q); 184 } 185 if (k != null) { 186 k = k / cl; 187 root.put(rp, k); 188 } 189 //System.out.println("sf,root = " + root); 190 return root; 191 } 192 193 194 /** 195 * GenPolynomial char-th root univariate polynomial. Base coefficient type 196 * must be finite field, that is ModInteger or 197 * AlgebraicNumber<ModInteger> etc. 198 * @param P GenPolynomial. 199 * @return char-th_rootOf(P), or null if no char-th root. 200 */ 201 @Override 202 public GenPolynomial<C> baseRootCharacteristic(GenPolynomial<C> P) { 203 if (P == null || P.isZERO()) { 204 return P; 205 } 206 GenPolynomialRing<C> pfac = P.ring; 207 if (pfac.nvar > 1) { 208 // basePthRoot not possible by return type 209 throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); 210 } 211 RingFactory<C> rf = pfac.coFac; 212 if (rf.characteristic().signum() != 1) { 213 // basePthRoot not possible 214 throw new IllegalArgumentException(P.getClass().getName() + " only for char p > 0 " + rf); 215 } 216 long mp = rf.characteristic().longValueExact(); 217 GenPolynomial<C> d = pfac.getZERO().copy(); 218 for (Monomial<C> m : P) { 219 ExpVector f = m.e; 220 long fl = f.getVal(0); 221 if (fl % mp != 0) { 222 return null; 223 } 224 fl = fl / mp; 225 ExpVector e = ExpVector.create(1, 0, fl); 226 // for m.c exists a char-th root, since finite field 227 C r = coeffRootCharacteristic(m.c); 228 d.doPutToMap(e, r); 229 } 230 return d; 231 } 232 233 234 /** 235 * GenPolynomial char-th root univariate polynomial with polynomial 236 * coefficients. 237 * @param P recursive univariate GenPolynomial. 238 * @return char-th_rootOf(P), or null if P is no char-th root. 239 */ 240 @Override 241 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateRootCharacteristic( 242 GenPolynomial<GenPolynomial<C>> P) { 243 if (P == null || P.isZERO()) { 244 return P; 245 } 246 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 247 if (pfac.nvar > 1) { 248 // basePthRoot not possible by return type 249 throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); 250 } 251 RingFactory<GenPolynomial<C>> rf = pfac.coFac; 252 if (rf.characteristic().signum() != 1) { 253 // basePthRoot not possible 254 throw new IllegalArgumentException(P.getClass().getName() + " only for char p > 0 " + rf); 255 } 256 long mp = rf.characteristic().longValueExact(); 257 GenPolynomial<GenPolynomial<C>> d = pfac.getZERO().copy(); 258 for (Monomial<GenPolynomial<C>> m : P) { 259 ExpVector f = m.e; 260 long fl = f.getVal(0); 261 if (fl % mp != 0) { 262 return null; 263 } 264 fl = fl / mp; 265 SortedMap<GenPolynomial<C>, Long> sm = rootCharacteristic(m.c); 266 if (sm == null) { 267 return null; 268 } 269 logger.info("sm,rec = {}", sm); 270 GenPolynomial<C> r = rf.getONE(); 271 for (Map.Entry<GenPolynomial<C>, Long> me : sm.entrySet()) { 272 GenPolynomial<C> rp = me.getKey(); 273 long gl = me.getValue(); //sm.get(rp); 274 if (gl > 1) { 275 rp = rp.power(gl); //Power.<GenPolynomial<C>> positivePower(rp, gl); 276 } 277 r = r.multiply(rp); 278 } 279 ExpVector e = ExpVector.create(1, 0, fl); 280 //System.out.println("put-root r = " + r + ", e = " + e); 281 d.doPutToMap(e, r); 282 } 283 return d; 284 } 285 286}