001/* 002 * $Id: SquarefreeFieldCharP.java 6022 2020-11-24 10:56:01Z 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.poly.AlgebraicNumber; 016import edu.jas.poly.AlgebraicNumberRing; 017import edu.jas.poly.ExpVector; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.PolyUtil; 021import edu.jas.structure.GcdRingElem; 022import edu.jas.structure.RingFactory; 023 024 025/** 026 * Squarefree decomposition for coefficient fields of characteristic p. 027 * @author Heinz Kredel 028 */ 029 030public abstract class SquarefreeFieldCharP<C extends GcdRingElem<C>> extends SquarefreeAbstract<C> { 031 032 033 private static final Logger logger = LogManager.getLogger(SquarefreeFieldCharP.class); 034 035 036 private static final boolean debug = logger.isDebugEnabled(); 037 038 039 /* 040 * Squarefree engine for characteristic p base coefficients. 041 */ 042 //protected final SquarefreeAbstract<C> rengine; 043 044 045 /** 046 * Factory for finite field of characteristic p coefficients. 047 */ 048 protected final RingFactory<C> coFac; 049 050 051 /** 052 * Factory for a algebraic extension of a finite field of characteristic p 053 * coefficients. If <code>coFac</code> is an algebraic extension, then 054 * <code>aCoFac</code> is equal to <code>coFac</code>, else 055 * <code>aCoFac</code> is <code>null</code>. 056 */ 057 protected final AlgebraicNumberRing<C> aCoFac; 058 059 060 /** 061 * Factory for a transcendental extension of a finite field of 062 * characteristic p coefficients. If <code>coFac</code> is an transcendental 063 * extension, then <code>qCoFac</code> is equal to <code>coFac</code>, else 064 * <code>qCoFac</code> is <code>null</code>. 065 */ 066 protected final QuotientRing<C> qCoFac; 067 068 069 /** 070 * Constructor. 071 */ 072 @SuppressWarnings("unchecked") 073 public SquarefreeFieldCharP(RingFactory<C> fac) { 074 super(GCDFactory.<C> getProxy(fac)); 075 if (!fac.isField()) { 076 //throw new IllegalArgumentException("fac must be a field: " + fac.toScript()); 077 logger.warn("fac should be a field: " + fac.toScript()); 078 } 079 if (fac.characteristic().signum() == 0) { 080 throw new IllegalArgumentException("characterisic(fac) must be non-zero"); 081 } 082 coFac = fac; 083 Object oFac = coFac; 084 if (oFac instanceof AlgebraicNumberRing) { 085 aCoFac = (AlgebraicNumberRing<C>) oFac; // <C> is not correct 086 //rengine = (SquarefreeAbstract) SquarefreeFactory.getImplementation(aCoFac.ring); 087 qCoFac = null; 088 } else { 089 aCoFac = null; 090 if (oFac instanceof QuotientRing) { 091 qCoFac = (QuotientRing<C>) oFac; // <C> is not correct 092 //rengine = (SquarefreeAbstract) SquarefreeFactory.getImplementation(qCoFac.ring); 093 } else { 094 qCoFac = null; 095 } 096 } 097 } 098 099 100 /** 101 * Get the String representation. 102 * @see java.lang.Object#toString() 103 */ 104 @Override 105 public String toString() { 106 return getClass().getName() + " with " + engine + " over " + coFac; 107 } 108 109 110 /** 111 * GenPolynomial polynomial greatest squarefree divisor. 112 * @param P GenPolynomial. 113 * @return squarefree(pp(P)). 114 */ 115 @Override 116 public GenPolynomial<C> baseSquarefreePart(GenPolynomial<C> P) { 117 if (P == null || P.isZERO()) { 118 return P; 119 } 120 GenPolynomialRing<C> pfac = P.ring; 121 if (pfac.nvar > 1) { 122 throw new IllegalArgumentException( 123 this.getClass().getName() + " only for univariate polynomials"); 124 } 125 GenPolynomial<C> s = pfac.getONE(); 126 SortedMap<GenPolynomial<C>, Long> factors = baseSquarefreeFactors(P); 127 //if (logger.isWarnEnabled()) { 128 // logger.warn("sqfPart, better use sqfFactors, factors = " + factors); 129 //} 130 for (GenPolynomial<C> sp : factors.keySet()) { 131 s = s.multiply(sp); 132 } 133 s = s.monic(); 134 return s; 135 } 136 137 138 /** 139 * GenPolynomial polynomial squarefree factorization. 140 * @param A GenPolynomial. 141 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 142 * p_i^{e_i} and p_i squarefree. 143 */ 144 @Override 145 public SortedMap<GenPolynomial<C>, Long> baseSquarefreeFactors(GenPolynomial<C> A) { 146 SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); 147 if (A == null || A.isZERO()) { 148 return sfactors; 149 } 150 GenPolynomialRing<C> pfac = A.ring; 151 if (A.isConstant()) { 152 C coeff = A.leadingBaseCoefficient(); 153 //System.out.println("coeff = " + coeff + " @ " + coeff.factory()); 154 SortedMap<C, Long> rfactors = squarefreeFactors(coeff); 155 //System.out.println("rfactors,const = " + rfactors); 156 if (rfactors != null && rfactors.size() > 0) { 157 for (Map.Entry<C, Long> me : rfactors.entrySet()) { 158 C c = me.getKey(); 159 if (!c.isONE()) { 160 GenPolynomial<C> cr = pfac.getONE().multiply(c); 161 Long rk = me.getValue(); // rfactors.get(c); 162 sfactors.put(cr, rk); 163 } 164 } 165 } else { 166 sfactors.put(A, 1L); 167 } 168 return sfactors; 169 } 170 if (pfac.nvar > 1) { 171 throw new IllegalArgumentException( 172 this.getClass().getName() + " only for univariate polynomials"); 173 } 174 C ldbcf = A.leadingBaseCoefficient(); 175 if (!ldbcf.isONE()) { 176 A = A.divide(ldbcf); 177 SortedMap<C, Long> rfactors = squarefreeFactors(ldbcf); 178 //System.out.println("rfactors,ldbcf = " + rfactors); 179 if (rfactors != null && rfactors.size() > 0) { 180 for (Map.Entry<C, Long> me : rfactors.entrySet()) { 181 C c = me.getKey(); 182 if (!c.isONE()) { 183 GenPolynomial<C> cr = pfac.getONE().multiply(c); 184 Long rk = me.getValue(); //rfactors.get(c); 185 sfactors.put(cr, rk); 186 } 187 } 188 } else { 189 GenPolynomial<C> f1 = pfac.getONE().multiply(ldbcf); 190 //System.out.println("gcda sqf f1 = " + f1); 191 sfactors.put(f1, 1L); 192 } 193 ldbcf = pfac.coFac.getONE(); 194 } 195 // divide by trailing term 196 ExpVector et = A.trailingExpVector(); 197 if (!et.isZERO()) { 198 GenPolynomial<C> tr = pfac.valueOf(et); 199 if (logger.isInfoEnabled()) { 200 logger.info("trailing term = " + tr); 201 } 202 A = PolyUtil.<C> basePseudoDivide(A, tr); 203 long ep = et.getVal(0); // univariate 204 et = et.subst(0,1); 205 tr = pfac.valueOf(et); 206 if (logger.isInfoEnabled()) { 207 logger.info("tr, ep = " + tr + ", " + ep); 208 } 209 sfactors.put(tr, ep); 210 if (A.length() == 1) { 211 return sfactors; 212 } 213 } 214 GenPolynomial<C> T0 = A; 215 long e = 1L; 216 GenPolynomial<C> Tp; 217 GenPolynomial<C> T = null; 218 GenPolynomial<C> V = null; 219 long k = 0L; 220 long mp = 0L; 221 boolean init = true; 222 while (true) { 223 //System.out.println("T0 = " + T0); 224 if (init) { 225 if (T0.isConstant() || T0.isZERO()) { 226 break; 227 } 228 Tp = PolyUtil.<C> baseDeriviative(T0); 229 T = engine.baseGcd(T0, Tp); 230 T = T.monic(); 231 V = PolyUtil.<C> basePseudoDivide(T0, T); 232 //System.out.println("iT0 = " + T0); 233 //System.out.println("iTp = " + Tp); 234 //System.out.println("iT = " + T); 235 //System.out.println("iV = " + V); 236 //System.out.println("const(iV) = " + V.isConstant()); 237 k = 0L; 238 mp = 0L; 239 init = false; 240 } 241 if (V.isConstant()) { 242 mp = pfac.characteristic().longValue(); // assert != 0 243 //T0 = PolyUtil.<C> baseModRoot(T,mp); 244 T0 = baseRootCharacteristic(T); 245 logger.info("char root: T0 = " + T0 + ", T = " + T); 246 if (T0 == null) { 247 //break; 248 T0 = pfac.getZERO(); 249 } 250 e = e * mp; 251 init = true; 252 continue; 253 } 254 k++; 255 if (mp != 0L && k % mp == 0L) { 256 T = PolyUtil.<C> basePseudoDivide(T, V); 257 System.out.println("k = " + k); 258 //System.out.println("T = " + T); 259 k++; 260 } 261 GenPolynomial<C> W = engine.baseGcd(T, V); 262 W = W.monic(); 263 GenPolynomial<C> z = PolyUtil.<C> basePseudoDivide(V, W); 264 //System.out.println("W = " + W); 265 //System.out.println("z = " + z); 266 V = W; 267 T = PolyUtil.<C> basePseudoDivide(T, V); 268 //System.out.println("V = " + V); 269 //System.out.println("T = " + T); 270 if (z.degree(0) > 0) { 271 if (ldbcf.isONE() && !z.leadingBaseCoefficient().isONE()) { 272 z = z.monic(); 273 //logger.info("z,monic = " + z); 274 } 275 logger.info("z, k = " + z + ", " + k); 276 sfactors.put(z, (e * k)); 277 } 278 } 279 logger.info("exit char root: T0 = " + T0 + ", T = " + T); 280 return sfactors; 281 } 282 283 284 /** 285 * GenPolynomial recursive univariate polynomial greatest squarefree 286 * divisor. 287 * @param P recursive univariate GenPolynomial. 288 * @return squarefree(pp(P)). 289 */ 290 @Override 291 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateSquarefreePart( 292 GenPolynomial<GenPolynomial<C>> P) { 293 if (P == null || P.isZERO()) { 294 return P; 295 } 296 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 297 if (pfac.nvar > 1) { 298 throw new IllegalArgumentException( 299 this.getClass().getName() + " only for univariate polynomials"); 300 } 301 GenPolynomial<GenPolynomial<C>> s = pfac.getONE(); 302 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> factors = recursiveUnivariateSquarefreeFactors(P); 303 if (logger.isWarnEnabled()) { 304 logger.info("sqfPart, better use sqfFactors, factors = " + factors); 305 } 306 for (GenPolynomial<GenPolynomial<C>> sp : factors.keySet()) { 307 s = s.multiply(sp); 308 } 309 s = PolyUtil.<C> monic(s); 310 return s; 311 } 312 313 314 /** 315 * GenPolynomial recursive univariate polynomial squarefree factorization. 316 * @param P recursive univariate GenPolynomial. 317 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 318 * p_i^{e_i} and p_i squarefree. 319 */ 320 @Override 321 public SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveUnivariateSquarefreeFactors( 322 GenPolynomial<GenPolynomial<C>> P) { 323 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> sfactors = new TreeMap<GenPolynomial<GenPolynomial<C>>, Long>(); 324 if (P == null || P.isZERO()) { 325 return sfactors; 326 } 327 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 328 if (pfac.nvar > 1) { 329 // recursiveContent not possible by return type 330 throw new IllegalArgumentException( 331 this.getClass().getName() + " only for univariate polynomials"); 332 } 333 // if base coefficient ring is a field, make monic 334 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac; 335 C ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); 336 if (!ldbcf.isONE()) { 337 GenPolynomial<C> lc = cfac.getONE().multiply(ldbcf); 338 GenPolynomial<GenPolynomial<C>> pl = pfac.getONE().multiply(lc); 339 sfactors.put(pl, 1L); 340 C li = ldbcf.inverse(); 341 //System.out.println("li = " + li); 342 P = P.multiply(cfac.getONE().multiply(li)); 343 //System.out.println("P,monic = " + P); 344 ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); 345 if (debug) { 346 logger.debug("new ldbcf: " + ldbcf); 347 } 348 } 349 // factors of content 350 GenPolynomial<C> Pc = engine.recursiveContent(P); 351 if (logger.isInfoEnabled()) { 352 logger.info("Pc = " + Pc); 353 } 354 Pc = Pc.monic(); 355 if (!Pc.isONE()) { 356 P = PolyUtil.<C> coefficientPseudoDivide(P, Pc); 357 } 358 SortedMap<GenPolynomial<C>, Long> rsf = squarefreeFactors(Pc); 359 if (logger.isInfoEnabled()) { 360 logger.info("rsf = " + rsf); 361 } 362 // add factors of content 363 for (Map.Entry<GenPolynomial<C>, Long> me : rsf.entrySet()) { 364 GenPolynomial<C> c = me.getKey(); 365 if (!c.isONE()) { 366 GenPolynomial<GenPolynomial<C>> cr = pfac.getONE().multiply(c); 367 Long rk = me.getValue(); //rsf.get(c); 368 sfactors.put(cr, rk); 369 } 370 } 371 // divide by trailing term 372 ExpVector et = P.trailingExpVector(); 373 if (!et.isZERO()) { 374 GenPolynomial<GenPolynomial<C>> tr = pfac.valueOf(et); 375 if (logger.isInfoEnabled()) { 376 logger.info("trailing term = " + tr); 377 } 378 P = PolyUtil.<C> recursivePseudoDivide(P, tr); 379 long ep = et.getVal(0); // univariate 380 et = et.subst(0, 1); 381 tr = pfac.valueOf(et); 382 sfactors.put(tr, ep); 383 } 384 385 // factors of recursive polynomial 386 GenPolynomial<GenPolynomial<C>> T0 = P; 387 long e = 1L; 388 GenPolynomial<GenPolynomial<C>> Tp; 389 GenPolynomial<GenPolynomial<C>> T = null; 390 GenPolynomial<GenPolynomial<C>> V = null; 391 long k = 0L; 392 long mp = 0L; 393 boolean init = true; 394 while (true) { 395 if (init) { 396 if (T0.isConstant() || T0.isZERO()) { 397 break; 398 } 399 Tp = PolyUtil.<C> recursiveDeriviative(T0); 400 //System.out.println("iT0 = " + T0); 401 //System.out.println("iTp = " + Tp); 402 T = engine.recursiveUnivariateGcd(T0, Tp); 403 T = PolyUtil.<C> monic(T); 404 V = PolyUtil.<C> recursivePseudoDivide(T0, T); 405 //System.out.println("iT = " + T); 406 //System.out.println("iV = " + V); 407 k = 0L; 408 mp = 0L; 409 init = false; 410 } 411 if (V.isConstant()) { 412 mp = pfac.characteristic().longValue(); // assert != 0 413 //T0 = PolyUtil.<C> recursiveModRoot(T,mp); 414 T0 = recursiveUnivariateRootCharacteristic(T); 415 logger.info("char root: T0r = " + T0 + ", Tr = " + T); 416 if (T0 == null) { 417 //break; 418 T0 = pfac.getZERO(); 419 } 420 e = e * mp; 421 init = true; 422 //continue; 423 } 424 k++; 425 if (mp != 0L && k % mp == 0L) { 426 T = PolyUtil.<C> recursivePseudoDivide(T, V); 427 System.out.println("k = " + k); 428 //System.out.println("T = " + T); 429 k++; 430 } 431 GenPolynomial<GenPolynomial<C>> W = engine.recursiveUnivariateGcd(T, V); 432 W = PolyUtil.<C> monic(W); 433 GenPolynomial<GenPolynomial<C>> z = PolyUtil.<C> recursivePseudoDivide(V, W); 434 //System.out.println("W = " + W); 435 //System.out.println("z = " + z); 436 V = W; 437 T = PolyUtil.<C> recursivePseudoDivide(T, V); 438 //System.out.println("V = " + V); 439 //System.out.println("T = " + T); 440 //was: if ( z.degree(0) > 0 ) { 441 if (!z.isONE() && !z.isZERO()) { 442 z = PolyUtil.<C> monic(z); 443 logger.info("z,put = " + z); 444 sfactors.put(z, (e * k)); 445 } 446 } 447 logger.info("exit char root: T0 = " + T0 + ", T = " + T); 448 if (sfactors.size() == 0) { 449 sfactors.put(pfac.getONE(), 1L); 450 } 451 return sfactors; 452 } 453 454 455 /** 456 * GenPolynomial greatest squarefree divisor. 457 * @param P GenPolynomial. 458 * @return squarefree(pp(P)). 459 */ 460 @Override 461 public GenPolynomial<C> squarefreePart(GenPolynomial<C> P) { 462 if (P == null) { 463 throw new IllegalArgumentException(this.getClass().getName() + " P != null"); 464 } 465 if (P.isZERO()) { 466 return P; 467 } 468 GenPolynomialRing<C> pfac = P.ring; 469 if (pfac.nvar <= 1) { 470 return baseSquarefreePart(P); 471 } 472 GenPolynomial<C> s = pfac.getONE(); 473 SortedMap<GenPolynomial<C>, Long> factors = squarefreeFactors(P); 474 if (logger.isWarnEnabled()) { 475 logger.info("sqfPart, better use sqfFactors, factors = " + factors); 476 } 477 for (GenPolynomial<C> sp : factors.keySet()) { 478 if (sp.isConstant()) { 479 continue; 480 } 481 s = s.multiply(sp); 482 } 483 return s.monic(); 484 } 485 486 487 /** 488 * GenPolynomial squarefree factorization. 489 * @param P GenPolynomial. 490 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 491 * p_i^{e_i} and p_i squarefree. 492 */ 493 @Override 494 public SortedMap<GenPolynomial<C>, Long> squarefreeFactors(GenPolynomial<C> P) { 495 if (P == null) { 496 throw new IllegalArgumentException(this.getClass().getName() + " P != null"); 497 } 498 GenPolynomialRing<C> pfac = P.ring; 499 if (pfac.nvar <= 1) { 500 return baseSquarefreeFactors(P); 501 } 502 SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); 503 if (P.isZERO()) { 504 return sfactors; 505 } 506 if (P.isONE()) { 507 sfactors.put(P, 1L); 508 return sfactors; 509 } 510 GenPolynomialRing<GenPolynomial<C>> rfac = pfac.recursive(1); 511 GenPolynomial<GenPolynomial<C>> Pr = PolyUtil.<C> recursive(rfac, P); 512 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> PP = recursiveUnivariateSquarefreeFactors(Pr); 513 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> m : PP.entrySet()) { 514 Long i = m.getValue(); 515 GenPolynomial<GenPolynomial<C>> Dr = m.getKey(); 516 GenPolynomial<C> D = PolyUtil.<C> distribute(pfac, Dr); 517 sfactors.put(D, i); 518 } 519 return sfactors; 520 } 521 522 523 /** 524 * Coefficient squarefree factorization. 525 * @param coeff coefficient. 526 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 527 * p_i^{e_i} and p_i squarefree. 528 */ 529 @SuppressWarnings("unchecked") 530 @Override 531 public SortedMap<C, Long> squarefreeFactors(C coeff) { 532 if (coeff == null) { 533 return null; 534 } 535 SortedMap<C, Long> factors = new TreeMap<C, Long>(); 536 RingFactory<C> cfac = (RingFactory<C>) coeff.factory(); 537 if (aCoFac != null) { 538 AlgebraicNumber<C> an = (AlgebraicNumber<C>) (Object) coeff; 539 if (cfac.isFinite()) { 540 SquarefreeFiniteFieldCharP<C> reng = (SquarefreeFiniteFieldCharP) SquarefreeFactory 541 .getImplementation(cfac); 542 SortedMap<C, Long> rfactors = reng.rootCharacteristic(coeff); // ?? 543 logger.info("rfactors,finite = " + rfactors); 544 factors.putAll(rfactors); 545 //return factors; 546 } else { 547 SquarefreeInfiniteAlgebraicFieldCharP<C> reng = (SquarefreeInfiniteAlgebraicFieldCharP) SquarefreeFactory 548 .getImplementation(cfac); 549 SortedMap<AlgebraicNumber<C>, Long> rfactors = reng.squarefreeFactors(an); 550 logger.info("rfactors,infinite,algeb = " + rfactors); 551 for (Map.Entry<AlgebraicNumber<C>, Long> me : rfactors.entrySet()) { 552 AlgebraicNumber<C> c = me.getKey(); 553 if (!c.isONE()) { 554 C cr = (C) (Object) c; 555 Long rk = me.getValue(); 556 factors.put(cr, rk); 557 } 558 } 559 } 560 } else if (qCoFac != null) { 561 Quotient<C> q = (Quotient<C>) (Object) coeff; 562 SquarefreeInfiniteFieldCharP<C> reng = (SquarefreeInfiniteFieldCharP) SquarefreeFactory 563 .getImplementation(cfac); 564 SortedMap<Quotient<C>, Long> rfactors = reng.squarefreeFactors(q); 565 logger.info("rfactors,infinite = " + rfactors); 566 for (Map.Entry<Quotient<C>, Long> me : rfactors.entrySet()) { 567 Quotient<C> c = me.getKey(); 568 if (!c.isONE()) { 569 C cr = (C) (Object) c; 570 Long rk = me.getValue(); 571 factors.put(cr, rk); 572 } 573 } 574 } else if (cfac.isFinite()) { 575 SquarefreeFiniteFieldCharP<C> reng = (SquarefreeFiniteFieldCharP) SquarefreeFactory 576 .getImplementation(cfac); 577 SortedMap<C, Long> rfactors = reng.rootCharacteristic(coeff); // ?? 578 logger.info("rfactors,finite = " + rfactors); 579 factors.putAll(rfactors); 580 //return factors; 581 } else { 582 logger.warn("case " + cfac + " not implemented"); 583 } 584 return factors; 585 } 586 587 588 /* --------- char-th roots --------------------- */ 589 590 591 /** 592 * GenPolynomial char-th root univariate polynomial. 593 * @param P GenPolynomial. 594 * @return char-th_rootOf(P), or null if no char-th root. 595 */ 596 public abstract GenPolynomial<C> baseRootCharacteristic(GenPolynomial<C> P); 597 598 599 /** 600 * GenPolynomial char-th root univariate polynomial with polynomial 601 * coefficients. 602 * @param P recursive univariate GenPolynomial. 603 * @return char-th_rootOf(P), or null if P is no char-th root. 604 */ 605 public abstract GenPolynomial<GenPolynomial<C>> recursiveUnivariateRootCharacteristic( 606 GenPolynomial<GenPolynomial<C>> P); 607 608 609 /** 610 * Polynomial is char-th root. 611 * @param P polynomial. 612 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 613 * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false. 614 */ 615 public boolean isCharRoot(GenPolynomial<C> P, SortedMap<GenPolynomial<C>, Long> F) { 616 if (P == null || F == null) { 617 throw new IllegalArgumentException("P and F may not be null"); 618 } 619 if (P.isZERO() && F.size() == 0) { 620 return true; 621 } 622 GenPolynomial<C> t = P.ring.getONE(); 623 long p = P.ring.characteristic().longValue(); 624 for (Map.Entry<GenPolynomial<C>, Long> me : F.entrySet()) { 625 GenPolynomial<C> f = me.getKey(); 626 Long E = me.getValue(); 627 long e = E.longValue(); 628 GenPolynomial<C> g = f.power(e); 629 if (!f.isConstant()) { 630 g = g.power(p); 631 } 632 t = t.multiply(g); 633 } 634 boolean f = P.equals(t) || P.equals(t.negate()); 635 if (!f) { 636 System.out.println("\nfactorization(map): " + f); 637 System.out.println("P = " + P); 638 System.out.println("t = " + t); 639 P = P.monic(); 640 t = t.monic(); 641 f = P.equals(t) || P.equals(t.negate()); 642 if (f) { 643 return f; 644 } 645 System.out.println("\nfactorization(map): " + f); 646 System.out.println("P = " + P); 647 System.out.println("t = " + t); 648 } 649 return f; 650 } 651 652 653 /** 654 * Recursive polynomial is char-th root. 655 * @param P recursive polynomial. 656 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 657 * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false. 658 */ 659 public boolean isRecursiveCharRoot(GenPolynomial<GenPolynomial<C>> P, 660 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> F) { 661 if (P == null || F == null) { 662 throw new IllegalArgumentException("P and F may not be null"); 663 } 664 if (P.isZERO() && F.size() == 0) { 665 return true; 666 } 667 GenPolynomial<GenPolynomial<C>> t = P.ring.getONE(); 668 long p = P.ring.characteristic().longValue(); 669 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> me : F.entrySet()) { 670 GenPolynomial<GenPolynomial<C>> f = me.getKey(); 671 Long E = me.getValue(); 672 long e = E.longValue(); 673 GenPolynomial<GenPolynomial<C>> g = f.power(e); 674 if (!f.isConstant()) { 675 g = g.power(p); 676 } 677 t = t.multiply(g); 678 } 679 boolean f = P.equals(t) || P.equals(t.negate()); 680 if (!f) { 681 System.out.println("\nfactorization(map): " + f); 682 System.out.println("P = " + P); 683 System.out.println("t = " + t); 684 P = P.monic(); 685 t = t.monic(); 686 f = P.equals(t) || P.equals(t.negate()); 687 if (f) { 688 return f; 689 } 690 System.out.println("\nfactorization(map): " + f); 691 System.out.println("P = " + P); 692 System.out.println("t = " + t); 693 } 694 return f; 695 } 696 697 698 /** 699 * Recursive polynomial is char-th root. 700 * @param P recursive polynomial. 701 * @param r = recursive polynomial. 702 * @return true if P = r**p, else false. 703 */ 704 public boolean isRecursiveCharRoot(GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> r) { 705 if (P == null || r == null) { 706 throw new IllegalArgumentException("P and r may not be null"); 707 } 708 if (P.isZERO() && r.isZERO()) { 709 return true; 710 } 711 long p = P.ring.characteristic().longValue(); 712 GenPolynomial<GenPolynomial<C>> t = r.power(p); 713 714 boolean f = P.equals(t) || P.equals(t.negate()); 715 if (!f) { 716 System.out.println("\nisCharRoot: " + f); 717 System.out.println("P = " + P); 718 System.out.println("t = " + t); 719 P = P.monic(); 720 t = t.monic(); 721 f = P.equals(t) || P.equals(t.negate()); 722 if (f) { 723 return f; 724 } 725 System.out.println("\nisCharRoot: " + f); 726 System.out.println("P = " + P); 727 System.out.println("t = " + t); 728 } 729 return f; 730 } 731 732}