001/* 002 * $Id: SquarefreeFieldCharP.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.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 GenPolynomial<C> T0 = A; 196 long e = 1L; 197 GenPolynomial<C> Tp; 198 GenPolynomial<C> T = null; 199 GenPolynomial<C> V = null; 200 long k = 0L; 201 long mp = 0L; 202 boolean init = true; 203 while (true) { 204 //System.out.println("T0 = " + T0); 205 if (init) { 206 if (T0.isConstant() || T0.isZERO()) { 207 break; 208 } 209 Tp = PolyUtil.<C> baseDeriviative(T0); 210 T = engine.baseGcd(T0, Tp); 211 T = T.monic(); 212 V = PolyUtil.<C> basePseudoDivide(T0, T); 213 //System.out.println("iT0 = " + T0); 214 //System.out.println("iTp = " + Tp); 215 //System.out.println("iT = " + T); 216 //System.out.println("iV = " + V); 217 //System.out.println("const(iV) = " + V.isConstant()); 218 k = 0L; 219 mp = 0L; 220 init = false; 221 } 222 if (V.isConstant()) { 223 mp = pfac.characteristic().longValue(); // assert != 0 224 //T0 = PolyUtil.<C> baseModRoot(T,mp); 225 T0 = baseRootCharacteristic(T); 226 logger.info("char root: T0 = " + T0 + ", T = " + T); 227 if (T0 == null) { 228 //break; 229 T0 = pfac.getZERO(); 230 } 231 e = e * mp; 232 init = true; 233 continue; 234 } 235 k++; 236 if (mp != 0L && k % mp == 0L) { 237 T = PolyUtil.<C> basePseudoDivide(T, V); 238 System.out.println("k = " + k); 239 //System.out.println("T = " + T); 240 k++; 241 } 242 GenPolynomial<C> W = engine.baseGcd(T, V); 243 W = W.monic(); 244 GenPolynomial<C> z = PolyUtil.<C> basePseudoDivide(V, W); 245 //System.out.println("W = " + W); 246 //System.out.println("z = " + z); 247 V = W; 248 T = PolyUtil.<C> basePseudoDivide(T, V); 249 //System.out.println("V = " + V); 250 //System.out.println("T = " + T); 251 if (z.degree(0) > 0) { 252 if (ldbcf.isONE() && !z.leadingBaseCoefficient().isONE()) { 253 z = z.monic(); 254 logger.info("z,monic = " + z); 255 } 256 sfactors.put(z, (e * k)); 257 } 258 } 259 logger.info("exit char root: T0 = " + T0 + ", T = " + T); 260 return sfactors; 261 } 262 263 264 /** 265 * GenPolynomial recursive univariate polynomial greatest squarefree 266 * divisor. 267 * @param P recursive univariate GenPolynomial. 268 * @return squarefree(pp(P)). 269 */ 270 @Override 271 public GenPolynomial<GenPolynomial<C>> recursiveUnivariateSquarefreePart( 272 GenPolynomial<GenPolynomial<C>> P) { 273 if (P == null || P.isZERO()) { 274 return P; 275 } 276 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 277 if (pfac.nvar > 1) { 278 throw new IllegalArgumentException( 279 this.getClass().getName() + " only for univariate polynomials"); 280 } 281 GenPolynomial<GenPolynomial<C>> s = pfac.getONE(); 282 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> factors = recursiveUnivariateSquarefreeFactors(P); 283 if (logger.isWarnEnabled()) { 284 logger.warn("sqfPart, better use sqfFactors, factors = " + factors); 285 } 286 for (GenPolynomial<GenPolynomial<C>> sp : factors.keySet()) { 287 s = s.multiply(sp); 288 } 289 return PolyUtil.<C> monic(s); 290 } 291 292 293 /** 294 * GenPolynomial recursive univariate polynomial squarefree factorization. 295 * @param P recursive univariate GenPolynomial. 296 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 297 * p_i^{e_i} and p_i squarefree. 298 */ 299 @Override 300 public SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveUnivariateSquarefreeFactors( 301 GenPolynomial<GenPolynomial<C>> P) { 302 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> sfactors = new TreeMap<GenPolynomial<GenPolynomial<C>>, Long>(); 303 if (P == null || P.isZERO()) { 304 return sfactors; 305 } 306 GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; 307 if (pfac.nvar > 1) { 308 // recursiveContent not possible by return type 309 throw new IllegalArgumentException( 310 this.getClass().getName() + " only for univariate polynomials"); 311 } 312 // if base coefficient ring is a field, make monic 313 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac; 314 C ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); 315 if (!ldbcf.isONE()) { 316 GenPolynomial<C> lc = cfac.getONE().multiply(ldbcf); 317 GenPolynomial<GenPolynomial<C>> pl = pfac.getONE().multiply(lc); 318 sfactors.put(pl, 1L); 319 C li = ldbcf.inverse(); 320 //System.out.println("li = " + li); 321 P = P.multiply(cfac.getONE().multiply(li)); 322 //System.out.println("P,monic = " + P); 323 ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); 324 if (debug) { 325 logger.debug("new ldbcf: " + ldbcf); 326 } 327 } 328 // factors of content 329 GenPolynomial<C> Pc = engine.recursiveContent(P); 330 if (logger.isInfoEnabled()) { 331 logger.info("Pc = " + Pc); 332 } 333 Pc = Pc.monic(); 334 if (!Pc.isONE()) { 335 P = PolyUtil.<C> coefficientPseudoDivide(P, Pc); 336 } 337 SortedMap<GenPolynomial<C>, Long> rsf = squarefreeFactors(Pc); 338 if (logger.isInfoEnabled()) { 339 logger.info("rsf = " + rsf); 340 } 341 // add factors of content 342 for (Map.Entry<GenPolynomial<C>, Long> me : rsf.entrySet()) { 343 GenPolynomial<C> c = me.getKey(); 344 if (!c.isONE()) { 345 GenPolynomial<GenPolynomial<C>> cr = pfac.getONE().multiply(c); 346 Long rk = me.getValue(); //rsf.get(c); 347 sfactors.put(cr, rk); 348 } 349 } 350 // divide by trailing term 351 ExpVector et = P.trailingExpVector(); 352 if (!et.isZERO()) { 353 GenPolynomial<GenPolynomial<C>> tr = pfac.valueOf(et); 354 if (logger.isInfoEnabled()) { 355 logger.info("trailing term = " + tr); 356 } 357 P = PolyUtil.<C> recursivePseudoDivide(P, tr); 358 long ep = et.getVal(0); // univariate 359 et = et.subst(0, 1); 360 tr = pfac.valueOf(et); 361 sfactors.put(tr, ep); 362 } 363 364 // factors of recursive polynomial 365 GenPolynomial<GenPolynomial<C>> T0 = P; 366 long e = 1L; 367 GenPolynomial<GenPolynomial<C>> Tp; 368 GenPolynomial<GenPolynomial<C>> T = null; 369 GenPolynomial<GenPolynomial<C>> V = null; 370 long k = 0L; 371 long mp = 0L; 372 boolean init = true; 373 while (true) { 374 if (init) { 375 if (T0.isConstant() || T0.isZERO()) { 376 break; 377 } 378 Tp = PolyUtil.<C> recursiveDeriviative(T0); 379 T = engine.recursiveUnivariateGcd(T0, Tp); 380 T = PolyUtil.<C> monic(T); 381 V = PolyUtil.<C> recursivePseudoDivide(T0, T); 382 //System.out.println("iT0 = " + T0); 383 //System.out.println("iTp = " + Tp); 384 //System.out.println("iT = " + T); 385 //System.out.println("iV = " + V); 386 k = 0L; 387 mp = 0L; 388 init = false; 389 } 390 if (V.isConstant()) { 391 mp = pfac.characteristic().longValue(); // assert != 0 392 //T0 = PolyUtil.<C> recursiveModRoot(T,mp); 393 T0 = recursiveUnivariateRootCharacteristic(T); 394 logger.info("char root: T0r = " + T0 + ", Tr = " + T); 395 if (T0 == null) { 396 //break; 397 T0 = pfac.getZERO(); 398 } 399 e = e * mp; 400 init = true; 401 //continue; 402 } 403 k++; 404 if (mp != 0L && k % mp == 0L) { 405 T = PolyUtil.<C> recursivePseudoDivide(T, V); 406 System.out.println("k = " + k); 407 //System.out.println("T = " + T); 408 k++; 409 } 410 GenPolynomial<GenPolynomial<C>> W = engine.recursiveUnivariateGcd(T, V); 411 W = PolyUtil.<C> monic(W); 412 GenPolynomial<GenPolynomial<C>> z = PolyUtil.<C> recursivePseudoDivide(V, W); 413 //System.out.println("W = " + W); 414 //System.out.println("z = " + z); 415 V = W; 416 T = PolyUtil.<C> recursivePseudoDivide(T, V); 417 //System.out.println("V = " + V); 418 //System.out.println("T = " + T); 419 //was: if ( z.degree(0) > 0 ) { 420 if (!z.isONE() && !z.isZERO()) { 421 z = PolyUtil.<C> monic(z); 422 logger.info("z,put = " + z); 423 sfactors.put(z, (e * k)); 424 } 425 } 426 logger.info("exit char root: T0 = " + T0 + ", T = " + T); 427 if (sfactors.size() == 0) { 428 sfactors.put(pfac.getONE(), 1L); 429 } 430 return sfactors; 431 } 432 433 434 /** 435 * GenPolynomial greatest squarefree divisor. 436 * @param P GenPolynomial. 437 * @return squarefree(pp(P)). 438 */ 439 @Override 440 public GenPolynomial<C> squarefreePart(GenPolynomial<C> P) { 441 if (P == null) { 442 throw new IllegalArgumentException(this.getClass().getName() + " P != null"); 443 } 444 if (P.isZERO()) { 445 return P; 446 } 447 GenPolynomialRing<C> pfac = P.ring; 448 if (pfac.nvar <= 1) { 449 return baseSquarefreePart(P); 450 } 451 GenPolynomial<C> s = pfac.getONE(); 452 SortedMap<GenPolynomial<C>, Long> factors = squarefreeFactors(P); 453 if (logger.isWarnEnabled()) { 454 logger.warn("sqfPart, better use sqfFactors, factors = " + factors); 455 } 456 for (GenPolynomial<C> sp : factors.keySet()) { 457 if (sp.isConstant()) { 458 continue; 459 } 460 s = s.multiply(sp); 461 } 462 return s.monic(); 463 } 464 465 466 /** 467 * GenPolynomial squarefree factorization. 468 * @param P GenPolynomial. 469 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 470 * p_i^{e_i} and p_i squarefree. 471 */ 472 @Override 473 public SortedMap<GenPolynomial<C>, Long> squarefreeFactors(GenPolynomial<C> P) { 474 if (P == null) { 475 throw new IllegalArgumentException(this.getClass().getName() + " P != null"); 476 } 477 GenPolynomialRing<C> pfac = P.ring; 478 if (pfac.nvar <= 1) { 479 return baseSquarefreeFactors(P); 480 } 481 SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); 482 if (P.isZERO()) { 483 return sfactors; 484 } 485 if (P.isONE()) { 486 sfactors.put(P, 1L); 487 return sfactors; 488 } 489 GenPolynomialRing<GenPolynomial<C>> rfac = pfac.recursive(1); 490 GenPolynomial<GenPolynomial<C>> Pr = PolyUtil.<C> recursive(rfac, P); 491 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> PP = recursiveUnivariateSquarefreeFactors(Pr); 492 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> m : PP.entrySet()) { 493 Long i = m.getValue(); 494 GenPolynomial<GenPolynomial<C>> Dr = m.getKey(); 495 GenPolynomial<C> D = PolyUtil.<C> distribute(pfac, Dr); 496 sfactors.put(D, i); 497 } 498 return sfactors; 499 } 500 501 502 /** 503 * Coefficient squarefree factorization. 504 * @param coeff coefficient. 505 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 506 * p_i^{e_i} and p_i squarefree. 507 */ 508 @SuppressWarnings("unchecked") 509 @Override 510 public SortedMap<C, Long> squarefreeFactors(C coeff) { 511 if (coeff == null) { 512 return null; 513 } 514 SortedMap<C, Long> factors = new TreeMap<C, Long>(); 515 RingFactory<C> cfac = (RingFactory<C>) coeff.factory(); 516 if (aCoFac != null) { 517 AlgebraicNumber<C> an = (AlgebraicNumber<C>) (Object) coeff; 518 if (cfac.isFinite()) { 519 SquarefreeFiniteFieldCharP<C> reng = (SquarefreeFiniteFieldCharP) SquarefreeFactory 520 .getImplementation(cfac); 521 SortedMap<C, Long> rfactors = reng.rootCharacteristic(coeff); // ?? 522 logger.info("rfactors,finite = " + rfactors); 523 factors.putAll(rfactors); 524 //return factors; 525 } else { 526 SquarefreeInfiniteAlgebraicFieldCharP<C> reng = (SquarefreeInfiniteAlgebraicFieldCharP) SquarefreeFactory 527 .getImplementation(cfac); 528 SortedMap<AlgebraicNumber<C>, Long> rfactors = reng.squarefreeFactors(an); 529 logger.info("rfactors,infinite,algeb = " + rfactors); 530 for (Map.Entry<AlgebraicNumber<C>, Long> me : rfactors.entrySet()) { 531 AlgebraicNumber<C> c = me.getKey(); 532 if (!c.isONE()) { 533 C cr = (C) (Object) c; 534 Long rk = me.getValue(); 535 factors.put(cr, rk); 536 } 537 } 538 } 539 } else if (qCoFac != null) { 540 Quotient<C> q = (Quotient<C>) (Object) coeff; 541 SquarefreeInfiniteFieldCharP<C> reng = (SquarefreeInfiniteFieldCharP) SquarefreeFactory 542 .getImplementation(cfac); 543 SortedMap<Quotient<C>, Long> rfactors = reng.squarefreeFactors(q); 544 logger.info("rfactors,infinite = " + rfactors); 545 for (Map.Entry<Quotient<C>, Long> me : rfactors.entrySet()) { 546 Quotient<C> c = me.getKey(); 547 if (!c.isONE()) { 548 C cr = (C) (Object) c; 549 Long rk = me.getValue(); 550 factors.put(cr, rk); 551 } 552 } 553 } else if (cfac.isFinite()) { 554 SquarefreeFiniteFieldCharP<C> reng = (SquarefreeFiniteFieldCharP) SquarefreeFactory 555 .getImplementation(cfac); 556 SortedMap<C, Long> rfactors = reng.rootCharacteristic(coeff); // ?? 557 logger.info("rfactors,finite = " + rfactors); 558 factors.putAll(rfactors); 559 //return factors; 560 } else { 561 logger.warn("case " + cfac + " not implemented"); 562 } 563 return factors; 564 } 565 566 567 /* --------- char-th roots --------------------- */ 568 569 570 /** 571 * GenPolynomial char-th root univariate polynomial. 572 * @param P GenPolynomial. 573 * @return char-th_rootOf(P), or null if no char-th root. 574 */ 575 public abstract GenPolynomial<C> baseRootCharacteristic(GenPolynomial<C> P); 576 577 578 /** 579 * GenPolynomial char-th root univariate polynomial with polynomial 580 * coefficients. 581 * @param P recursive univariate GenPolynomial. 582 * @return char-th_rootOf(P), or null if P is no char-th root. 583 */ 584 public abstract GenPolynomial<GenPolynomial<C>> recursiveUnivariateRootCharacteristic( 585 GenPolynomial<GenPolynomial<C>> P); 586 587 588 /** 589 * Polynomial is char-th root. 590 * @param P polynomial. 591 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 592 * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false. 593 */ 594 public boolean isCharRoot(GenPolynomial<C> P, SortedMap<GenPolynomial<C>, Long> F) { 595 if (P == null || F == null) { 596 throw new IllegalArgumentException("P and F may not be null"); 597 } 598 if (P.isZERO() && F.size() == 0) { 599 return true; 600 } 601 GenPolynomial<C> t = P.ring.getONE(); 602 long p = P.ring.characteristic().longValue(); 603 for (Map.Entry<GenPolynomial<C>, Long> me : F.entrySet()) { 604 GenPolynomial<C> f = me.getKey(); 605 Long E = me.getValue(); 606 long e = E.longValue(); 607 GenPolynomial<C> g = f.power(e); 608 if (!f.isConstant()) { 609 g = g.power(p); 610 } 611 t = t.multiply(g); 612 } 613 boolean f = P.equals(t) || P.equals(t.negate()); 614 if (!f) { 615 System.out.println("\nfactorization(map): " + f); 616 System.out.println("P = " + P); 617 System.out.println("t = " + t); 618 P = P.monic(); 619 t = t.monic(); 620 f = P.equals(t) || P.equals(t.negate()); 621 if (f) { 622 return f; 623 } 624 System.out.println("\nfactorization(map): " + f); 625 System.out.println("P = " + P); 626 System.out.println("t = " + t); 627 } 628 return f; 629 } 630 631 632 /** 633 * Recursive polynomial is char-th root. 634 * @param P recursive polynomial. 635 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 636 * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false. 637 */ 638 public boolean isRecursiveCharRoot(GenPolynomial<GenPolynomial<C>> P, 639 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> F) { 640 if (P == null || F == null) { 641 throw new IllegalArgumentException("P and F may not be null"); 642 } 643 if (P.isZERO() && F.size() == 0) { 644 return true; 645 } 646 GenPolynomial<GenPolynomial<C>> t = P.ring.getONE(); 647 long p = P.ring.characteristic().longValue(); 648 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> me : F.entrySet()) { 649 GenPolynomial<GenPolynomial<C>> f = me.getKey(); 650 Long E = me.getValue(); 651 long e = E.longValue(); 652 GenPolynomial<GenPolynomial<C>> g = f.power(e); 653 if (!f.isConstant()) { 654 g = g.power(p); 655 } 656 t = t.multiply(g); 657 } 658 boolean f = P.equals(t) || P.equals(t.negate()); 659 if (!f) { 660 System.out.println("\nfactorization(map): " + f); 661 System.out.println("P = " + P); 662 System.out.println("t = " + t); 663 P = P.monic(); 664 t = t.monic(); 665 f = P.equals(t) || P.equals(t.negate()); 666 if (f) { 667 return f; 668 } 669 System.out.println("\nfactorization(map): " + f); 670 System.out.println("P = " + P); 671 System.out.println("t = " + t); 672 } 673 return f; 674 } 675 676 677 /** 678 * Recursive polynomial is char-th root. 679 * @param P recursive polynomial. 680 * @param r = recursive polynomial. 681 * @return true if P = r**p, else false. 682 */ 683 public boolean isRecursiveCharRoot(GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> r) { 684 if (P == null || r == null) { 685 throw new IllegalArgumentException("P and r may not be null"); 686 } 687 if (P.isZERO() && r.isZERO()) { 688 return true; 689 } 690 long p = P.ring.characteristic().longValue(); 691 GenPolynomial<GenPolynomial<C>> t = r.power(p); 692 693 boolean f = P.equals(t) || P.equals(t.negate()); 694 if (!f) { 695 System.out.println("\nisCharRoot: " + f); 696 System.out.println("P = " + P); 697 System.out.println("t = " + t); 698 P = P.monic(); 699 t = t.monic(); 700 f = P.equals(t) || P.equals(t.negate()); 701 if (f) { 702 return f; 703 } 704 System.out.println("\nisCharRoot: " + f); 705 System.out.println("P = " + P); 706 System.out.println("t = " + t); 707 } 708 return f; 709 } 710 711}