001 /* 002 * $Id: RReductionSeq.java 3423 2010-12-24 10:56:50Z kredel $ 003 */ 004 005 package edu.jas.gbufd; 006 007 008 import java.util.ArrayList; 009 import java.util.Iterator; 010 import java.util.List; 011 import java.util.Map; 012 013 import org.apache.log4j.Logger; 014 015 import edu.jas.gb.ReductionAbstract; 016 import edu.jas.poly.ExpVector; 017 import edu.jas.poly.GenPolynomial; 018 import edu.jas.poly.GenSolvablePolynomial; 019 020 import edu.jas.structure.RegularRingElem; 021 022 023 /** 024 * Polynomial Regular ring Reduction sequential use algorithm. Implements 025 * normalform and boolean closure stuff. 026 * @param <C> coefficient type 027 * @author Heinz Kredel 028 */ 029 030 public class RReductionSeq<C extends RegularRingElem<C>> extends ReductionAbstract<C> 031 implements RReduction<C> { 032 033 034 private static final Logger logger = Logger.getLogger(RReductionSeq.class); 035 036 037 private final boolean debug = logger.isDebugEnabled(); 038 039 040 /** 041 * Constructor. 042 */ 043 public RReductionSeq() { 044 } 045 046 047 /** 048 * Is top reducible. Condition is a b != 0, for a=ldcf(A) and b=ldcf(B) and 049 * lt(B) | lt(A) for some B in F. 050 * @param A polynomial. 051 * @param P polynomial list. 052 * @return true if A is top reducible with respect to P. 053 */ 054 @Override 055 public boolean isTopReducible(List<GenPolynomial<C>> P, GenPolynomial<C> A) { 056 if (P == null || P.isEmpty()) { 057 return false; 058 } 059 if (A == null || A.isZERO()) { 060 return false; 061 } 062 boolean mt = false; 063 ExpVector e = A.leadingExpVector(); 064 C a = A.leadingBaseCoefficient(); 065 a = a.idempotent(); 066 for (GenPolynomial<C> p : P) { 067 mt = e.multipleOf(p.leadingExpVector()); 068 if (mt) { 069 C b = p.leadingBaseCoefficient(); 070 //C r = a.multiply( b ); 071 //C r = a.multiply( b.idempotent() ); 072 C r = a.idempotentAnd(b); 073 mt = !r.isZERO(); 074 if (mt) { 075 return true; 076 } 077 } 078 } 079 return false; 080 } 081 082 083 /** 084 * Is strong top reducible. Condition is idempotent(a) == idempotent(b), for 085 * a=ldcf(A) and b=ldcf(B) and lt(B) | lt(A) for some B in F. 086 * @param A polynomial. 087 * @param P polynomial list. 088 * @return true if A is string top reducible with respect to P. 089 */ 090 public boolean isStrongTopReducible(List<GenPolynomial<C>> P, GenPolynomial<C> A) { 091 if (P == null || P.isEmpty()) { 092 return false; 093 } 094 if (A == null || A.isZERO()) { 095 return false; 096 } 097 boolean mt = false; 098 ExpVector e = A.leadingExpVector(); 099 C a = A.leadingBaseCoefficient(); 100 a = a.idempotent(); 101 for (GenPolynomial<C> p : P) { 102 mt = e.multipleOf(p.leadingExpVector()); 103 if (mt) { 104 C b = p.leadingBaseCoefficient(); 105 mt = a.equals(b.idempotent()); 106 if (mt) { 107 return true; 108 } 109 } 110 } 111 return false; 112 } 113 114 115 /** 116 * Is in Normalform. 117 * @param Ap polynomial. 118 * @param Pp polynomial list. 119 * @return true if Ap is in normalform with respect to Pp. 120 */ 121 @Override 122 @SuppressWarnings("unchecked") 123 public boolean isNormalform(List<GenPolynomial<C>> Pp, GenPolynomial<C> Ap) { 124 if (Pp == null || Pp.isEmpty()) { 125 return true; 126 } 127 if (Ap == null || Ap.isZERO()) { 128 return true; 129 } 130 int l; 131 GenPolynomial<C>[] P; 132 synchronized (Pp) { 133 l = Pp.size(); 134 P = new GenPolynomial[l]; 135 //P = Pp.toArray(); 136 for (int i = 0; i < Pp.size(); i++) { 137 P[i] = Pp.get(i); 138 } 139 } 140 ExpVector[] htl = new ExpVector[l]; 141 C[] lbc = (C[]) new RegularRingElem[l]; // want <C> 142 GenPolynomial<C>[] p = new GenPolynomial[l]; 143 Map.Entry<ExpVector, C> m; 144 int i; 145 int j = 0; 146 for (i = 0; i < l; i++) { 147 if (P[i] == null) { 148 continue; 149 } 150 p[i] = P[i]; 151 m = p[i].leadingMonomial(); 152 if (m != null) { 153 p[j] = p[i]; 154 htl[j] = m.getKey(); 155 lbc[j] = m.getValue(); 156 j++; 157 } 158 } 159 l = j; 160 boolean mt = false; 161 Map<ExpVector, C> Am = Ap.getMap(); 162 for (ExpVector e : Am.keySet()) { 163 for (i = 0; i < l; i++) { 164 mt = e.multipleOf(htl[i]); 165 if (mt) { 166 C a = Am.get(e); 167 //C r = a.multiply( lbc[i] ); 168 //C r = a.idempotent().multiply( lbc[i].idempotent() ); 169 C r = a.idempotentAnd(lbc[i]); 170 mt = !r.isZERO(); 171 if (mt) { 172 return false; 173 } 174 } 175 } 176 } 177 return true; 178 } 179 180 181 /** 182 * Normalform using r-reduction. 183 * @param Ap polynomial. 184 * @param Pp polynomial list. 185 * @return r-nf(Ap) with respect to Pp. 186 */ 187 @SuppressWarnings("unchecked") 188 public GenPolynomial<C> normalform(List<GenPolynomial<C>> Pp, GenPolynomial<C> Ap) { 189 if (Pp == null || Pp.isEmpty()) { 190 return Ap; 191 } 192 if (Ap == null || Ap.isZERO()) { 193 return Ap; 194 } 195 int l; 196 GenPolynomial<C>[] P; 197 synchronized (Pp) { 198 l = Pp.size(); 199 P = (GenPolynomial<C>[]) new GenPolynomial[l]; 200 //P = Pp.toArray(); 201 for (int i = 0; i < Pp.size(); i++) { 202 P[i] = Pp.get(i); 203 } 204 } 205 //System.out.println("l = " + l); 206 Map.Entry<ExpVector, C> m; 207 ExpVector[] htl = new ExpVector[l]; 208 C[] lbc = (C[]) new RegularRingElem[l]; // want <C> 209 GenPolynomial<C>[] p = (GenPolynomial<C>[]) new GenPolynomial[l]; 210 int i; 211 int j = 0; 212 for (i = 0; i < l; i++) { 213 if (P[i] == null) { 214 continue; 215 } 216 p[i] = P[i].abs(); 217 m = p[i].leadingMonomial(); 218 if (m != null) { 219 p[j] = p[i]; 220 htl[j] = m.getKey(); 221 lbc[j] = m.getValue(); 222 j++; 223 } 224 } 225 l = j; 226 ExpVector e, f; 227 C a, b; 228 C r = null; 229 boolean mt = false; 230 GenPolynomial<C> R = Ap.ring.getZERO(); 231 GenPolynomial<C> Q = null; 232 GenPolynomial<C> S = Ap; 233 while (S.length() > 0) { 234 m = S.leadingMonomial(); 235 e = m.getKey(); 236 a = m.getValue(); 237 for (i = 0; i < l; i++) { 238 mt = e.multipleOf(htl[i]); 239 if (mt) { 240 //r = a.multiply( lbc[i] ); 241 //r = a.idempotent().multiply( lbc[i].idempotent() ); 242 r = a.idempotentAnd(lbc[i]); 243 //System.out.println("r = " + r); 244 mt = !r.isZERO(); // && mt 245 if (mt) { 246 b = a.divide(lbc[i]); 247 if (b.isZERO()) { // strange case in regular rings 248 System.out.println("b == zero: r = " + r); 249 continue; 250 } 251 f = e.subtract(htl[i]); 252 //logger.info("red div = " + f); 253 Q = p[i].multiply(b, f); 254 S = S.subtract(Q); // not ok with reductum 255 f = S.leadingExpVector(); 256 if (!e.equals(f)) { 257 a = Ap.ring.coFac.getZERO(); 258 break; 259 } 260 a = S.leadingBaseCoefficient(); 261 } 262 } 263 } 264 if (!a.isZERO()) { //! mt ) { 265 //logger.debug("irred"); 266 R = R.sum(a, e); 267 S = S.reductum(); 268 } 269 } 270 return R; //.abs(); // not monic if not boolean closed 271 } 272 273 274 /** 275 * GB criterium 4. Use only for commutative polynomial rings. <b>Note:</b> 276 * Experimental version for r-Groebner bases. 277 * @param A polynomial. 278 * @param B polynomial. 279 * @param e = lcm(ht(A),ht(B)) 280 * @return true if the S-polynomial(i,j) is required, else false. 281 */ 282 @Override 283 public boolean criterion4(GenPolynomial<C> A, GenPolynomial<C> B, ExpVector e) { 284 if (logger.isInfoEnabled()) { 285 if (!A.ring.equals(B.ring)) { 286 logger.error("rings equal"); 287 } 288 if (A instanceof GenSolvablePolynomial || B instanceof GenSolvablePolynomial) { 289 logger.error("GBCriterion4 not applicabable to SolvablePolynomials"); 290 return true; 291 } 292 } 293 ExpVector ei = A.leadingExpVector(); 294 ExpVector ej = B.leadingExpVector(); 295 ExpVector g = ei.sum(ej); 296 // boolean t = g == e ; 297 ExpVector h = g.subtract(e); 298 int s = h.signum(); 299 if (s == 0) { // disjoint ht 300 C a = A.leadingBaseCoefficient(); 301 C b = B.leadingBaseCoefficient(); 302 C d = a.multiply(b); 303 if (d.isZERO()) { // a guess 304 //System.out.println("d1 = " + d + ", a = " + a + ", b = " + b); 305 return false; // can skip pair 306 } 307 } 308 return true; //! ( s == 0 ); 309 } 310 311 312 /** 313 * GB criterium 4. Use only for commutative polynomial rings. <b>Note:</b> 314 * Experimental version for r-Groebner bases. 315 * @param A polynomial. 316 * @param B polynomial. 317 * @return true if the S-polynomial(i,j) is required, else false. 318 */ 319 @Override 320 public boolean criterion4(GenPolynomial<C> A, GenPolynomial<C> B) { 321 if (logger.isInfoEnabled()) { 322 if (A instanceof GenSolvablePolynomial || B instanceof GenSolvablePolynomial) { 323 logger.error("GBCriterion4 not applicabable to SolvablePolynomials"); 324 return true; 325 } 326 } 327 ExpVector ei = A.leadingExpVector(); 328 ExpVector ej = B.leadingExpVector(); 329 ExpVector g = ei.sum(ej); 330 ExpVector e = ei.lcm(ej); 331 // boolean t = g == e ; 332 ExpVector h = g.subtract(e); 333 int s = h.signum(); 334 if (s == 0) { // disjoint ht 335 C a = A.leadingBaseCoefficient(); 336 C b = B.leadingBaseCoefficient(); 337 C d = a.multiply(b); 338 if (d.isZERO()) { // a guess 339 return false; // can skip pair 340 } 341 } 342 return true; //! ( s == 0 ); 343 } 344 345 346 /** 347 * Normalform with recording. 348 * @param row recording matrix, is modified. 349 * @param Pp a polynomial list for reduction. 350 * @param Ap a polynomial. 351 * @return Ap - row*Pp = nf(Pp,Ap) , the normal form of Ap wrt. Pp. 352 */ 353 @SuppressWarnings("unchecked") 354 public GenPolynomial<C> normalform(List<GenPolynomial<C>> row, 355 List<GenPolynomial<C>> Pp, GenPolynomial<C> Ap) { 356 if (Pp == null || Pp.isEmpty()) { 357 return Ap; 358 } 359 if (Ap == null || Ap.isZERO()) { 360 return Ap; 361 } 362 int l; 363 GenPolynomial<C>[] P; 364 synchronized (Pp) { 365 l = Pp.size(); 366 P = (GenPolynomial<C>[]) new GenPolynomial[l]; 367 //P = Pp.toArray(); 368 for (int i = 0; i < Pp.size(); i++) { 369 P[i] = Pp.get(i); 370 } 371 } 372 //System.out.println("l = " + l); 373 Map.Entry<ExpVector, C> m; 374 ExpVector[] htl = new ExpVector[l]; 375 C[] lbc = (C[]) new RegularRingElem[l]; // want <C> 376 GenPolynomial<C>[] p = (GenPolynomial<C>[]) new GenPolynomial[l]; 377 int i; 378 int j = 0; 379 for (i = 0; i < l; i++) { 380 p[i] = P[i]; 381 m = p[i].leadingMonomial(); 382 if (m != null) { 383 p[j] = p[i]; 384 htl[j] = m.getKey(); 385 lbc[j] = m.getValue(); 386 j++; 387 } 388 } 389 l = j; 390 ExpVector e, f; 391 C a; 392 C r = null; 393 boolean mt = false; 394 GenPolynomial<C> fac = null; 395 GenPolynomial<C> zero = Ap.ring.getZERO(); 396 GenPolynomial<C> R = Ap.ring.getZERO(); 397 GenPolynomial<C> Q = null; 398 GenPolynomial<C> S = Ap; 399 while (S.length() > 0) { 400 m = S.leadingMonomial(); 401 e = m.getKey(); 402 a = m.getValue(); 403 for (i = 0; i < l; i++) { 404 mt = e.multipleOf(htl[i]); 405 if (mt) { 406 //r = a.idempotent().multiply( lbc[i].idempotent() ); 407 //r = a.multiply( lbc[i] ); 408 r = a.idempotentAnd(lbc[i]); 409 //System.out.println("r = " + r); 410 mt = !r.isZERO(); // && mt 411 if (mt) { 412 a = a.divide(lbc[i]); 413 if (a.isZERO()) { // strange case in regular rings 414 System.out.println("b == zero: r = " + r); 415 continue; 416 } 417 f = e.subtract(htl[i]); 418 //logger.info("red div = " + f); 419 Q = p[i].multiply(a, f); 420 S = S.subtract(Q); // not ok with reductum 421 422 fac = row.get(i); 423 if (fac == null) { 424 fac = zero.sum(a, f); 425 } else { 426 fac = fac.sum(a, f); 427 } 428 row.set(i, fac); 429 430 f = S.leadingExpVector(); 431 if (!e.equals(f)) { 432 a = Ap.ring.coFac.getZERO(); 433 break; 434 } 435 a = S.leadingBaseCoefficient(); 436 } 437 } 438 } 439 if (!a.isZERO()) { //! mt ) { 440 //logger.debug("irred"); 441 R = R.sum(a, e); 442 S = S.reductum(); 443 } 444 } 445 return R; //.abs(); not for recording 446 } 447 448 449 /** 450 * Irreducible set. May not be boolean closed. 451 * @param Pp polynomial list. 452 * @return a list P of polynomials which are in normalform wrt. P. 453 */ 454 @Override 455 public List<GenPolynomial<C>> irreducibleSet(List<GenPolynomial<C>> Pp) { 456 ArrayList<GenPolynomial<C>> P = new ArrayList<GenPolynomial<C>>(); 457 if (Pp == null) { 458 return null; 459 } 460 for (GenPolynomial<C> a : Pp) { 461 if (!a.isZERO()) { 462 P.add(a); 463 } 464 } 465 int l = P.size(); 466 if (l <= 1) 467 return P; 468 469 int irr = 0; 470 ExpVector e; 471 ExpVector f; 472 GenPolynomial<C> a; 473 Iterator<GenPolynomial<C>> it; 474 logger.debug("irr = "); 475 while (irr != l) { 476 //it = P.listIterator(); 477 //a = P.get(0); //it.next(); 478 a = P.remove(0); 479 e = a.leadingExpVector(); 480 a = normalform(P, a); 481 // no not make monic because of boolean closure 482 logger.debug(String.valueOf(irr)); 483 if (a.isZERO()) { 484 l--; 485 if (l <= 1) { 486 return P; 487 } 488 } else { 489 f = a.leadingExpVector(); 490 if (e.equals(f)) { 491 // lbcf(a) eventually shorter 492 // correct since longer coeffs can reduce shorter coeffs 493 irr++; 494 } else { 495 irr = 0; 496 } 497 P.add(a); 498 } 499 } 500 //System.out.println(); 501 return P; 502 } 503 504 505 /* 506 * -------- boolean closure stuff ----------------------------------------- 507 */ 508 509 /** 510 * Is boolean closed, test if A == idempotent(ldcf(A)) A. 511 * @param A polynomial. 512 * @return true if A is boolean closed, else false. 513 */ 514 public boolean isBooleanClosed(GenPolynomial<C> A) { 515 if (A == null || A.isZERO()) { 516 return true; 517 } 518 C a = A.leadingBaseCoefficient(); 519 C i = a.idempotent(); 520 GenPolynomial<C> B = A.multiply(i); 521 // better run idemAnd on coefficients 522 if (A.equals(B)) { 523 return true; 524 } 525 return false; 526 } 527 528 529 /** 530 * Is boolean closed, test if all A in F are boolean closed. 531 * @param F polynomial list. 532 * @return true if F is boolean closed, else false. 533 */ 534 public boolean isBooleanClosed(List<GenPolynomial<C>> F) { 535 if (F == null || F.size() == 0) { 536 return true; 537 } 538 for (GenPolynomial<C> a : F) { 539 if (a == null || a.isZERO()) { 540 continue; 541 } 542 //System.out.println("a = " + a); 543 if (!isBooleanClosed(a)) { 544 return false; 545 } 546 } 547 return true; 548 } 549 550 551 /** 552 * Is reduced boolean closed, test if all A in F are boolean closed or br(A) 553 * reduces to zero. 554 * @param F polynomial list. 555 * @return true if F is boolean closed, else false. 556 */ 557 public boolean isReducedBooleanClosed(List<GenPolynomial<C>> F) { 558 if (F == null || F.size() == 0) { 559 return true; 560 } 561 GenPolynomial<C> b; 562 GenPolynomial<C> r; 563 for (GenPolynomial<C> a : F) { 564 //System.out.println("a = " + a); 565 if (a == null) { 566 continue; 567 } 568 while (!a.isZERO()) { 569 if (!isBooleanClosed(a)) { 570 b = booleanClosure(a); 571 b = normalform(F, b); 572 if (!b.isZERO()) { //F.contains(r) 573 return false; 574 } 575 } 576 r = booleanRemainder(a); 577 r = normalform(F, r); 578 if (!r.isZERO()) { //F.contains(r) 579 return false; 580 } 581 //System.out.println("r = " + r); 582 a = r; 583 } 584 } 585 return true; 586 } 587 588 589 /** 590 * Boolean closure, compute idempotent(ldcf(A)) A. 591 * @param A polynomial. 592 * @return bc(A). 593 */ 594 public GenPolynomial<C> booleanClosure(GenPolynomial<C> A) { 595 if (A == null || A.isZERO()) { 596 return A; 597 } 598 C a = A.leadingBaseCoefficient(); 599 C i = a.idempotent(); 600 GenPolynomial<C> B = A.multiply(i); 601 return B; 602 } 603 604 605 /** 606 * Boolean remainder, compute idemComplement(ldcf(A)) A. 607 * @param A polynomial. 608 * @return br(A). 609 */ 610 public GenPolynomial<C> booleanRemainder(GenPolynomial<C> A) { 611 if (A == null || A.isZERO()) { 612 return A; 613 } 614 C a = A.leadingBaseCoefficient(); 615 C i = a.idemComplement(); 616 GenPolynomial<C> B = A.multiply(i); 617 return B; 618 } 619 620 621 /** 622 * Boolean closure, compute BC(A) for all A in F. 623 * @param F polynomial list. 624 * @return bc(F). 625 */ 626 public List<GenPolynomial<C>> booleanClosure(List<GenPolynomial<C>> F) { 627 if (F == null || F.size() == 0) { 628 return F; 629 } 630 List<GenPolynomial<C>> B = new ArrayList<GenPolynomial<C>>(F.size()); 631 for (GenPolynomial<C> a : F) { 632 if (a == null) { 633 continue; 634 } 635 while (!a.isZERO()) { 636 GenPolynomial<C> b = booleanClosure(a); 637 B.add(b); 638 a = booleanRemainder(a); 639 } 640 } 641 return B; 642 } 643 644 645 /** 646 * Reduced boolean closure, compute BC(A) for all A in F. 647 * @param F polynomial list. 648 * @return red(bc(F)) = bc(red(F)). 649 */ 650 public List<GenPolynomial<C>> reducedBooleanClosure(List<GenPolynomial<C>> F) { 651 if (F == null || F.size() == 0) { 652 return F; 653 } 654 List<GenPolynomial<C>> B = new ArrayList<GenPolynomial<C>>(F); 655 GenPolynomial<C> a; 656 GenPolynomial<C> b; 657 GenPolynomial<C> c; 658 int len = B.size(); 659 for (int i = 0; i < len; i++) { // not B.size(), it changes 660 a = B.remove(0); 661 if (a == null) { 662 continue; 663 } 664 while (!a.isZERO()) { 665 //System.out.println("a = " + a); 666 b = booleanClosure(a); 667 //System.out.println("b = " + b); 668 b = booleanClosure(normalform(B, b)); 669 if (b.isZERO()) { 670 break; 671 } 672 B.add(b); // adds as last 673 c = a.subtract(b); // = BR(a mod B) 674 //System.out.println("c = " + c); 675 c = normalform(B, c); 676 a = c; 677 } 678 } 679 return B; 680 } 681 682 683 /** 684 * Reduced boolean closure, compute BC(A) modulo F. 685 * @param A polynomial. 686 * @param F polynomial list. 687 * @return red(bc(A)). 688 */ 689 public List<GenPolynomial<C>> reducedBooleanClosure(List<GenPolynomial<C>> F, 690 GenPolynomial<C> A) { 691 List<GenPolynomial<C>> B = new ArrayList<GenPolynomial<C>>(); 692 if (A == null || A.isZERO()) { 693 return B; 694 } 695 GenPolynomial<C> a = A; 696 GenPolynomial<C> b; 697 GenPolynomial<C> c; 698 while (!a.isZERO()) { 699 //System.out.println("a = " + a); 700 b = booleanClosure(a); 701 //System.out.println("b = " + b); 702 b = booleanClosure(normalform(F, b)); 703 if (b.isZERO()) { 704 break; 705 } 706 B.add(b); // adds as last 707 c = a.subtract(b); // = BR(a mod F) 708 //System.out.println("c = " + c); 709 c = normalform(F, c); 710 //System.out.println("c = " + c); 711 a = c; 712 } 713 return B; 714 } 715 716 }