001/* 002 * $Id: SquarefreeFieldCharP.java 4965 2014-10-17 20:07:51Z 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 if (P.isONE()) { 479 sfactors.put(P, 1L); 480 return sfactors; 481 } 482 GenPolynomialRing<C> cfac = pfac.contract(1); 483 GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(cfac, 1); 484 485 GenPolynomial<GenPolynomial<C>> Pr = PolyUtil.<C> recursive(rfac, P); 486 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> PP = recursiveUnivariateSquarefreeFactors(Pr); 487 488 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> m : PP.entrySet()) { 489 Long i = m.getValue(); 490 GenPolynomial<GenPolynomial<C>> Dr = m.getKey(); 491 GenPolynomial<C> D = PolyUtil.<C> distribute(pfac, Dr); 492 sfactors.put(D, i); 493 } 494 return sfactors; 495 } 496 497 498 /** 499 * Coefficient squarefree factorization. 500 * @param coeff coefficient. 501 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 502 * p_i^{e_i} and p_i squarefree. 503 */ 504 @SuppressWarnings("cast") 505 @Override 506 public SortedMap<C, Long> squarefreeFactors(C coeff) { 507 if (coeff == null) { 508 return null; 509 } 510 SortedMap<C, Long> factors = new TreeMap<C, Long>(); 511 RingFactory<C> cfac = (RingFactory<C>) coeff.factory(); 512 if (aCoFac != null) { 513 AlgebraicNumber<C> an = (AlgebraicNumber<C>) (Object) coeff; 514 if (cfac.isFinite()) { 515 SquarefreeFiniteFieldCharP<C> reng = (SquarefreeFiniteFieldCharP) SquarefreeFactory 516 .getImplementation(cfac); 517 SortedMap<C, Long> rfactors = reng.rootCharacteristic(coeff); // ?? 518 logger.info("rfactors,finite = " + rfactors); 519 factors.putAll(rfactors); 520 //return factors; 521 } else { 522 SquarefreeInfiniteAlgebraicFieldCharP<C> reng = (SquarefreeInfiniteAlgebraicFieldCharP) SquarefreeFactory 523 .getImplementation(cfac); 524 SortedMap<AlgebraicNumber<C>, Long> rfactors = reng.squarefreeFactors(an); 525 logger.info("rfactors,infinite,algeb = " + rfactors); 526 for (Map.Entry<AlgebraicNumber<C>, Long> me : rfactors.entrySet()) { 527 AlgebraicNumber<C> c = me.getKey(); 528 if (!c.isONE()) { 529 C cr = (C) (Object) c; 530 Long rk = me.getValue(); // rfactors.get(c); 531 factors.put(cr, rk); 532 } 533 } 534 } 535 } else if (qCoFac != null) { 536 Quotient<C> q = (Quotient<C>) (Object) coeff; 537 SquarefreeInfiniteFieldCharP<C> reng = (SquarefreeInfiniteFieldCharP) SquarefreeFactory 538 .getImplementation(cfac); 539 SortedMap<Quotient<C>, Long> rfactors = reng.squarefreeFactors(q); 540 logger.info("rfactors,infinite = " + rfactors); 541 for (Map.Entry<Quotient<C>, Long> me : rfactors.entrySet()) { 542 Quotient<C> c = me.getKey(); 543 if (!c.isONE()) { 544 C cr = (C) (Object) c; 545 Long rk = me.getValue(); //rfactors.get(c); 546 factors.put(cr, rk); 547 } 548 } 549 } else if (cfac.isFinite()) { 550 SquarefreeFiniteFieldCharP<C> reng = (SquarefreeFiniteFieldCharP) SquarefreeFactory 551 .getImplementation(cfac); 552 SortedMap<C, Long> rfactors = reng.rootCharacteristic(coeff); // ?? 553 logger.info("rfactors,finite = " + rfactors); 554 factors.putAll(rfactors); 555 //return factors; 556 } else { 557 logger.warn("case " + cfac + " not implemented"); 558 } 559 return factors; 560 } 561 562 563 /* --------- char-th roots --------------------- */ 564 565 566 /** 567 * GenPolynomial char-th root univariate polynomial. 568 * @param P GenPolynomial. 569 * @return char-th_rootOf(P), or null if no char-th root. 570 */ 571 public abstract GenPolynomial<C> baseRootCharacteristic(GenPolynomial<C> P); 572 573 574 /** 575 * GenPolynomial char-th root univariate polynomial with polynomial 576 * coefficients. 577 * @param P recursive univariate GenPolynomial. 578 * @return char-th_rootOf(P), or null if P is no char-th root. 579 */ 580 public abstract GenPolynomial<GenPolynomial<C>> recursiveUnivariateRootCharacteristic( 581 GenPolynomial<GenPolynomial<C>> P); 582 583 584 /** 585 * Polynomial is char-th root. 586 * @param P polynomial. 587 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 588 * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false. 589 */ 590 public boolean isCharRoot(GenPolynomial<C> P, SortedMap<GenPolynomial<C>, Long> F) { 591 if (P == null || F == null) { 592 throw new IllegalArgumentException("P and F may not be null"); 593 } 594 if (P.isZERO() && F.size() == 0) { 595 return true; 596 } 597 GenPolynomial<C> t = P.ring.getONE(); 598 long p = P.ring.characteristic().longValue(); 599 for (Map.Entry<GenPolynomial<C>, Long> me : F.entrySet()) { 600 GenPolynomial<C> f = me.getKey(); 601 Long E = me.getValue(); //F.get(f); 602 long e = E.longValue(); 603 GenPolynomial<C> g = Power.<GenPolynomial<C>> positivePower(f, e); 604 if (!f.isConstant()) { 605 g = Power.<GenPolynomial<C>> positivePower(g, p); 606 } 607 t = t.multiply(g); 608 } 609 boolean f = P.equals(t) || P.equals(t.negate()); 610 if (!f) { 611 System.out.println("\nfactorization(map): " + f); 612 System.out.println("P = " + P); 613 System.out.println("t = " + t); 614 P = P.monic(); 615 t = t.monic(); 616 f = P.equals(t) || P.equals(t.negate()); 617 if (f) { 618 return f; 619 } 620 System.out.println("\nfactorization(map): " + f); 621 System.out.println("P = " + P); 622 System.out.println("t = " + t); 623 } 624 return f; 625 } 626 627 628 /** 629 * Recursive polynomial is char-th root. 630 * @param P recursive polynomial. 631 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 632 * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false. 633 */ 634 public boolean isRecursiveCharRoot(GenPolynomial<GenPolynomial<C>> P, 635 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> F) { 636 if (P == null || F == null) { 637 throw new IllegalArgumentException("P and F may not be null"); 638 } 639 if (P.isZERO() && F.size() == 0) { 640 return true; 641 } 642 GenPolynomial<GenPolynomial<C>> t = P.ring.getONE(); 643 long p = P.ring.characteristic().longValue(); 644 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> me : F.entrySet()) { 645 GenPolynomial<GenPolynomial<C>> f = me.getKey(); 646 Long E = me.getValue(); //F.get(f); 647 long e = E.longValue(); 648 GenPolynomial<GenPolynomial<C>> g = Power.<GenPolynomial<GenPolynomial<C>>> positivePower(f, e); 649 if (!f.isConstant()) { 650 g = Power.<GenPolynomial<GenPolynomial<C>>> positivePower(g, p); 651 } 652 t = t.multiply(g); 653 } 654 boolean f = P.equals(t) || P.equals(t.negate()); 655 if (!f) { 656 System.out.println("\nfactorization(map): " + f); 657 System.out.println("P = " + P); 658 System.out.println("t = " + t); 659 P = P.monic(); 660 t = t.monic(); 661 f = P.equals(t) || P.equals(t.negate()); 662 if (f) { 663 return f; 664 } 665 System.out.println("\nfactorization(map): " + f); 666 System.out.println("P = " + P); 667 System.out.println("t = " + t); 668 } 669 return f; 670 } 671 672 673 /** 674 * Recursive polynomial is char-th root. 675 * @param P recursive polynomial. 676 * @param r = recursive polynomial. 677 * @return true if P = r**p, else false. 678 */ 679 public boolean isRecursiveCharRoot(GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> r) { 680 if (P == null || r == null) { 681 throw new IllegalArgumentException("P and r may not be null"); 682 } 683 if (P.isZERO() && r.isZERO()) { 684 return true; 685 } 686 long p = P.ring.characteristic().longValue(); 687 GenPolynomial<GenPolynomial<C>> t = Power.<GenPolynomial<GenPolynomial<C>>> positivePower(r, p); 688 689 boolean f = P.equals(t) || P.equals(t.negate()); 690 if (!f) { 691 System.out.println("\nisCharRoot: " + f); 692 System.out.println("P = " + P); 693 System.out.println("t = " + t); 694 P = P.monic(); 695 t = t.monic(); 696 f = P.equals(t) || P.equals(t.negate()); 697 if (f) { 698 return f; 699 } 700 System.out.println("\nisCharRoot: " + f); 701 System.out.println("P = " + P); 702 System.out.println("t = " + t); 703 } 704 return f; 705 } 706 707}