001/* 002 * $Id$ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.ArrayList; 009import java.util.List; 010import java.util.ListIterator; 011 012import org.apache.logging.log4j.Logger; 013import org.apache.logging.log4j.LogManager; 014 015import edu.jas.poly.ExpVector; 016import edu.jas.poly.GenPolynomial; 017import edu.jas.poly.GenSolvablePolynomial; 018import edu.jas.poly.GenSolvablePolynomialRing; 019import edu.jas.poly.QLRSolvablePolynomialRing; 020import edu.jas.poly.PolyUtil; 021import edu.jas.poly.PolynomialList; 022import edu.jas.structure.RingElem; 023 024 025/** 026 * Solvable Groebner bases sequential algorithms. Implements common left, right 027 * and twosided Groebner bases and left, right and twosided GB tests. 028 * @param <C> coefficient type 029 * @author Heinz Kredel 030 */ 031 032public class SolvableGroebnerBaseSeq<C extends RingElem<C>> extends SolvableGroebnerBaseAbstract<C> { 033 034 035 private static final Logger logger = LogManager.getLogger(SolvableGroebnerBaseSeq.class); 036 037 038 private static final boolean debug = logger.isDebugEnabled(); 039 040 041 /** 042 * Constructor. 043 */ 044 public SolvableGroebnerBaseSeq() { 045 super(); 046 } 047 048 049 /** 050 * Constructor. 051 * @param sred Solvable reduction engine 052 */ 053 public SolvableGroebnerBaseSeq(SolvableReduction<C> sred) { 054 super(sred); 055 } 056 057 058 /** 059 * Constructor. 060 * @param pl pair selection strategy 061 */ 062 public SolvableGroebnerBaseSeq(PairList<C> pl) { 063 super(pl); 064 } 065 066 067 /** 068 * Constructor. 069 * @param sred Solvable reduction engine 070 * @param pl pair selection strategy 071 */ 072 public SolvableGroebnerBaseSeq(SolvableReduction<C> sred, PairList<C> pl) { 073 super(sred, pl); 074 } 075 076 077 /** 078 * Left Groebner base using pairlist class. 079 * @param modv number of module variables. 080 * @param F solvable polynomial list. 081 * @return leftGB(F) a left Groebner base of F. 082 */ 083 @SuppressWarnings("unchecked") 084 public List<GenSolvablePolynomial<C>> leftGB(int modv, List<GenSolvablePolynomial<C>> F) { 085 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(F); 086 G = PolynomialList.castToSolvableList(PolyUtil.<C> monic(PolynomialList.castToList(G))); 087 if (G.size() <= 1) { 088 return G; 089 } 090 GenSolvablePolynomialRing<C> ring = G.get(0).ring; 091 if (!ring.coFac.isField() && ring.coFac.isCommutative()) { 092 throw new IllegalArgumentException("coefficients not from a field: " + ring.coFac.toScript()); 093 } 094 PairList<C> pairlist = strategy.create(modv, ring); 095 pairlist.put(PolynomialList.castToList(G)); 096 logger.info("start {}", pairlist); 097 098 GenSolvablePolynomial<C> pi, pj, S, H; 099 Pair<C> pair; 100 while (pairlist.hasNext()) { 101 pair = pairlist.removeNext(); 102 if (pair == null) { 103 continue; 104 } 105 pi = (GenSolvablePolynomial<C>) pair.pi; 106 pj = (GenSolvablePolynomial<C>) pair.pj; 107 if (debug) { 108 logger.info("pi = {}", pi.leadingExpVector()); 109 logger.info("pj = {}", pj.leadingExpVector()); 110 } 111 112 S = sred.leftSPolynomial(pi, pj); 113 if (S.isZERO()) { 114 pair.setZero(); 115 continue; 116 } 117 if (debug) { 118 logger.info("ht(S) = {}", S.leadingExpVector()); 119 } 120 121 H = sred.leftNormalform(G, S); 122 if (H.isZERO()) { 123 pair.setZero(); 124 continue; 125 } 126 if (debug) { 127 logger.info("ht(H) = {}", H.leadingExpVector()); 128 //logger.info("ht(H) = {}, lc(H) = {}", H.leadingExpVector(), H.leadingBaseCoefficient().toScript()); 129 } 130 131 H = H.monic(); 132 if (H.isONE()) { 133 G.clear(); 134 G.add(H); 135 return G; // since no threads are activated 136 } 137 if (debug) { 138 // logger.info("H = {}", H); 139 logger.info("#monic(H) = {}", H.length()); 140 } 141 if (H.length() > 0) { 142 //l++; 143 G.add(H); 144 pairlist.put(H); 145 } 146 } 147 logger.debug("#sequential list = {}", G.size()); 148 G = leftMinimalGB(G); 149 logger.info("end {}", pairlist); 150 return G; 151 } 152 153 154 /** 155 * Solvable Extended Groebner base using critical pair class. 156 * @param modv module variable number. 157 * @param F solvable polynomial list. 158 * @return a container for an extended left Groebner base of F. 159 */ 160 @Override 161 @SuppressWarnings("unchecked") 162 public SolvableExtendedGB<C> extLeftGB(int modv, List<GenSolvablePolynomial<C>> F) { 163 if (F == null || F.isEmpty()) { 164 throw new IllegalArgumentException("null or empty F not allowed"); 165 } 166 List<GenSolvablePolynomial<C>> G = new ArrayList<GenSolvablePolynomial<C>>(); 167 List<List<GenSolvablePolynomial<C>>> F2G = new ArrayList<List<GenSolvablePolynomial<C>>>(); 168 List<List<GenSolvablePolynomial<C>>> G2F = new ArrayList<List<GenSolvablePolynomial<C>>>(); 169 PairList<C> pairlist = null; 170 boolean oneInGB = false; 171 int len = F.size(); 172 173 List<GenSolvablePolynomial<C>> row = null; 174 List<GenSolvablePolynomial<C>> rows = null; 175 List<GenSolvablePolynomial<C>> rowh = null; 176 GenSolvablePolynomialRing<C> ring = null; 177 GenSolvablePolynomial<C> p, H; 178 179 int nzlen = 0; 180 for (GenSolvablePolynomial<C> f : F) { 181 if (f.length() > 0) { 182 nzlen++; 183 } 184 if (ring == null) { 185 ring = f.ring; 186 } 187 } 188 GenSolvablePolynomial<C> mone = ring.getONE(); //.negate(); 189 int k = 0; 190 ListIterator<GenSolvablePolynomial<C>> it = F.listIterator(); 191 while (it.hasNext()) { 192 p = it.next(); 193 if (p.length() > 0) { 194 row = PolynomialList.<C> castToSolvableList( blas.genVector(nzlen, null) ); 195 //C c = p.leadingBaseCoefficient(); 196 //c = c.inverse(); 197 //p = p.multiply( c ); 198 row.set(k, mone); //.multiply(c) ); 199 k++; 200 if (p.isUnit()) { 201 G.clear(); 202 G.add(p); 203 G2F.clear(); 204 G2F.add(row); 205 oneInGB = true; 206 break; 207 } 208 G.add(p); 209 G2F.add(row); 210 if (pairlist == null) { 211 //pairlist = new CriticalPairList<C>( modv, p.ring ); 212 pairlist = strategy.create(modv, p.ring); 213 } 214 // putOne not required 215 pairlist.put(p); 216 } else { 217 len--; 218 } 219 } 220 SolvableExtendedGB<C> exgb; 221 if (len <= 1 || oneInGB) { 222 // adjust F2G 223 for (GenSolvablePolynomial<C> f : F) { 224 row = PolynomialList.<C> castToSolvableList( blas.genVector(G.size(), null) ); 225 H = sred.leftNormalform(row, G, f); 226 if (!H.isZERO()) { 227 logger.error("nonzero H = {}", H); 228 } 229 F2G.add(row); 230 } 231 exgb = new SolvableExtendedGB<C>(F, G, F2G, G2F); 232 //System.out.println("exgb 1 = " + exgb); 233 return exgb; 234 } 235 logger.info("start {}", pairlist); 236 237 Pair<C> pair; 238 int i, j; 239 GenSolvablePolynomial<C> pi, pj, S, x, y; 240 //GenPolynomial<C> z; 241 while (pairlist.hasNext() && !oneInGB) { 242 pair = pairlist.removeNext(); 243 if (pair == null) { 244 //pairlist.update(); // ? 245 continue; 246 } 247 i = pair.i; 248 j = pair.j; 249 pi = (GenSolvablePolynomial<C>) pair.pi; 250 pj = (GenSolvablePolynomial<C>) pair.pj; 251 if (debug) { 252 logger.info("i, pi = {}, {}", i, pi); 253 logger.info("j, pj = {}, {}", j, pj); 254 } 255 256 rows = PolynomialList.<C> castToSolvableList( blas.genVector(G.size(), null) ); 257 S = sred.leftSPolynomial(rows, i, pi, j, pj); 258 if (debug) { 259 logger.debug("is reduction S = {}", sred.isLeftReductionNF(rows, G, ring.getZERO(), S)); 260 } 261 if (S.isZERO()) { 262 pair.setZero(); 263 //pairlist.update( pair, S ); 264 // do not add to G2F 265 continue; 266 } 267 if (debug) { 268 logger.debug("ht(S) = {}", S.leadingExpVector()); 269 } 270 271 rowh = PolynomialList.<C> castToSolvableList( blas.genVector(G.size(), null) ); 272 H = sred.leftNormalform(rowh, G, S); 273 if (debug) { 274 //System.out.println("H = " + H); 275 logger.debug("is reduction H = {}", sred.isLeftReductionNF(rowh, G, S, H)); 276 } 277 if (H.isZERO()) { 278 pair.setZero(); 279 //pairlist.update( pair, H ); 280 // do not add to G2F 281 continue; 282 } 283 if (debug) { 284 logger.debug("ht(H) = {}", H.leadingExpVector()); 285 } 286 287 row = PolynomialList.<C>castToSolvableList(blas.vectorCombineOld(PolynomialList.<C>castToList(rows),PolynomialList.<C>castToList(rowh))); 288 // if (debug) { 289 // logger.debug("is reduction 0+sum(row,G) == H : " 290 // + sred.isLeftReductionNF(row, G, H, ring.getZERO())); 291 // } 292 293 // H = H.monic(); 294 C c = H.leadingBaseCoefficient(); 295 c = c.inverse(); 296 H = H.multiply(c); 297 // 1*c*row, leads to wrong method dispatch: 298 row = PolynomialList.<C> castToSolvableList(blas.scalarProduct(mone.multiply(c), 299 PolynomialList.<C> castToList(row))); 300 row.set(G.size(), mone); 301 if (H.isONE()) { 302 // pairlist.record( pair, H ); 303 // G.clear(); 304 G.add(H); 305 G2F.add(row); 306 oneInGB = true; 307 break; 308 } 309 if (debug) { 310 logger.debug("H = {}", H); 311 } 312 G.add(H); 313 //pairlist.update( pair, H ); 314 pairlist.put(H); 315 G2F.add(row); 316 } 317 if (debug) { 318 exgb = new SolvableExtendedGB<C>(F, G, F2G, G2F); 319 logger.info("exgb unnorm = {}", exgb); 320 } 321 G2F = normalizeMatrix(F.size(), G2F); 322 if (debug) { 323 exgb = new SolvableExtendedGB<C>(F, G, F2G, G2F); 324 logger.info("exgb nonmin = {}", exgb); 325 boolean t2 = isLeftReductionMatrix(exgb); 326 logger.debug("exgb t2 = {}", t2); 327 } 328 exgb = minimalSolvableExtendedGB(F.size(), G, G2F); 329 G = exgb.G; 330 G2F = exgb.G2F; 331 logger.debug("#sequential list = {}", G.size()); 332 logger.info("end {}", pairlist); 333 // setup matrices F and F2G 334 for (GenSolvablePolynomial<C> f : F) { 335 row = PolynomialList.<C> castToSolvableList( blas.genVector(G.size(), null) ); 336 H = sred.leftNormalform(row, G, f); 337 if (!H.isZERO()) { 338 logger.error("nonzero H = {}", H); 339 } 340 F2G.add(row); 341 } 342 logger.info("extLeftGB end"); 343 return new SolvableExtendedGB<C>(F, G, F2G, G2F); 344 } 345 346 347 /** 348 * Twosided Groebner base using pairlist class. 349 * @param modv number of module variables. 350 * @param Fp solvable polynomial list. 351 * @return tsGB(Fp) a twosided Groebner base of Fp. 352 */ 353 @SuppressWarnings("unchecked") 354 public List<GenSolvablePolynomial<C>> twosidedGB(int modv, List<GenSolvablePolynomial<C>> Fp) { 355 List<GenSolvablePolynomial<C>> F = normalizeZerosOnes(Fp); 356 F = PolynomialList.castToSolvableList(PolyUtil.<C> monic(PolynomialList.castToList(F))); 357 if (F.size() < 1) { // 0 not 1 358 return F; 359 } 360 if (F.size() == 1 && F.get(0).isONE()) { 361 return F; 362 } 363 GenSolvablePolynomialRing<C> ring = F.get(0).ring; 364 if (!ring.coFac.isField() && ring.coFac.isCommutative()) { 365 throw new IllegalArgumentException("coefficients not from a field"); 366 } 367 // add also coefficient generators 368 List<GenSolvablePolynomial<C>> X; 369 X = PolynomialList.castToSolvableList(ring.generators(modv)); 370 logger.info("right multipliers = {}", X); 371 List<GenSolvablePolynomial<C>> G = new ArrayList<GenSolvablePolynomial<C>>(F.size() * (1 + X.size())); 372 G.addAll(F); 373 logger.info("right multiply: G = {}", G); 374 GenSolvablePolynomial<C> p, q; 375 for (int i = 0; i < G.size(); i++) { // G changes 376 p = G.get(i); 377 for (GenSolvablePolynomial<C> x : X) { 378 //x = X.get(j); 379 if (x.isONE()) { 380 continue; 381 } 382 q = p.multiply(x); 383 logger.info("right multiply: p = {}, x = {}, q = {}", p, x, q); 384 q = sred.leftNormalform(G, q); 385 q = q.monic(); 386 logger.info("right multiply: red(q) = {}", q); 387 if (!q.isZERO()) { 388 //System.out.println("q generating: = " + q + ", p = " + p + ", x = " + x); 389 if (q.isONE()) { 390 //System.out.println("G generated so far: " + G); 391 G.clear(); 392 G.add(q); 393 return G; // since no threads are activated 394 } 395 if (!G.contains(q)) { // why? 396 G.add(q); 397 } else { 398 logger.info("right multiply contained: q = {}", q); 399 } 400 } 401 } 402 } 403 if (G.size() <= 1) { // 1 ok 404 return G; // since no threads are activated 405 } 406 //System.out.println("G generated = " + G); 407 PairList<C> pairlist = strategy.create(modv, ring); 408 pairlist.put(PolynomialList.castToList(G)); 409 logger.info("twosided start {}", pairlist); 410 411 Pair<C> pair; 412 GenSolvablePolynomial<C> pi, pj, S, H; 413 while (pairlist.hasNext()) { 414 pair = pairlist.removeNext(); 415 if (pair == null) { 416 continue; 417 } 418 419 pi = (GenSolvablePolynomial<C>) pair.pi; 420 pj = (GenSolvablePolynomial<C>) pair.pj; 421 if (debug) { 422 logger.debug("pi = {}", pi); 423 logger.debug("pj = {}", pj); 424 } 425 426 S = sred.leftSPolynomial(pi, pj); 427 if (S.isZERO()) { 428 pair.setZero(); 429 continue; 430 } 431 if (debug) { 432 logger.debug("ht(S) = {}", S.leadingExpVector()); 433 } 434 435 H = sred.leftNormalform(G, S); 436 if (H.isZERO()) { 437 pair.setZero(); 438 continue; 439 } 440 if (debug) { 441 logger.debug("ht(H) = {}", H.leadingExpVector()); 442 } 443 444 H = H.monic(); 445 if (H.isONE()) { 446 G.clear(); 447 G.add(H); 448 return G; // since no threads are activated 449 } 450 if (debug) { 451 logger.debug("H = {}", H); 452 } 453 if (H.length() > 0) { 454 G.add(H); 455 pairlist.put(H); 456 //System.out.println("H generated = " + H); 457 for (GenSolvablePolynomial<C> x : X) { 458 //x = X.get(j); 459 if (x.isONE()) { 460 continue; 461 } 462 q = H.multiply(x); 463 p = sred.leftNormalform(G, q); 464 if (!p.isZERO()) { 465 //System.out.println("p generated = " + p + ", x = " + x); 466 p = p.monic(); 467 if (p.isONE()) { 468 G.clear(); 469 G.add(p); 470 return G; // since no threads are activated 471 } 472 G.add(p); 473 pairlist.put(p); 474 } 475 } 476 //System.out.println("G generated = " + G); 477 } 478 } 479 logger.debug("#sequential list = {}", G.size()); 480 G = leftMinimalGB(G); 481 logger.info("twosided end {}", pairlist); 482 return G; 483 } 484 485 486 /** 487 * Normalize M. Make all rows the same size and make certain column elements 488 * zero. 489 * @param M a reduction matrix. 490 * @return normalized M. 491 */ 492 public List<List<GenSolvablePolynomial<C>>> normalizeMatrix(int flen, 493 List<List<GenSolvablePolynomial<C>>> M) { 494 if (M == null) { 495 return M; 496 } 497 if (M.size() == 0) { 498 return M; 499 } 500 List<List<GenSolvablePolynomial<C>>> N = new ArrayList<List<GenSolvablePolynomial<C>>>(); 501 List<List<GenSolvablePolynomial<C>>> K = new ArrayList<List<GenSolvablePolynomial<C>>>(); 502 int len = M.get(M.size() - 1).size(); // longest row 503 // pad / extend rows 504 for (List<GenSolvablePolynomial<C>> row : M) { 505 List<GenSolvablePolynomial<C>> nrow = new ArrayList<GenSolvablePolynomial<C>>(row); 506 for (int i = row.size(); i < len; i++) { 507 nrow.add(null); 508 } 509 N.add(nrow); 510 } 511 // System.out.println("norm N fill = " + N); 512 // make zero columns 513 int k = flen; 514 for (int i = 0; i < N.size(); i++) { // 0 515 List<GenSolvablePolynomial<C>> row = N.get(i); 516 if (debug) { 517 logger.info("row = {}", row); 518 } 519 K.add(row); 520 if (i < flen) { // skip identity part 521 continue; 522 } 523 List<GenSolvablePolynomial<C>> xrow; 524 GenSolvablePolynomial<C> a; 525 //System.out.println("norm i = " + i); 526 for (int j = i + 1; j < N.size(); j++) { 527 List<GenSolvablePolynomial<C>> nrow = N.get(j); 528 //System.out.println("nrow j = " +j + ", " + nrow); 529 if (k < nrow.size()) { // always true 530 a = nrow.get(k); 531 //System.out.println("k, a = " + k + ", " + a); 532 if (a != null && !a.isZERO()) { // a*row + nrow, leads to wrong method dispatch 533 List<GenPolynomial<C>> yrow = blas.scalarProduct(a, 534 PolynomialList.<C> castToList(row)); 535 yrow = blas.vectorAdd(yrow, PolynomialList.<C> castToList(nrow)); 536 xrow = PolynomialList.<C> castToSolvableList(yrow); 537 N.set(j, xrow); 538 } 539 } 540 } 541 k++; 542 } 543 //System.out.println("norm K reduc = {}", K); 544 // truncate 545 N.clear(); 546 for (List<GenSolvablePolynomial<C>> row : K) { 547 List<GenSolvablePolynomial<C>> tr = new ArrayList<GenSolvablePolynomial<C>>(); 548 for (int i = 0; i < flen; i++) { 549 tr.add(row.get(i)); 550 } 551 N.add(tr); 552 } 553 K = N; 554 //System.out.println("norm K trunc = " + K); 555 return K; 556 } 557 558 559 /** 560 * Test if M is a left reduction matrix. 561 * @param exgb an SolvableExtendedGB container. 562 * @return true, if exgb contains a left reduction matrix, else false. 563 */ 564 @Override 565 public boolean isLeftReductionMatrix(SolvableExtendedGB<C> exgb) { 566 if (exgb == null) { 567 return true; 568 } 569 return isLeftReductionMatrix(exgb.F, exgb.G, exgb.F2G, exgb.G2F); 570 } 571 572 573 /** 574 * Minimal solvable extended groebner basis. 575 * @param Gp a left Groebner base. 576 * @param M a left reduction matrix, is modified. 577 * @return a (partially) reduced left Groebner base of Gp in a container. 578 */ 579 public SolvableExtendedGB<C> minimalSolvableExtendedGB(int flen, List<GenSolvablePolynomial<C>> Gp, 580 List<List<GenSolvablePolynomial<C>>> M) { 581 if (Gp == null) { 582 return null; //new SolvableExtendedGB<C>(null,Gp,null,M); 583 } 584 if (Gp.size() <= 1) { 585 return new SolvableExtendedGB<C>(null, Gp, null, M); 586 } 587 List<GenSolvablePolynomial<C>> G; 588 List<GenSolvablePolynomial<C>> F; 589 G = new ArrayList<GenSolvablePolynomial<C>>(Gp); 590 F = new ArrayList<GenSolvablePolynomial<C>>(Gp.size()); 591 592 List<List<GenSolvablePolynomial<C>>> Mg; 593 List<List<GenSolvablePolynomial<C>>> Mf; 594 Mg = new ArrayList<List<GenSolvablePolynomial<C>>>(M.size()); 595 Mf = new ArrayList<List<GenSolvablePolynomial<C>>>(M.size()); 596 List<GenSolvablePolynomial<C>> row; 597 for (List<GenSolvablePolynomial<C>> r : M) { 598 // must be copied also 599 row = new ArrayList<GenSolvablePolynomial<C>>(r); 600 Mg.add(row); 601 } 602 row = null; 603 604 GenSolvablePolynomial<C> a; 605 ExpVector e; 606 ExpVector f; 607 GenSolvablePolynomial<C> p; 608 boolean mt; 609 ListIterator<GenSolvablePolynomial<C>> it; 610 ArrayList<Integer> ix = new ArrayList<Integer>(); 611 ArrayList<Integer> jx = new ArrayList<Integer>(); 612 int k = 0; 613 //System.out.println("flen, Gp, M = " + flen + ", " + Gp.size() + ", " + M.size() ); 614 while (G.size() > 0) { 615 a = G.remove(0); 616 e = a.leadingExpVector(); 617 618 it = G.listIterator(); 619 mt = false; 620 while (it.hasNext() && !mt) { 621 p = it.next(); 622 f = p.leadingExpVector(); 623 mt = e.multipleOf(f); 624 } 625 it = F.listIterator(); 626 while (it.hasNext() && !mt) { 627 p = it.next(); 628 f = p.leadingExpVector(); 629 mt = e.multipleOf(f); 630 } 631 //System.out.println("k, mt = " + k + ", " + mt); 632 if (!mt) { 633 F.add(a); 634 ix.add(k); 635 } else { // drop polynomial and corresponding row and column 636 // F.add( a.ring.getZERO() ); 637 jx.add(k); 638 } 639 k++; 640 } 641 if (debug) { 642 logger.debug("ix, #M, jx = {}, {}, {}", ix, Mg.size(), jx); 643 } 644 int fix = -1; // copied polys 645 // copy Mg to Mf as indicated by ix 646 for (int i = 0; i < ix.size(); i++) { 647 int u = ix.get(i); 648 if (u >= flen && fix == -1) { 649 fix = Mf.size(); 650 } 651 //System.out.println("copy u, fix = " + u + ", " + fix); 652 if (u >= 0) { 653 row = Mg.get(u); 654 Mf.add(row); 655 } 656 } 657 if (F.size() <= 1 || fix == -1) { 658 return new SolvableExtendedGB<C>(null, F, null, Mf); 659 } 660 // must return, since extended normalform has not correct order of polys 661 /* 662 G = F; 663 F = new ArrayList<GenSolvablePolynomial<C>>( G.size() ); 664 List<GenSolvablePolynomial<C>> temp; 665 k = 0; 666 final int len = G.size(); 667 while ( G.size() > 0 ) { 668 a = G.remove(0); 669 if ( k >= fix ) { // dont touch copied polys 670 row = Mf.get( k ); 671 //System.out.println("doing k = " + k + ", " + a); 672 // must keep order, but removed polys missing 673 temp = new ArrayList<GenPolynomial<C>>( len ); 674 temp.addAll( F ); 675 temp.add( a.ring.getZERO() ); // ?? 676 temp.addAll( G ); 677 //System.out.println("row before = " + row); 678 a = sred.leftNormalform( row, temp, a ); 679 //System.out.println("row after = " + row); 680 } 681 F.add( a ); 682 k++; 683 } 684 // does Mf need renormalization? 685 */ 686 return new SolvableExtendedGB<C>(null, F, null, Mf); 687 } 688 689 690 /** 691 * Right Groebner base via right reduction using pairlist 692 * class. Overrides rightGB() via opposite ring. 693 * @param modv number of module variables. 694 * @param F solvable polynomial list. 695 * @return rightGB(F) a right Groebner base of F. 696 */ 697 @Override 698 @SuppressWarnings("unchecked") 699 public List<GenSolvablePolynomial<C>> rightGB(int modv, List<GenSolvablePolynomial<C>> F) { 700 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(F); 701 G = PolynomialList.castToSolvableList(PolyUtil.<C> monic(PolynomialList.castToList(G))); 702 if (G.size() <= 1) { 703 return G; 704 } 705 GenSolvablePolynomialRing<C> ring = G.get(0).ring; 706 if (!ring.coFac.isField() && ring.coFac.isCommutative()) { 707 throw new IllegalArgumentException("coefficients not from a field"); 708 } 709 PairList<C> pairlist = strategy.create(modv, ring); 710 pairlist.put(PolynomialList.castToList(G)); 711 logger.info("start {}", pairlist); 712 713 GenSolvablePolynomial<C> pi, pj, S, H; 714 Pair<C> pair; 715 while (pairlist.hasNext()) { 716 pair = pairlist.removeNext(); 717 if (pair == null) { 718 continue; 719 } 720 pi = (GenSolvablePolynomial<C>) pair.pi; 721 pj = (GenSolvablePolynomial<C>) pair.pj; 722 if (debug) { 723 logger.info("pi = {}", pi); 724 logger.info("pj = {}", pj); 725 } 726 727 S = sred.rightSPolynomial(pi, pj); 728 if (S.isZERO()) { 729 pair.setZero(); 730 continue; 731 } 732 if (debug) { 733 logger.info("ht(S) = {}", S.leadingExpVector()); 734 } 735 736 H = sred.rightNormalform(G, S); 737 if (H.isZERO()) { 738 pair.setZero(); 739 continue; 740 } 741 if (debug) { 742 logger.info("ht(H) = {}", H.leadingExpVector()); 743 } 744 745 H = H.monic(); 746 if (H.isONE()) { 747 G.clear(); 748 G.add(H); 749 return G; // since no threads are activated 750 } 751 if (debug) { 752 logger.info("H = {}", H); 753 } 754 if (H.length() > 0) { 755 //l++; 756 G.add(H); 757 pairlist.put(H); 758 } 759 } 760 logger.debug("#sequential list = {}", G.size()); 761 G = rightMinimalGB(G); 762 logger.info("end {}", pairlist); 763 return G; 764 } 765 766}