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