001/* 002 * $Id: SquarefreeAbstract.java 4115 2012-08-19 13:18:59Z kredel $ 003 */ 004 005package edu.jas.ufd; 006 007 008import java.util.ArrayList; 009import java.util.List; 010import java.util.Map; 011import java.util.SortedMap; 012import java.util.TreeMap; 013 014import edu.jas.poly.GenPolynomial; 015import edu.jas.poly.GenPolynomialRing; 016import edu.jas.poly.PolyUtil; 017import edu.jas.structure.GcdRingElem; 018import edu.jas.structure.Power; 019import edu.jas.structure.RingFactory; 020 021 022/** 023 * Abstract squarefree decomposition class. 024 * @author Heinz Kredel 025 */ 026 027public abstract class SquarefreeAbstract<C extends GcdRingElem<C>> implements Squarefree<C> { 028 029 030 /** 031 * GCD engine for respective base coefficients. 032 */ 033 protected final GreatestCommonDivisorAbstract<C> engine; 034 035 036 /** 037 * Constructor. 038 */ 039 public SquarefreeAbstract(GreatestCommonDivisorAbstract<C> engine) { 040 this.engine = engine; 041 } 042 043 044 /** 045 * GenPolynomial polynomial greatest squarefree divisor. 046 * @param P GenPolynomial. 047 * @return squarefree(pp(P)). 048 */ 049 public abstract GenPolynomial<C> baseSquarefreePart(GenPolynomial<C> P); 050 051 052 /** 053 * GenPolynomial polynomial squarefree factorization. 054 * @param A GenPolynomial. 055 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 056 * p_i^{e_i} and p_i squarefree. 057 */ 058 public abstract SortedMap<GenPolynomial<C>, Long> baseSquarefreeFactors(GenPolynomial<C> A); 059 060 061 /** 062 * GenPolynomial recursive polynomial greatest squarefree divisor. 063 * @param P recursive univariate GenPolynomial. 064 * @return squarefree(pp(P)). 065 */ 066 public abstract GenPolynomial<GenPolynomial<C>> recursiveUnivariateSquarefreePart( 067 GenPolynomial<GenPolynomial<C>> P); 068 069 070 /** 071 * GenPolynomial recursive univariate polynomial squarefree factorization. 072 * @param P recursive univariate GenPolynomial. 073 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 074 * p_i^{e_i} and p_i squarefree. 075 */ 076 public abstract SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveUnivariateSquarefreeFactors( 077 GenPolynomial<GenPolynomial<C>> P); 078 079 080 /** 081 * GenPolynomial greatest squarefree divisor. 082 * @param P GenPolynomial. 083 * @return squarefree(P) a primitive respectively monic polynomial. 084 */ 085 public abstract GenPolynomial<C> squarefreePart(GenPolynomial<C> P); 086 087 088 /** 089 * GenPolynomial test if is squarefree. 090 * @param P GenPolynomial. 091 * @return true if P is squarefree, else false. 092 */ 093 public boolean isSquarefree(GenPolynomial<C> P) { 094 GenPolynomial<C> S = squarefreePart(P); 095 GenPolynomial<C> Ps = P; 096 if (P.ring.coFac.isField()) { 097 Ps = Ps.monic(); 098 } else { 099 Ps = engine.basePrimitivePart(Ps); 100 } 101 boolean f = Ps.equals(S); 102 //if (!f) { 103 //System.out.println("\nisSquarefree: " + f); 104 //System.out.println("S = " + S); 105 //System.out.println("P = " + P); 106 //} 107 return f; 108 } 109 110 111 /** 112 * GenPolynomial list test if squarefree. 113 * @param L list of GenPolynomial. 114 * @return true if each P in L is squarefree, else false. 115 */ 116 public boolean isSquarefree(List<GenPolynomial<C>> L) { 117 if (L == null || L.isEmpty()) { 118 return true; 119 } 120 for (GenPolynomial<C> P : L) { 121 if (!isSquarefree(P)) { 122 return false; 123 } 124 } 125 return true; 126 } 127 128 129 /** 130 * Recursive GenPolynomial test if is squarefree. 131 * @param P recursive univariate GenPolynomial. 132 * @return true if P is squarefree, else false. 133 */ 134 public boolean isRecursiveSquarefree(GenPolynomial<GenPolynomial<C>> P) { 135 GenPolynomial<GenPolynomial<C>> S = recursiveUnivariateSquarefreePart(P); 136 boolean f = P.equals(S); 137 if (!f) { 138 System.out.println("\nisSquarefree: " + f); 139 System.out.println("S = " + S); 140 System.out.println("P = " + P); 141 } 142 return f; 143 } 144 145 146 /** 147 * GenPolynomial squarefree factorization. 148 * @param P GenPolynomial. 149 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 150 * p_i^{e_i} and p_i squarefree. 151 */ 152 public abstract SortedMap<GenPolynomial<C>, Long> squarefreeFactors(GenPolynomial<C> P); 153 154 155 /** 156 * GenPolynomial squarefree and co-prime list. 157 * @param A list of GenPolynomials. 158 * @return B with gcd(b,c) = 1 for all b != c in B and for all non-constant 159 * a in A there exists b in B with b|a and each b in B is 160 * squarefree. B does not contain zero or constant polynomials. 161 */ 162 public List<GenPolynomial<C>> coPrimeSquarefree(List<GenPolynomial<C>> A) { 163 if (A == null || A.isEmpty()) { 164 return A; 165 } 166 List<GenPolynomial<C>> S = new ArrayList<GenPolynomial<C>>(); 167 for (GenPolynomial<C> g : A) { 168 SortedMap<GenPolynomial<C>, Long> sm = squarefreeFactors(g); 169 S.addAll(sm.keySet()); 170 } 171 List<GenPolynomial<C>> B = engine.coPrime(S); 172 return B; 173 } 174 175 176 /** 177 * GenPolynomial squarefree and co-prime list. 178 * @param a polynomial. 179 * @param P squarefree co-prime list of GenPolynomials. 180 * @return B with gcd(b,c) = 1 for all b != c in B and for non-constant a 181 * there exists b in P with b|a. B does not contain zero or constant 182 * polynomials. 183 */ 184 public List<GenPolynomial<C>> coPrimeSquarefree(GenPolynomial<C> a, List<GenPolynomial<C>> P) { 185 if (a == null || a.isZERO() || a.isConstant()) { 186 return P; 187 } 188 SortedMap<GenPolynomial<C>, Long> sm = squarefreeFactors(a); 189 List<GenPolynomial<C>> B = P; 190 for (GenPolynomial<C> f : sm.keySet()) { 191 B = engine.coPrime(f, B); 192 } 193 return B; 194 } 195 196 197 /** 198 * Test if list of GenPolynomials is squarefree and co-prime. 199 * @param B list of GenPolynomials. 200 * @return true, if for all b != c in B gcd(b,c) = 1 and each b in B is 201 * squarefree, else false. 202 */ 203 public boolean isCoPrimeSquarefree(List<GenPolynomial<C>> B) { 204 if (B == null || B.isEmpty()) { 205 return true; 206 } 207 if (!engine.isCoPrime(B)) { 208 return false; 209 } 210 return isSquarefree(B); 211 } 212 213 214 /** 215 * Normalize factorization. p'_i > 0 for i > 1 and p'_1 != 1 if k > 216 * 1. 217 * @param F = [p_1->e_1;, ..., p_k->e_k]. 218 * @return F' = [p'_1->e_1, ..., p'_k->e_k]. 219 */ 220 public SortedMap<GenPolynomial<C>, Long> normalizeFactorization(SortedMap<GenPolynomial<C>, Long> F) { 221 if (F == null || F.size() <= 1) { 222 return F; 223 } 224 List<GenPolynomial<C>> Fp = new ArrayList<GenPolynomial<C>>(F.keySet()); 225 GenPolynomial<C> f0 = Fp.get(0); 226 if (f0.ring.characteristic().signum() != 0) { // only ordered coefficients 227 return F; 228 } 229 long e0 = F.get(f0); 230 SortedMap<GenPolynomial<C>, Long> Sp = new TreeMap<GenPolynomial<C>, Long>(); 231 for (int i = 1; i < Fp.size(); i++) { 232 GenPolynomial<C> fi = Fp.get(i); 233 long ei = F.get(fi); 234 if (fi.signum() < 0) { 235 //System.out.println("e0 = " + e0 + ", f0 = " + f0); 236 //System.out.println("ei = " + ei + ", fi = " + fi); 237 fi = fi.negate(); 238 if (ei % 2 != 0) { // && e0 % 2 != 0 239 f0 = f0.negate(); 240 } 241 } 242 Sp.put(fi, ei); 243 } 244 if (!f0.isONE()) { 245 Sp.put(f0, e0); 246 } 247 return Sp; 248 } 249 250 251 /** 252 * GenPolynomial is (squarefree) factorization. 253 * @param P GenPolynomial. 254 * @param F = [p_1,...,p_k]. 255 * @return true if P = prod_{i=1,...,r} p_i, else false. 256 */ 257 public boolean isFactorization(GenPolynomial<C> P, List<GenPolynomial<C>> F) { 258 if (P == null || F == null) { 259 throw new IllegalArgumentException("P and F may not be null"); 260 } 261 GenPolynomial<C> t = P.ring.getONE(); 262 for (GenPolynomial<C> f : F) { 263 t = t.multiply(f); 264 } 265 boolean f = P.equals(t) || P.equals(t.negate()); 266 if (!f) { 267 System.out.println("\nfactorization(list): " + f); 268 System.out.println("F = " + F); 269 System.out.println("P = " + P); 270 System.out.println("t = " + t); 271 } 272 return f; 273 } 274 275 276 /** 277 * Count number of factors in a (squarefree) factorization. 278 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 279 * @return sum_{i=1,...,k} e_i. 280 */ 281 public long factorCount(SortedMap<GenPolynomial<C>, Long> F) { 282 if (F == null || F.isEmpty()) { 283 return 0L; 284 } 285 long f = 0L; 286 for (Long e : F.values()) { 287 f += e; 288 } 289 return f; 290 } 291 292 293 /** 294 * GenPolynomial is (squarefree) factorization. 295 * @param P GenPolynomial. 296 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 297 * @return true if P = prod_{i=1,...,k} p_i**e_i, else false. 298 */ 299 public boolean isFactorization(GenPolynomial<C> P, SortedMap<GenPolynomial<C>, Long> F) { 300 if (P == null || F == null) { 301 throw new IllegalArgumentException("P and F may not be null"); 302 } 303 if (P.isZERO() && F.size() == 0) { 304 return true; 305 } 306 GenPolynomial<C> t = P.ring.getONE(); 307 for (Map.Entry<GenPolynomial<C>, Long> me : F.entrySet()) { 308 GenPolynomial<C> f = me.getKey(); 309 Long E = me.getValue(); // F.get(f); 310 long e = E.longValue(); 311 GenPolynomial<C> g = Power.<GenPolynomial<C>> positivePower(f, e); 312 t = t.multiply(g); 313 } 314 boolean f = P.equals(t) || P.equals(t.negate()); 315 if (!f) { 316 //System.out.println("P = " + P); 317 //System.out.println("t = " + t); 318 P = P.monic(); 319 t = t.monic(); 320 f = P.equals(t) || P.equals(t.negate()); 321 if (f) { 322 return f; 323 } 324 System.out.println("\nfactorization(map): " + f); 325 System.out.println("F = " + F); 326 System.out.println("P = " + P); 327 System.out.println("t = " + t); 328 //RuntimeException e = new RuntimeException("fac-map"); 329 //e.printStackTrace(); 330 //throw e; 331 } 332 return f; 333 } 334 335 336 /** 337 * GenPolynomial is (squarefree) factorization. 338 * @param P GenPolynomial. 339 * @param F = [p_1 -> e_1, ..., p_k -> e_k]. 340 * @return true if P = prod_{i=1,...,k} p_i**e_i, else false. 341 */ 342 public boolean isRecursiveFactorization(GenPolynomial<GenPolynomial<C>> P, 343 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> F) { 344 if (P == null || F == null) { 345 throw new IllegalArgumentException("P and F may not be null"); 346 } 347 if (P.isZERO() && F.size() == 0) { 348 return true; 349 } 350 GenPolynomial<GenPolynomial<C>> t = P.ring.getONE(); 351 for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> me : F.entrySet()) { 352 GenPolynomial<GenPolynomial<C>> f = me.getKey(); 353 Long E = me.getValue(); // F.get(f); 354 long e = E.longValue(); 355 GenPolynomial<GenPolynomial<C>> g = Power.<GenPolynomial<GenPolynomial<C>>> positivePower(f, e); 356 t = t.multiply(g); 357 } 358 boolean f = P.equals(t) || P.equals(t.negate()); 359 if (!f) { 360 //System.out.println("P = " + P); 361 //System.out.println("t = " + t); 362 GenPolynomialRing<C> cf = (GenPolynomialRing<C>) P.ring.coFac; 363 GreatestCommonDivisorAbstract<C> engine = GCDFactory.getProxy(cf.coFac); 364 GenPolynomial<GenPolynomial<C>> Pp = engine.recursivePrimitivePart(P); 365 Pp = PolyUtil.<C> monic(Pp); 366 GenPolynomial<GenPolynomial<C>> tp = engine.recursivePrimitivePart(t); 367 tp = PolyUtil.<C> monic(tp); 368 f = Pp.equals(tp) || Pp.equals(tp.negate()); 369 if (f) { 370 return f; 371 } 372 System.out.println("\nfactorization(map): " + f); 373 System.out.println("F = " + F); 374 System.out.println("P = " + P); 375 System.out.println("t = " + t); 376 System.out.println("Pp = " + Pp); 377 System.out.println("tp = " + tp); 378 //RuntimeException e = new RuntimeException("fac-map"); 379 //e.printStackTrace(); 380 //throw e; 381 } 382 return f; 383 } 384 385 386 /** 387 * GenPolynomial recursive polynomial greatest squarefree divisor. 388 * @param P recursive GenPolynomial. 389 * @return squarefree(pp(P)). 390 */ 391 public GenPolynomial<GenPolynomial<C>> recursiveSquarefreePart(GenPolynomial<GenPolynomial<C>> P) { 392 if (P == null || P.isZERO()) { 393 return P; 394 } 395 if (P.ring.nvar <= 1) { 396 return recursiveUnivariateSquarefreePart(P); 397 } 398 // distributed polynomials squarefree part 399 GenPolynomialRing<GenPolynomial<C>> rfac = P.ring; 400 RingFactory<GenPolynomial<C>> rrfac = rfac.coFac; 401 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) rrfac; 402 GenPolynomialRing<C> dfac = cfac.extend(rfac.nvar); 403 GenPolynomial<C> Pd = PolyUtil.<C> distribute(dfac, P); 404 GenPolynomial<C> Dd = squarefreePart(Pd); 405 // convert to recursive 406 GenPolynomial<GenPolynomial<C>> C = PolyUtil.<C> recursive(rfac, Dd); 407 return C; 408 } 409 410 411 /** 412 * GenPolynomial recursive polynomial squarefree factorization. 413 * @param P recursive GenPolynomial. 414 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 415 * p_i^{e_i} and p_i squarefree. 416 */ 417 public SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveSquarefreeFactors( 418 GenPolynomial<GenPolynomial<C>> P) { 419 SortedMap<GenPolynomial<GenPolynomial<C>>, Long> factors; 420 factors = new TreeMap<GenPolynomial<GenPolynomial<C>>, Long>(); 421 if (P == null || P.isZERO()) { 422 return factors; 423 } 424 if (P.ring.nvar <= 1) { 425 return recursiveUnivariateSquarefreeFactors(P); 426 } 427 // distributed polynomials squarefree part 428 GenPolynomialRing<GenPolynomial<C>> rfac = P.ring; 429 RingFactory<GenPolynomial<C>> rrfac = rfac.coFac; 430 GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) rrfac; 431 GenPolynomialRing<C> dfac = cfac.extend(rfac.nvar); 432 GenPolynomial<C> Pd = PolyUtil.<C> distribute(dfac, P); 433 SortedMap<GenPolynomial<C>, Long> dfacs = squarefreeFactors(Pd); 434 // convert to recursive 435 for (Map.Entry<GenPolynomial<C>, Long> Dm : dfacs.entrySet()) { 436 GenPolynomial<C> Dd = Dm.getKey(); 437 Long e = Dm.getValue(); 438 GenPolynomial<GenPolynomial<C>> C = PolyUtil.<C> recursive(rfac, Dd); 439 factors.put(C, e); 440 } 441 return factors; 442 } 443 444 445 /** 446 * Univariate GenPolynomial partial fraction decomposition. 447 * @param A univariate GenPolynomial. 448 * @param D sorted map [d_1 -> e_1, ..., d_k -> e_k] with d_i 449 * squarefree. 450 * @return [ [Ai0, Ai1,..., Aie_i], i=0,...,k ] with A/prod(D) = A0 + sum( 451 * sum ( Aij/di^j ) ) with deg(Aij) < deg(di). 452 */ 453 public List<List<GenPolynomial<C>>> basePartialFraction(GenPolynomial<C> A, 454 SortedMap<GenPolynomial<C>, Long> D) { 455 if (D == null || A == null) { 456 throw new IllegalArgumentException("null A or D not allowed"); 457 } 458 List<List<GenPolynomial<C>>> pf = new ArrayList<List<GenPolynomial<C>>>(D.size() + 1); 459 if (D.size() == 0) { 460 return pf; 461 } 462 //List<GenPolynomial<C>> fi; 463 if (A.isZERO()) { 464 for (Map.Entry<GenPolynomial<C>, Long> me : D.entrySet()) { 465 //GenPolynomial<C> d = me.getKey(); 466 long e = me.getValue(); //D.get(d); 467 int e1 = (int) e + 1; 468 List<GenPolynomial<C>> fi = new ArrayList<GenPolynomial<C>>(e1); 469 for (int i = 0; i < e1; i++) { 470 fi.add(A); 471 } 472 pf.add(fi); 473 } 474 List<GenPolynomial<C>> fi = new ArrayList<GenPolynomial<C>>(1); 475 fi.add(A); 476 pf.add(0, fi); 477 return pf; 478 } 479 // A != 0, D != empty 480 List<GenPolynomial<C>> Dp = new ArrayList<GenPolynomial<C>>(D.size()); 481 for (Map.Entry<GenPolynomial<C>, Long> me : D.entrySet()) { 482 GenPolynomial<C> d = me.getKey(); 483 long e = me.getValue(); //D.get(d); 484 GenPolynomial<C> f = Power.<GenPolynomial<C>> positivePower(d, e); 485 Dp.add(f); 486 } 487 List<GenPolynomial<C>> F = engine.basePartialFraction(A, Dp); 488 //System.out.println("fraction list = " + F.size()); 489 GenPolynomial<C> A0 = F.remove(0); 490 List<GenPolynomial<C>> fi = new ArrayList<GenPolynomial<C>>(1); 491 fi.add(A0); 492 pf.add(fi); 493 int i = 0; 494 for (Map.Entry<GenPolynomial<C>, Long> me : D.entrySet()) { // assume fixed sequence order 495 GenPolynomial<C> d = me.getKey(); 496 long e = me.getValue(); // D.get(d); 497 int ei = (int) e; 498 GenPolynomial<C> gi = F.get(i); // assume fixed sequence order 499 List<GenPolynomial<C>> Fi = engine.basePartialFraction(gi, d, ei); 500 pf.add(Fi); 501 i++; 502 } 503 return pf; 504 } 505 506 507 /** 508 * Test for Univariate GenPolynomial partial fraction decomposition. 509 * @param A univariate GenPolynomial. 510 * @param D sorted map [d_1 -> e_1, ..., d_k -> e_k] with d_i 511 * squarefree. 512 * @param F a list of lists [ [Ai0, Ai1,..., Aie_i], i=0,...,k ] 513 * @return true, if A/prod(D) = A0 + sum( sum ( Aij/di^j ) ), else false. 514 */ 515 public boolean isBasePartialFraction(GenPolynomial<C> A, SortedMap<GenPolynomial<C>, Long> D, 516 List<List<GenPolynomial<C>>> F) { 517 if (D == null || A == null || F == null) { 518 throw new IllegalArgumentException("null A, D or F not allowed"); 519 } 520 if (D.isEmpty() && F.isEmpty()) { 521 return true; 522 } 523 if (D.isEmpty() || F.isEmpty()) { 524 return false; 525 } 526 List<GenPolynomial<C>> Dp = new ArrayList<GenPolynomial<C>>(D.size()); 527 for (Map.Entry<GenPolynomial<C>, Long> me : D.entrySet()) { 528 GenPolynomial<C> d = me.getKey(); 529 long e = me.getValue(); // D.get(d); 530 GenPolynomial<C> f = Power.<GenPolynomial<C>> positivePower(d, e); 531 Dp.add(f); 532 } 533 List<GenPolynomial<C>> fi = F.get(0); 534 if (fi.size() != 1) { 535 System.out.println("size(fi) != 1 " + fi); 536 return false; 537 } 538 boolean t; 539 GenPolynomial<C> A0 = fi.get(0); 540 //System.out.println("A0 = " + A0); 541 List<GenPolynomial<C>> Qp = new ArrayList<GenPolynomial<C>>(D.size() + 1); 542 Qp.add(A0); 543 544 // List<GenPolynomial<C>> Fp = engine.basePartialFraction(A,Dp); 545 // System.out.println("fraction list = " + F.size()); 546 // t = engine.isBasePartialFraction(A,Dp,Fp); 547 // if ( ! t ) { 548 // System.out.println("not recursion isPartFrac = " + Fp); 549 // return false; 550 // } 551 // GenPolynomial<C> A0p = Fp.remove(0); 552 // if ( ! A0.equals(A0p) ) { 553 // System.out.println("A0 != A0p " + A0p); 554 // return false; 555 // } 556 557 int i = 0; 558 for (Map.Entry<GenPolynomial<C>, Long> me : D.entrySet()) { // assume fixed sequence order 559 GenPolynomial<C> d = me.getKey(); 560 long e = me.getValue(); // D.get(d); 561 int ei = (int) e; 562 List<GenPolynomial<C>> Fi = F.get(i + 1); // assume fixed sequence order 563 564 // GenPolynomial<C> pi = Fp.get(i); // assume fixed sequence order 565 // t = engine.isBasePartialFraction(pi,d,ei,Fi); 566 // if ( ! t ) { 567 // System.out.println("not isPartFrac exp = " + pi + ", d = " + d + ", e = " + ei); 568 // System.out.println("not isPartFrac exp = " + Fi); 569 // return false; 570 // } 571 572 GenPolynomial<C> qi = engine.basePartialFractionValue(d, ei, Fi); 573 Qp.add(qi); 574 575 // t = qi.equals(pi); 576 // if ( ! t ) { 577 // System.out.println("not isPartFrac exp = " + pi + ", d = " + d + ", e = " + ei + ", qi = " + qi); 578 // } 579 580 i++; 581 } 582 583 t = engine.isBasePartialFraction(A, Dp, Qp); 584 if (!t) { 585 System.out.println("not final isPartFrac " + Qp); 586 } 587 return t; 588 } 589 590 591 /** 592 * Coefficients greatest squarefree divisor. 593 * @param P coefficient. 594 * @return squarefree part of P. 595 */ 596 public C squarefreePart(C P) { 597 if (P == null) { 598 return null; 599 } 600 // just for the moment: TODO 601 C s = null; 602 SortedMap<C, Long> factors = squarefreeFactors(P); 603 //logger.info("sqfPart,factors = " + factors); 604 System.out.println("sqfPart,factors = " + factors); 605 for (C sp : factors.keySet()) { 606 if (s == null) { 607 s = sp; 608 } else { 609 s = s.multiply(sp); 610 } 611 } 612 return s; 613 } 614 615 616 /** 617 * Coefficients squarefree factorization. 618 * @param P coefficient. 619 * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} 620 * p_i^{e_i} and p_i squarefree. 621 */ 622 public abstract SortedMap<C, Long> squarefreeFactors(C P); 623 /* not possible: 624 { 625 if (P == null) { 626 return null; 627 } 628 SortedMap<C, Long> factors = new TreeMap<C, Long>(); 629 SquarefreeAbstract<C> reng = SquarefreeFactory.getImplementation((RingFactory<C>) P.factory()); 630 System.out.println("fcp,reng = " + reng); 631 SortedMap<C, Long> rfactors = reng.squarefreeFactors(P); 632 for (C c : rfactors.keySet()) { 633 if (!c.isONE()) { 634 C cr = (C) (Object) c; 635 Long rk = rfactors.get(c); 636 factors.put(cr, rk); 637 } 638 } 639 640 return factors; 641 } 642 */ 643 644}