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