001 /* 002 * $Id: ComprehensiveGroebnerBaseSeq.java 3626 2011-05-08 09:51:57Z kredel $ 003 */ 004 005 package edu.jas.application; 006 007 008 import java.util.ArrayList; 009 import java.util.List; 010 import java.util.Collections; 011 012 import org.apache.log4j.Logger; 013 014 import edu.jas.gb.GroebnerBase; 015 import edu.jas.gbufd.GBFactory; 016 import edu.jas.poly.ExpVector; 017 import edu.jas.poly.GenPolynomial; 018 import edu.jas.poly.GenPolynomialRing; 019 import edu.jas.structure.GcdRingElem; 020 import edu.jas.structure.RingFactory; 021 import edu.jas.ufd.SquarefreeAbstract; 022 import edu.jas.ufd.SquarefreeFactory; 023 024 025 /** 026 * Comprehensive Groebner Base sequential algorithm. Implements faithful 027 * comprehensive Groebner bases via Groebner systems and CGB test. 028 * @param <C> coefficient type 029 * @author Heinz Kredel 030 */ 031 032 public class ComprehensiveGroebnerBaseSeq<C extends GcdRingElem<C>> 033 /* extends GroebnerBaseAbstract<GenPolynomial<C>> */{ 034 035 036 private static final Logger logger = Logger.getLogger(ComprehensiveGroebnerBaseSeq.class); 037 038 039 private static final boolean debug = logger.isDebugEnabled(); 040 041 042 /** 043 * Squarefree for coefficient content and primitive parts. 044 */ 045 protected final SquarefreeAbstract<C> engine; 046 047 048 /** 049 * Flag if gcd engine should be used. 050 */ 051 private final boolean notFaithfull = false; 052 053 054 /** 055 * Comprehensive reduction engine. 056 */ 057 protected final CReductionSeq<C> cred; 058 059 060 /** 061 * Polynomial coefficient ring factory. 062 */ 063 protected final RingFactory<C> cofac; 064 065 066 /** 067 * Constructor. 068 * @param rf base coefficient ring factory. 069 */ 070 public ComprehensiveGroebnerBaseSeq(RingFactory<C> rf) { 071 this(new CReductionSeq<C>(rf), rf); 072 } 073 074 075 /** 076 * Constructor. 077 * @param red C-pseudo-Reduction engine 078 * @param rf base coefficient ring factory. 079 */ 080 @SuppressWarnings("unchecked") 081 public ComprehensiveGroebnerBaseSeq(CReductionSeq<C> red, RingFactory<C> rf) { 082 // super(null); // red not possible since type of type 083 cred = red; 084 cofac = rf; 085 // selection for C but used for R: 086 //engine e = GCDFactory.<C> getImplementation(cofac); 087 engine = SquarefreeFactory.<C> getImplementation(rf); 088 } 089 090 091 /** 092 * Comprehensive-Groebner base test. 093 * @param F polynomial list. 094 * @return true, if F is a Comprehensive-Groebner base, else false. 095 */ 096 // @Override 097 public boolean isGB(List<GenPolynomial<GenPolynomial<C>>> F) { 098 return isGB(0, F); 099 } 100 101 102 /** 103 * Comprehensive-Groebner base test. 104 * @param modv module variable number. 105 * @param F polynomial list. 106 * @return true, if F is a Comprehensive-Groebner base, else false. 107 */ 108 // @Override 109 public boolean isGB(int modv, List<GenPolynomial<GenPolynomial<C>>> F) { 110 // return isGBcol( modv, F ); 111 return isGBsubst(modv, F); 112 } 113 114 115 /** 116 * Comprehensive-Groebner base test using colored systems. 117 * @param F polynomial list. 118 * @return true, if F is a Comprehensive-Groebner base, else false. 119 */ 120 // @Override 121 public boolean isGBcol(List<GenPolynomial<GenPolynomial<C>>> F) { 122 return isGBcol(0, F); 123 } 124 125 126 /** 127 * Comprehensive-Groebner base test using colored systems. 128 * @param modv module variable number. 129 * @param F polynomial list. 130 * @return true, if F is a Comprehensive-Groebner base, else false. 131 */ 132 // @Override 133 public boolean isGBcol(int modv, List<GenPolynomial<GenPolynomial<C>>> F) { 134 if (F == null || F.size() == 0) { 135 return true; 136 } 137 List<ColoredSystem<C>> CS = cred.determine(F); 138 return isGBsys(modv, CS); 139 } 140 141 142 /** 143 * Comprehensive-Groebner system test. 144 * @param CS list of colored systems. 145 * @return true, if CS is a Comprehensive-Groebner system, else false. 146 */ 147 // @Override 148 public boolean isGBsys(List<ColoredSystem<C>> CS) { 149 return isGBsys(0, CS); 150 } 151 152 153 /** 154 * Comprehensive-Groebner system test. 155 * @param modv module variable number. 156 * @param CS list of colored systems. 157 * @return true, if CS is a Comprehensive-Groebner system, else false. 158 */ 159 // @Override 160 public boolean isGBsys(int modv, List<ColoredSystem<C>> CS) { 161 if (CS == null || CS.size() == 0) { 162 return true; 163 } 164 ColorPolynomial<C> p, q, h, hp; 165 for (ColoredSystem<C> cs : CS) { 166 if (true || debug) { 167 if (!cs.isDetermined()) { 168 System.out.println("not determined, cs = " + cs); 169 return false; 170 } 171 if (!cs.checkInvariant()) { 172 System.out.println("not invariant, cs = " + cs); 173 return false; 174 } 175 } 176 Condition<C> cond = cs.condition; 177 List<ColorPolynomial<C>> S = cs.list; 178 int k = S.size(); 179 for (int j = 0; j < k; j++) { 180 p = S.get(j); 181 for (int l = j + 1; l < k; l++) { 182 q = S.get(l); 183 h = cred.SPolynomial(p, q); 184 // System.out.println("spol(a,b) = " + h); 185 h = cred.normalform(cond, S, h); 186 // System.out.println("NF(spol(a,b)) = " + h); 187 if (true || debug) { 188 if (!cred.isNormalform(S, h)) { 189 System.out.println("not normalform, h = " + h); 190 System.out.println("cs = " + cs); 191 return false; 192 } 193 } 194 if (!h.isZERO()) { 195 hp = cond.reDetermine(h); 196 if (!hp.isZERO()) { 197 System.out.println("p = " + p); 198 System.out.println("q = " + q); 199 System.out.println("not zero: NF(spol(p,q)) = " + h); 200 System.out.println("redetermine(NF(spol(p,q))) = " + hp); 201 System.out.println("cs = " + cs); 202 return false; 203 } 204 } 205 } 206 } 207 } 208 return true; 209 } 210 211 212 /** 213 * Comprehensive-Groebner base test using substitution. 214 * @param F polynomial list. 215 * @return true, if F is a Comprehensive-Groebner base, else false. 216 */ 217 // @Override 218 public boolean isGBsubst(List<GenPolynomial<GenPolynomial<C>>> F) { 219 return isGBsubst(0, F); 220 } 221 222 223 /** 224 * Comprehensive-Groebner base test using substitution. 225 * @param modv module variable number. 226 * @param F polynomial list. 227 * @return true, if F is a Comprehensive-Groebner base, else false. 228 */ 229 // @Override 230 public boolean isGBsubst(int modv, List<GenPolynomial<GenPolynomial<C>>> F) { 231 if (F == null || F.size() == 0) { 232 return true; 233 } 234 GenPolynomial<GenPolynomial<C>> f = F.get(0); // assert non Zero 235 GenPolynomialRing<GenPolynomial<C>> cf = f.ring; 236 237 List<ColoredSystem<C>> CS = cred.determine(F); 238 if (logger.isDebugEnabled()) { 239 logger.info("determined polynomials =\n" + CS); 240 } 241 // substitute zero conditions into parameter coefficients and test 242 for (ColoredSystem<C> cs : CS) { 243 Ideal<C> id = cs.condition.zero; 244 ResidueRing<C> r = new ResidueRing<C>(id); 245 GenPolynomialRing<Residue<C>> rf = new GenPolynomialRing<Residue<C>>(r, cf); 246 List<GenPolynomial<Residue<C>>> list = PolyUtilApp.<C> toResidue(rf, F); 247 //GroebnerBase<Residue<C>> bb = new GroebnerBasePseudoSeq<Residue<C>>(r); 248 GroebnerBase<Residue<C>> bb = GBFactory.getImplementation(r); 249 boolean t = bb.isGB(list); 250 if (!t) { 251 System.out.println("test condition = " + cs.condition); 252 System.out.println("no GB for residue coefficients = " + list); 253 return false; 254 } 255 } 256 257 // substitute random ideal into parameter coefficients and test 258 GenPolynomialRing<C> ccf = (GenPolynomialRing<C>) cf.coFac; 259 int nv = ccf.nvar - 2; 260 if (nv < 1) { 261 nv = 1; 262 } 263 List<GenPolynomial<C>> il = new ArrayList<GenPolynomial<C>>(); 264 int i = 0; 265 int j = 1; 266 while (i < nv) { 267 j++; 268 GenPolynomial<C> p = ccf.random(j + 1); 269 // System.out.println("p = " + p); 270 if (p.isConstant()) { 271 continue; 272 } 273 if (p.isZERO()) { 274 continue; 275 } 276 p = engine.squarefreePart(p); 277 il.add(p); 278 i++; 279 } 280 logger.info("random ideal = " + il); 281 Ideal<C> id = new Ideal<C>(ccf, il); 282 ResidueRing<C> r = new ResidueRing<C>(id); 283 GenPolynomialRing<Residue<C>> rf = new GenPolynomialRing<Residue<C>>(r, cf); 284 List<GenPolynomial<Residue<C>>> list = PolyUtilApp.<C> toResidue(rf, F); 285 logger.info("random residue = " + r.ideal.getList()); 286 //GroebnerBase<Residue<C>> bb = new GroebnerBasePseudoSeq<Residue<C>>(r); 287 GroebnerBase<Residue<C>> bb = GBFactory.getImplementation(r); 288 boolean t = bb.isGB(list); 289 if (!t) { 290 System.out.println("no GB for residue coefficients = " + list); 291 return false; 292 } 293 return true; 294 } 295 296 297 /** 298 * Comprehensive-Groebner system test. 299 * @param F Groebner system. 300 * @return true, if F is a Comprehensive-Groebner system, else false. 301 */ 302 // @Override 303 public boolean isGBsys(GroebnerSystem<C> F) { 304 return isGBsys(0, F.list); 305 } 306 307 308 /** 309 * Comprehensive-Groebner base test. 310 * @param F Groebner system. 311 * @return true, if F is a Comprehensive-Groebner base, else false. 312 */ 313 // @Override 314 public boolean isCGB(GroebnerSystem<C> F) { 315 return isGB(F.getCGB()); 316 } 317 318 319 /** 320 * Comprehensive-Groebner system and base test. 321 * @param F Groebner system. 322 * @return true, if F is a Comprehensive-Groebner system and base, else 323 * false. 324 */ 325 // @Override 326 public boolean isGB(GroebnerSystem<C> F) { 327 return isGBsys(0, F.list) && isGB(F.getCGB()); 328 } 329 330 331 /** 332 * Comprehensive Groebner base system using pairlist class. 333 * @param F polynomial list. 334 * @return GBsys(F) a Comprehensive Groebner system of F. 335 */ 336 // @Override 337 // @SuppressWarnings("unchecked") 338 public GroebnerSystem<C> GBsys(List<GenPolynomial<GenPolynomial<C>>> F) { 339 if (F == null) { 340 return null; 341 } 342 List<ColoredSystem<C>> CSp = new ArrayList<ColoredSystem<C>>(); 343 if (F.size() == 0) { 344 return new GroebnerSystem<C>(CSp); 345 } 346 // extract coefficient factory 347 GenPolynomial<GenPolynomial<C>> f = F.get(0); 348 GenPolynomialRing<GenPolynomial<C>> fac = f.ring; 349 // determine polynomials 350 List<ColoredSystem<C>> CS = cred.determine(F); 351 // System.out.println("CS = " + CS); 352 // CS.remove(0); // empty colored system 353 if (logger.isInfoEnabled()) { 354 logger.info("determined polynomials =\n" + CS); 355 } 356 357 // setup pair lists 358 List<ColoredSystem<C>> CSs = new ArrayList<ColoredSystem<C>>(); 359 ColoredSystem<C> css; 360 for (ColoredSystem<C> cs : CS) { 361 OrderedCPairlist<C> pairlist = new OrderedCPairlist<C>(fac); 362 for (ColorPolynomial<C> p : cs.list) { 363 // System.out.println("p = " + p); 364 pairlist.put(p); 365 } 366 css = new ColoredSystem<C>(cs.condition, cs.list, pairlist); 367 CSs.add(css); 368 } 369 370 // main loop 371 List<ColoredSystem<C>> CSb = new ArrayList<ColoredSystem<C>>(); 372 List<ColoredSystem<C>> ncs; 373 List<ColoredSystem<C>> CSh, CSbh; 374 ColoredSystem<C> cs; 375 List<ColorPolynomial<C>> G; 376 OrderedCPairlist<C> pairlist; 377 Condition<C> cond; 378 int si = 0; 379 while (CSs.size() > 0) { 380 cs = CSs.get(0); // remove(0); 381 si++; 382 logger.info("poped GBsys number " + si + " with condition = " + cs.condition); 383 logger.info("poped GBsys (remaining " + (CSs.size() - 1) + ") with pairlist = " + cs.pairlist); 384 if (!cs.isDetermined()) { 385 cs = cs.reDetermine(); 386 } 387 pairlist = cs.pairlist; 388 G = cs.list; 389 cond = cs.condition; 390 // logger.info( pairlist.toString() ); 391 392 CPair<C> pair; 393 ColorPolynomial<C> pi; 394 ColorPolynomial<C> pj; 395 ColorPolynomial<C> S; 396 // GenPolynomial<GenPolynomial<C>> H; 397 ColorPolynomial<C> H; 398 while (pairlist.hasNext()) { 399 pair = pairlist.removeNext(); 400 if (pair == null) 401 continue; 402 403 pi = pair.pi; 404 pj = pair.pj; 405 if (debug) { 406 logger.info("pi = " + pi); 407 logger.info("pj = " + pj); 408 } 409 410 S = cred.SPolynomial(pi, pj); 411 if (S.isZERO()) { 412 pair.setZero(); 413 continue; 414 } 415 if (debug) { 416 // logger.info("ht(S) = " + S.leadingExpVector() ); 417 logger.info("S = " + S); 418 } 419 420 H = cred.normalform(cond, G, S); 421 if (H.isZERO()) { 422 pair.setZero(); 423 continue; 424 } 425 if (debug) { 426 logger.info("ht(H) = " + H.leadingExpVector()); 427 } 428 429 H = H.abs(); 430 if (debug) { 431 logger.debug("H = " + H); 432 } 433 logger.info("H = " + H); 434 if (!H.isZERO()) { 435 CSh = new ArrayList<ColoredSystem<C>>(); 436 ncs = determineAddPairs(cs, H); 437 if (ncs == null || ncs.size() == 0) { 438 continue; 439 } 440 cs = ncs.remove(0); // remove other? 441 pairlist = cs.pairlist; 442 G = cs.list; 443 cond = cs.condition; 444 logger.info("replaced main branch = " + cond); 445 logger.info("#new systems = " + ncs.size()); 446 int yi = CSs.size(); 447 for (ColoredSystem<C> x : ncs) { 448 if (!x.isDetermined()) { 449 x = x.reDetermine(); 450 } 451 CSs = x.addToList(CSs); 452 } 453 logger.info("#new systems added = " + (CSs.size() - yi)); 454 } 455 } 456 // all s-pols reduce to zero in this branch 457 if (!cs.isDetermined()) { 458 cs = cs.reDetermine(); 459 } 460 CSb.add(cs); 461 CSs.remove(0); 462 logger.info("done with = " + cs.condition); 463 } 464 // all branches done 465 CSh = new ArrayList<ColoredSystem<C>>(); 466 for (ColoredSystem<C> x : CSb) { 467 // System.out.println("G = " + x.list ); 468 if (!x.isDetermined()) { 469 x = x.reDetermine(); 470 } 471 cs = minimalGB(x); 472 // System.out.println("min(G) = " + cs.list ); 473 if (!cs.isDetermined()) { 474 cs = cs.reDetermine(); 475 } 476 // cs = new ColoredSystem<C>( x.condition, G, x.pairlist ); 477 CSh.add(cs); 478 logger.info("#sequential done = " + x.condition); 479 logger.info(x.pairlist.toString()); 480 } 481 CSb = new ArrayList<ColoredSystem<C>>(CSh); 482 return new GroebnerSystem<C>(CSb); 483 } 484 485 486 /** 487 * Determine polynomial relative to a condition of a colored system and add 488 * pairs. 489 * @param cs a colored system. 490 * @param A color polynomial. 491 * @return list of colored systems, the conditions extending the condition 492 * of cs. 493 */ 494 public List<ColoredSystem<C>> determineAddPairs(ColoredSystem<C> cs, ColorPolynomial<C> A) { 495 List<ColoredSystem<C>> NCS = new ArrayList<ColoredSystem<C>>(); 496 if (A == null || A.isZERO()) { 497 // NCS.add( cs ); 498 return NCS; 499 } 500 List<ColorPolynomial<C>> S = cs.list; 501 Condition<C> cond = cs.condition; // .clone(); done in Condition 502 // itself 503 OrderedCPairlist<C> pl = cs.pairlist; 504 505 List<ColorPolynomial<C>> Sp; 506 ColorPolynomial<C> nz; 507 ColoredSystem<C> NS; 508 // if ( A.isDetermined() ) { ... } // dont use this 509 // System.out.println("to determine = " + A); 510 GenPolynomial<GenPolynomial<C>> Ap = A.getPolynomial(); 511 List<Condition<C>> cd = cred.caseDistinction(cond, Ap); 512 logger.info("# cases = " + cd.size()); 513 for (Condition<C> cnd : cd) { 514 //nz = cnd.determine(Ap); 515 nz = cnd.reDetermine(A); 516 if (nz == null || nz.isZERO()) { 517 logger.info("zero determined nz = " + nz); 518 Sp = new ArrayList<ColorPolynomial<C>>(S); 519 OrderedCPairlist<C> PL = pl.clone(); 520 NS = new ColoredSystem<C>(cnd, Sp, PL); 521 try { 522 if (!NS.isDetermined()) { 523 NS = NS.reDetermine(); 524 } 525 } catch (RuntimeException e) { 526 System.out.println("Contradiction in NS_0 = " + NS); 527 //e.printStackTrace(); 528 continue; 529 } 530 NCS = NS.addToList(NCS); 531 continue; 532 } 533 if (S.contains(nz)) { 534 System.out.println("*** S.contains(nz) ***"); 535 continue; 536 } 537 logger.info("new determined nz = " + nz); 538 Sp = new ArrayList<ColorPolynomial<C>>(S); 539 Sp.add(nz); 540 OrderedCPairlist<C> PL = pl.clone(); 541 PL.put(nz); 542 NS = new ColoredSystem<C>(cnd, Sp, PL); 543 try { 544 if (!NS.isDetermined()) { 545 NS = NS.reDetermine(); 546 } 547 } catch (RuntimeException e) { 548 System.out.println("Contradiction in NS = " + NS); 549 //e.printStackTrace(); 550 continue; 551 } 552 NCS = NS.addToList(NCS); 553 } 554 // System.out.println("new determination = " + NCS); 555 return NCS; 556 } 557 558 559 /** 560 * Comprehensive Groebner base via Groebner system. 561 * @param F polynomial list. 562 * @return GB(F) a Comprehensive Groebner base of F. 563 */ 564 // @Override 565 // @SuppressWarnings("unchecked") 566 public List<GenPolynomial<GenPolynomial<C>>> GB(List<GenPolynomial<GenPolynomial<C>>> F) { 567 if (F == null) { 568 return F; 569 } 570 // compute Groebner system 571 GroebnerSystem<C> gs = GBsys(F); 572 // System.out.println("\n\nGBsys = " + gs); 573 return gs.getCGB(); 574 } 575 576 577 /** 578 * Minimal ordered Groebner basis. 579 * @param cs colored system. 580 * @return a reduced Groebner base of Gp. 581 */ 582 // @Override 583 public ColoredSystem<C> minimalGB(ColoredSystem<C> cs) { 584 // List<ColorPolynomial<C>> Gp ) { 585 if (cs == null || cs.list == null || cs.list.size() <= 1) { 586 return cs; 587 } 588 // remove zero polynomials 589 List<ColorPolynomial<C>> G = new ArrayList<ColorPolynomial<C>>(cs.list.size()); 590 for (ColorPolynomial<C> a : cs.list) { 591 if (a != null && !a.isZERO()) { // always true in GB() 592 // already positive a = a.abs(); 593 G.add(a); 594 } 595 } 596 if (G.size() <= 1) { 597 return new ColoredSystem<C>(cs.condition, G, cs.pairlist); 598 } 599 // System.out.println("G check " + G); 600 // remove top reducible polynomials 601 Condition<C> cond = cs.condition; 602 ColorPolynomial<C> a, b; 603 List<ColorPolynomial<C>> F; 604 F = new ArrayList<ColorPolynomial<C>>(G.size()); 605 while (G.size() > 0) { 606 a = G.remove(0); 607 b = a; 608 // System.out.println("check " + b); 609 if (false) { 610 if (a.red.leadingBaseCoefficient().isConstant()) { // dont drop 611 // these 612 F.add(a); 613 continue; 614 } 615 } 616 if (cred.isTopReducible(G, a) || cred.isTopReducible(F, a)) { 617 // drop polynomial 618 if (false) { 619 // System.out.println("trying to drop " + a); 620 List<ColorPolynomial<C>> ff; 621 ff = new ArrayList<ColorPolynomial<C>>(G); 622 ff.addAll(F); 623 a = cred.normalform(cond, ff, a); 624 try { 625 a = cond.reDetermine(a); 626 } catch (RuntimeException ignored) { 627 } 628 if (!a.isZERO()) { 629 if (false || debug) { 630 System.out.println("error, nf(a) != 0 " + b + ", " + a); 631 } 632 F.add(b); 633 } 634 } 635 } else { 636 F.add(a); 637 } 638 } 639 G = F; 640 if (G.size() <= 1) { 641 return new ColoredSystem<C>(cs.condition, G, cs.pairlist); 642 } 643 Collections.reverse(G); // important for lex GB 644 // reduce remaining polynomials 645 int len = G.size(); 646 int i = 0; 647 while (i < len) { 648 a = G.remove(0); 649 b = a; 650 ExpVector e = a.red.leadingExpVector(); 651 // System.out.println("reducing " + a); 652 a = cred.normalform(cond, G, a); // unchanged by top reduction 653 // System.out.println("reduced " + a); 654 try { 655 a = cond.reDetermine(a); 656 } catch (RuntimeException ignored) { 657 } 658 ExpVector f = a.red.leadingExpVector(); 659 // a = ##engine.basePrimitivePart(a); //a.monic(); was not required 660 // a = a.abs(); 661 // a = red.normalform( F, a ); 662 if (e.equals(f)) { 663 G.add(a); // adds as last 664 } else { // should not happen 665 if (false) { 666 System.out.println("error, nf(a) not determined " + b + ", " + a); 667 } 668 G.add(b); // adds as last 669 } 670 i++; 671 } 672 return new ColoredSystem<C>(cs.condition, G, cs.pairlist); 673 } 674 675 }