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