001/* 002 * $Id: SquarefreeFiniteFieldCharP.java 5871 2018-07-20 15:58:45Z kredel $ 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 if (logger.isInfoEnabled()) { 139 logger.info("sf = " + sf); 140 } 141 // better: test if sf.size() == 1 // not ok 142 Long k = null; 143 for (Map.Entry<GenPolynomial<C>, Long> me : sf.entrySet()) { 144 GenPolynomial<C> p = me.getKey(); 145 if (p.isConstant()) { 146 //System.out.println("p,const = " + p); 147 continue; 148 } 149 Long e = me.getValue(); //sf.get(p); 150 java.math.BigInteger E = new java.math.BigInteger(e.toString()); 151 java.math.BigInteger r = E.remainder(c); 152 if (!r.equals(java.math.BigInteger.ZERO)) { 153 //System.out.println("r = " + r); 154 return null; 155 } 156 if (k == null) { 157 k = e; 158 } else if (k.compareTo(e) >= 0) { 159 k = e; 160 } 161 } 162 // now c divides all exponents 163 Long cl = c.longValue(); 164 GenPolynomial<C> rp = P.ring.getONE(); 165 for (Map.Entry<GenPolynomial<C>, Long> me : sf.entrySet()) { 166 GenPolynomial<C> q = me.getKey(); 167 Long e = me.getValue(); // sf.get(q); 168 if (q.isConstant()) { // ensure p-th root 169 C qc = q.leadingBaseCoefficient(); 170 //System.out.println("qc,const = " + qc + ", e = " + e); 171 if (e > 1L) { 172 qc = qc.power(e); //Power.<C> positivePower(qc, e); 173 //e = 1L; 174 } 175 C qr = coeffRootCharacteristic(qc); 176 //System.out.println("qr,const = " + qr); 177 q = P.ring.getONE().multiply(qr); 178 root.put(q, 1L); 179 continue; 180 } 181 if (e > k) { 182 long ep = e / cl; 183 q = q.power(ep); //Power.<GenPolynomial<C>> positivePower(q, ep); 184 } 185 rp = rp.multiply(q); 186 } 187 if (k != null) { 188 k = k / cl; 189 root.put(rp, k); 190 } 191 //System.out.println("sf,root = " + root); 192 return root; 193 } 194 195 196 /** 197 * GenPolynomial char-th root univariate polynomial. Base coefficient type 198 * must be finite field, that is ModInteger or 199 * AlgebraicNumber<ModInteger> etc. 200 * @param P GenPolynomial. 201 * @return char-th_rootOf(P), or null if no char-th root. 202 */ 203 @Override 204 public GenPolynomial<C> baseRootCharacteristic(GenPolynomial<C> P) { 205 if (P == null || P.isZERO()) { 206 return P; 207 } 208 GenPolynomialRing<C> pfac = P.ring; 209 if (pfac.nvar > 1) { 210 // basePthRoot not possible by return type 211 throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); 212 } 213 RingFactory<C> rf = pfac.coFac; 214 if (rf.characteristic().signum() != 1) { 215 // basePthRoot not possible 216 throw new IllegalArgumentException(P.getClass().getName() + " only for char p > 0 " + rf); 217 } 218 long mp = rf.characteristic().longValue(); 219 GenPolynomial<C> d = pfac.getZERO().copy(); 220 for (Monomial<C> m : P) { 221 ExpVector f = m.e; 222 long fl = f.getVal(0); 223 if (fl % mp != 0) { 224 return null; 225 } 226 fl = fl / mp; 227 ExpVector e = ExpVector.create(1, 0, fl); 228 // for m.c exists a char-th root, since finite field 229 C r = coeffRootCharacteristic(m.c); 230 d.doPutToMap(e, r); 231 } 232 return d; 233 } 234 235 236 /** 237 * GenPolynomial char-th root univariate polynomial with polynomial 238 * coefficients. 239 * @param P recursive univariate GenPolynomial. 240 * @return char-th_rootOf(P), or null if P is no char-th root. 241 */ 242 @Override 243 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateRootCharacteristic( 244 GenPolynomial<GenPolynomial<C>> P) { 245 if (P == null || P.isZERO()) { 246 return P; 247 } 248 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 249 if (pfac.nvar > 1) { 250 // basePthRoot not possible by return type 251 throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); 252 } 253 RingFactory<GenPolynomial<C>> rf = pfac.coFac; 254 if (rf.characteristic().signum() != 1) { 255 // basePthRoot not possible 256 throw new IllegalArgumentException(P.getClass().getName() + " only for char p > 0 " + rf); 257 } 258 long mp = rf.characteristic().longValue(); 259 GenPolynomial<GenPolynomial<C>> d = pfac.getZERO().copy(); 260 for (Monomial<GenPolynomial<C>> m : P) { 261 ExpVector f = m.e; 262 long fl = f.getVal(0); 263 if (fl % mp != 0) { 264 return null; 265 } 266 fl = fl / mp; 267 SortedMap<GenPolynomial<C>, Long> sm = rootCharacteristic(m.c); 268 if (sm == null) { 269 return null; 270 } 271 if (logger.isInfoEnabled()) { 272 logger.info("sm,rec = " + sm); 273 } 274 GenPolynomial<C> r = rf.getONE(); 275 for (Map.Entry<GenPolynomial<C>, Long> me : sm.entrySet()) { 276 GenPolynomial<C> rp = me.getKey(); 277 long gl = me.getValue(); //sm.get(rp); 278 if (gl > 1) { 279 rp = rp.power(gl); //Power.<GenPolynomial<C>> positivePower(rp, gl); 280 } 281 r = r.multiply(rp); 282 } 283 ExpVector e = ExpVector.create(1, 0, fl); 284 //System.out.println("put-root r = " + r + ", e = " + e); 285 d.doPutToMap(e, r); 286 } 287 return d; 288 } 289 290}