001/* 002 * $Id: GroebnerBaseAbstract.java 4289 2012-11-04 14:29:36Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007import java.util.ArrayList; 008import java.util.List; 009import java.util.Map; 010import java.util.TreeMap; 011import java.util.ListIterator; 012import java.util.Set; 013import java.util.HashSet; 014import java.util.Collections; 015 016import org.apache.log4j.Logger; 017 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.TermOrder; 021import edu.jas.poly.PolyUtil; 022import edu.jas.poly.PolynomialList; 023import edu.jas.structure.RingElem; 024import edu.jas.structure.RingFactory; 025import edu.jas.poly.ExpVector; 026import edu.jas.vector.BasicLinAlg; 027 028 029/** 030 * Groebner Bases abstract class. 031 * Implements common Groebner bases and GB test methods. 032 * @param <C> coefficient type 033 * @author Heinz Kredel 034 * 035 * @see edu.jas.application.GBAlgorithmBuilder 036 * @see edu.jas.gbufd.GBFactory 037 */ 038 039public abstract class GroebnerBaseAbstract<C extends RingElem<C>> 040 implements GroebnerBase<C> { 041 042 private static final Logger logger = Logger.getLogger(GroebnerBaseAbstract.class); 043 private final boolean debug = logger.isDebugEnabled(); 044 045 046 /** 047 * Reduction engine. 048 */ 049 public final Reduction<C> red; 050 051 052 /** 053 * Strategy for pair selection. 054 */ 055 public final PairList<C> strategy; 056 057 058 /** 059 * linear algebra engine. 060 */ 061 public final BasicLinAlg<GenPolynomial<C>> blas; 062 063 064 /** 065 * Constructor. 066 */ 067 public GroebnerBaseAbstract() { 068 this( new ReductionSeq<C>() ); 069 } 070 071 072 /** 073 * Constructor. 074 * @param red Reduction engine 075 */ 076 public GroebnerBaseAbstract(Reduction<C> red) { 077 this(red, new OrderedPairlist<C>() ); 078 } 079 080 081 /** 082 * Constructor. 083 * @param red Reduction engine 084 * @param pl pair selection strategy 085 */ 086 public GroebnerBaseAbstract(Reduction<C> red, PairList<C> pl) { 087 this.red = red; 088 this.strategy = pl; 089 blas = new BasicLinAlg<GenPolynomial<C>>(); 090 } 091 092 093 /** 094 * Get the String representation with GB engines. 095 * @see java.lang.Object#toString() 096 */ 097 @Override 098 public String toString() { 099 return this.getClass().getSimpleName(); 100 } 101 102 103 /** 104 * Groebner base test. 105 * @param F polynomial list. 106 * @return true, if F is a Groebner base, else false. 107 */ 108 public boolean isGB(List<GenPolynomial<C>> F) { 109 return isGB(0,F); 110 } 111 112 113 /** 114 * Groebner base test. 115 * @param modv module variable number. 116 * @param F polynomial list. 117 * @return true, if F is a Groebner base, else false. 118 */ 119 public boolean isGB(int modv, List<GenPolynomial<C>> F) { 120 return isGB(modv,F,true); 121 } 122 123 124 /** 125 * Groebner base test. 126 * @param F polynomial list. 127 * @param b true for simple test, false for GB test. 128 * @return true, if F is a Groebner base, else false. 129 */ 130 public boolean isGB(List<GenPolynomial<C>> F, boolean b) { 131 return isGB(0,F,b); 132 } 133 134 135 /** 136 * Groebner base test. 137 * @param modv module variable number. 138 * @param F polynomial list. 139 * @param b true for simple test, false for GB test. 140 * @return true, if F is a Groebner base, else false. 141 */ 142 public boolean isGB(int modv, List<GenPolynomial<C>> F, boolean b) { 143 if ( b ) { 144 return isGBsimple(modv,F); 145 } 146 return isGBidem(modv,F); 147 } 148 149 150 /** 151 * Groebner base simple test. 152 * @param modv module variable number. 153 * @param F polynomial list. 154 * @return true, if F is a Groebner base, else false. 155 */ 156 public boolean isGBsimple(int modv, List<GenPolynomial<C>> F) { 157 if ( F == null || F.isEmpty() ) { 158 return true; 159 } 160 GenPolynomial<C> pi, pj, s, h; 161 ExpVector ei, ej, eij; 162 for ( int i = 0; i < F.size(); i++ ) { 163 pi = F.get(i); 164 ei = pi.leadingExpVector(); 165 for ( int j = i+1; j < F.size(); j++ ) { 166 pj = F.get(j); 167 ej = pj.leadingExpVector(); 168 if ( ! red.moduleCriterion(modv, ei, ej) ) { 169 continue; 170 } 171 eij = ei.lcm(ej); 172 if ( ! red.criterion4(ei, ej, eij) ) { 173 continue; 174 } 175 if ( ! criterion3(i, j, eij, F) ) { 176 continue; 177 } 178 s = red.SPolynomial(pi, pj); 179 if ( s.isZERO() ) { 180 continue; 181 } 182 //System.out.println("i, j = " + i + ", " + j); 183 h = red.normalform( F, s ); 184 if ( ! h.isZERO() ) { 185 logger.info("no GB: pi = " + pi + ", pj = " + pj); 186 logger.info("s = " + s + ", h = " + h); 187 return false; 188 } 189 } 190 } 191 return true; 192 } 193 194 195 /** 196 * GB criterium 3. 197 * @return true if the S-polynomial(i,j) is required. 198 */ 199 boolean criterion3(int i, int j, ExpVector eij, List<GenPolynomial<C>> P) { 200 assert i < j; 201 //for ( int k = 0; k < P.size(); k++ ) { 202 // not of much use 203 for ( int k = 0; k < i; k++ ) { 204 GenPolynomial<C> A = P.get( k ); 205 ExpVector ek = A.leadingExpVector(); 206 if ( eij.multipleOf(ek) ) { 207 return false; 208 } 209 } 210 return true; 211 } 212 213 214 /** 215 * Groebner base idempotence test. 216 * @param modv module variable number. 217 * @param F polynomial list. 218 * @return true, if F is equal to GB(F), else false. 219 */ 220 public boolean isGBidem(int modv, List<GenPolynomial<C>> F) { 221 if ( F == null || F.isEmpty() ) { 222 return true; 223 } 224 GenPolynomialRing<C> pring = F.get(0).ring; 225 List<GenPolynomial<C>> G = GB(modv,F); 226 PolynomialList<C> Fp = new PolynomialList<C>(pring,F); 227 PolynomialList<C> Gp = new PolynomialList<C>(pring,G); 228 return Fp.compareTo(Gp) == 0; 229 } 230 231 232 /** 233 * Common zero test. 234 * @param F polynomial list. 235 * @return -1, 0 or 1 if dimension(ideal(F)) &eq; -1, 0 or ≥ 1. 236 */ 237 public int commonZeroTest(List<GenPolynomial<C>> F) { 238 if (F == null || F.isEmpty()) { 239 return 1; 240 } 241 GenPolynomialRing<C> pfac = F.get(0).ring; 242 if (pfac.nvar <= 0) { 243 return -1; 244 } 245 //int uht = 0; 246 Set<Integer> v = new HashSet<Integer>(); // for non reduced GBs 247 for (GenPolynomial<C> p : F) { 248 if ( p.isZERO() ) { 249 continue; 250 } 251 if ( p.isConstant() ) { // for non-monic lists 252 return -1; 253 } 254 ExpVector e = p.leadingExpVector(); 255 if (e == null) { 256 continue; 257 } 258 int[] u = e.dependencyOnVariables(); 259 if (u == null) { 260 continue; 261 } 262 if (u.length == 1) { 263 //uht++; 264 v.add(u[0]); 265 } 266 } 267 if (pfac.nvar == v.size()) { 268 return 0; 269 } 270 return 1; 271 } 272 273 274 /** 275 * Groebner base using pairlist class. 276 * @param F polynomial list. 277 * @return GB(F) a Groebner base of F. 278 */ 279 public List<GenPolynomial<C>> 280 GB( List<GenPolynomial<C>> F ) { 281 return GB(0,F); 282 } 283 284 285 /** 286 * Extended Groebner base using critical pair class. 287 * @param F polynomial list. 288 * @return a container for a Groebner base G of F together with back-and-forth transformations. 289 */ 290 public ExtendedGB<C> 291 extGB( List<GenPolynomial<C>> F ) { 292 return extGB(0,F); 293 } 294 295 296 /** 297 * Extended Groebner base using critical pair class. 298 * @param modv module variable number. 299 * @param F polynomial list. 300 * @return a container for a Groebner base G of F together with back-and-forth transformations. 301 */ 302 public ExtendedGB<C> 303 extGB( int modv, 304 List<GenPolynomial<C>> F ) { 305 throw new UnsupportedOperationException("extGB not implemented in " 306 + this.getClass().getSimpleName()); 307 } 308 309 310 /** 311 * Minimal ordered Groebner basis. 312 * @param Gp a Groebner base. 313 * @return a reduced Groebner base of Gp. 314 */ 315 public List<GenPolynomial<C>> 316 minimalGB(List<GenPolynomial<C>> Gp) { 317 if ( Gp == null || Gp.size() <= 1 ) { 318 return Gp; 319 } 320 // remove zero polynomials 321 List<GenPolynomial<C>> G 322 = new ArrayList<GenPolynomial<C>>( Gp.size() ); 323 for ( GenPolynomial<C> a : Gp ) { 324 if ( a != null && !a.isZERO() ) { // always true in GB() 325 // already positive a = a.abs(); 326 G.add( a ); 327 } 328 } 329 if ( G.size() <= 1 ) { 330 return G; 331 } 332 // remove top reducible polynomials 333 GenPolynomial<C> a; 334 List<GenPolynomial<C>> F; 335 F = new ArrayList<GenPolynomial<C>>( G.size() ); 336 while ( G.size() > 0 ) { 337 a = G.remove(0); 338 if ( red.isTopReducible(G,a) || red.isTopReducible(F,a) ) { 339 // drop polynomial 340 if ( debug ) { 341 System.out.println("dropped " + a); 342 List<GenPolynomial<C>> ff; 343 ff = new ArrayList<GenPolynomial<C>>( G ); 344 ff.addAll(F); 345 a = red.normalform( ff, a ); 346 if ( !a.isZERO() ) { 347 System.out.println("error, nf(a) " + a); 348 } 349 } 350 } else { 351 F.add(a); 352 } 353 } 354 G = F; 355 if ( G.size() <= 1 ) { 356 return G; 357 } 358 // reduce remaining polynomials 359 Collections.reverse(G); // important for lex GB 360 int len = G.size(); 361 if ( debug ) { 362 System.out.println("#G " + len); 363 for (GenPolynomial<C> aa : G) { 364 System.out.println("aa = " + aa.length() + ", lt = " + aa.getMap().keySet()); 365 } 366 } 367 int i = 0; 368 while ( i < len ) { 369 a = G.remove(0); 370 if ( debug ) { 371 System.out.println("doing " + a.length() + ", lt = " + a.leadingExpVector()); 372 } 373 a = red.normalform( G, a ); 374 G.add( a ); // adds as last 375 i++; 376 } 377 return G; 378 } 379 380 381 /** 382 * Test for minimal ordered Groebner basis. 383 * @param Gp an ideal base. 384 * @return true, if Gp is a reduced minimal Groebner base. 385 */ 386 public boolean isMinimalGB(List<GenPolynomial<C>> Gp) { 387 if ( Gp == null || Gp.size() == 0 ) { 388 return true; 389 } 390 // test for zero polynomials 391 for ( GenPolynomial<C> a : Gp ) { 392 if ( a == null || a.isZERO() ) { 393 if (debug) { 394 logger.debug("zero polynomial " + a); 395 } 396 return false; 397 } 398 } 399 // test for top reducible polynomials 400 List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>( Gp ); 401 List<GenPolynomial<C>> F = new ArrayList<GenPolynomial<C>>( G.size() ); 402 while ( G.size() > 0 ) { 403 GenPolynomial<C> a = G.remove(0); 404 if ( red.isTopReducible(G,a) || red.isTopReducible(F,a) ) { 405 if (debug) { 406 logger.debug("top reducible polynomial " + a); 407 } 408 return false; 409 } else { 410 F.add(a); 411 } 412 } 413 G = F; 414 if ( G.size() <= 1 ) { 415 return true; 416 } 417 // test reducibility of polynomials 418 int len = G.size(); 419 int i = 0; 420 while ( i < len ) { 421 GenPolynomial<C> a = G.remove(0); 422 if ( ! red.isNormalform( G, a ) ) { 423 if (debug) { 424 logger.debug("reducible polynomial " + a); 425 } 426 return false; 427 } 428 G.add( a ); // re-adds as last 429 i++; 430 } 431 return true; 432 } 433 434 435 /** 436 * Test if reduction matrix. 437 * @param exgb an ExtendedGB container. 438 * @return true, if exgb contains a reduction matrix, else false. 439 */ 440 public boolean 441 isReductionMatrix(ExtendedGB<C> exgb) { 442 if ( exgb == null ) { 443 return true; 444 } 445 return isReductionMatrix(exgb.F,exgb.G,exgb.F2G,exgb.G2F); 446 } 447 448 449 /** 450 * Test if reduction matrix. 451 * @param F a polynomial list. 452 * @param G a Groebner base. 453 * @param Mf a possible reduction matrix. 454 * @param Mg a possible reduction matrix. 455 * @return true, if Mg and Mf are reduction matrices, else false. 456 */ 457 public boolean 458 isReductionMatrix(List<GenPolynomial<C>> F, 459 List<GenPolynomial<C>> G, 460 List<List<GenPolynomial<C>>> Mf, 461 List<List<GenPolynomial<C>>> Mg) { 462 // no more check G and Mg: G * Mg[i] == 0 463 // check F and Mg: F * Mg[i] == G[i] 464 int k = 0; 465 for ( List<GenPolynomial<C>> row : Mg ) { 466 boolean t = red.isReductionNF( row, F, G.get( k ), null ); 467 if ( ! t ) { 468 logger.error("F isReductionMatrix s, k = " + F.size() + ", " + k); 469 return false; 470 } 471 k++; 472 } 473 // check G and Mf: G * Mf[i] == F[i] 474 k = 0; 475 for ( List<GenPolynomial<C>> row : Mf ) { 476 boolean t = red.isReductionNF( row, G, F.get( k ), null ); 477 if ( ! t ) { 478 logger.error("G isReductionMatrix s, k = " + G.size() + ", " + k); 479 return false; 480 } 481 k++; 482 } 483 return true; 484 } 485 486 487 /** 488 * Normalize M. 489 * Make all rows the same size and make certain column elements zero. 490 * @param M a reduction matrix. 491 * @return normalized M. 492 */ 493 public List<List<GenPolynomial<C>>> 494 normalizeMatrix(int flen, List<List<GenPolynomial<C>>> M) { 495 if ( M == null ) { 496 return M; 497 } 498 if ( M.size() == 0 ) { 499 return M; 500 } 501 List<List<GenPolynomial<C>>> N = new ArrayList<List<GenPolynomial<C>>>(); 502 List<List<GenPolynomial<C>>> K = new ArrayList<List<GenPolynomial<C>>>(); 503 int len = M.get( M.size()-1 ).size(); // longest row 504 // pad / extend rows 505 for ( List<GenPolynomial<C>> row : M ) { 506 List<GenPolynomial<C>> nrow = new ArrayList<GenPolynomial<C>>( row ); 507 for ( int i = row.size(); i < len; i++ ) { 508 nrow.add( null ); 509 } 510 N.add( nrow ); 511 } 512 // System.out.println("norm N fill = " + N); 513 // make zero columns 514 int k = flen; 515 for ( int i = 0; i < N.size(); i++ ) { // 0 516 List<GenPolynomial<C>> row = N.get( i ); 517 if ( debug ) { 518 logger.info("row = " + row); 519 } 520 K.add( row ); 521 if ( i < flen ) { // skip identity part 522 continue; 523 } 524 List<GenPolynomial<C>> xrow; 525 GenPolynomial<C> a; 526 //System.out.println("norm i = " + i); 527 for ( int j = i+1; j < N.size(); j++ ) { 528 List<GenPolynomial<C>> nrow = N.get( j ); 529 //System.out.println("nrow j = " +j + ", " + nrow); 530 if ( k < nrow.size() ) { // always true 531 a = nrow.get( k ); 532 //System.out.println("k, a = " + k + ", " + a); 533 if ( a != null && !a.isZERO() ) { 534 xrow = blas.scalarProduct( a, row); 535 xrow = blas.vectorAdd(xrow,nrow); 536 //System.out.println("xrow = " + xrow); 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<GenPolynomial<C>> row: K ) { 547 List<GenPolynomial<C>> tr = new ArrayList<GenPolynomial<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 * Minimal extended groebner basis. 561 * @param Gp a Groebner base. 562 * @param M a reduction matrix, is modified. 563 * @return a (partially) reduced Groebner base of Gp in a container. 564 */ 565 public ExtendedGB<C> 566 minimalExtendedGB(int flen, 567 List<GenPolynomial<C>> Gp, 568 List<List<GenPolynomial<C>>> M) { 569 if ( Gp == null ) { 570 return null; //new ExtendedGB<C>(null,Gp,null,M); 571 } 572 if ( Gp.size() <= 1 ) { 573 return new ExtendedGB<C>(null,Gp,null,M); 574 } 575 List<GenPolynomial<C>> G; 576 List<GenPolynomial<C>> F; 577 G = new ArrayList<GenPolynomial<C>>( Gp ); 578 F = new ArrayList<GenPolynomial<C>>( Gp.size() ); 579 580 List<List<GenPolynomial<C>>> Mg; 581 List<List<GenPolynomial<C>>> Mf; 582 Mg = new ArrayList<List<GenPolynomial<C>>>( M.size() ); 583 Mf = new ArrayList<List<GenPolynomial<C>>>( M.size() ); 584 List<GenPolynomial<C>> row; 585 for ( List<GenPolynomial<C>> r : M ) { 586 // must be copied also 587 row = new ArrayList<GenPolynomial<C>>( r ); 588 Mg.add( row ); 589 } 590 row = null; 591 592 GenPolynomial<C> a; 593 ExpVector e; 594 ExpVector f; 595 GenPolynomial<C> p; 596 boolean mt; 597 ListIterator<GenPolynomial<C>> it; 598 ArrayList<Integer> ix = new ArrayList<Integer>(); 599 ArrayList<Integer> jx = new ArrayList<Integer>(); 600 int k = 0; 601 //System.out.println("flen, Gp, M = " + flen + ", " + Gp.size() + ", " + M.size() ); 602 while ( G.size() > 0 ) { 603 a = G.remove(0); 604 e = a.leadingExpVector(); 605 606 it = G.listIterator(); 607 mt = false; 608 while ( it.hasNext() && ! mt ) { 609 p = it.next(); 610 f = p.leadingExpVector(); 611 mt = e.multipleOf( f ); 612 } 613 it = F.listIterator(); 614 while ( it.hasNext() && ! mt ) { 615 p = it.next(); 616 f = p.leadingExpVector(); 617 mt = e.multipleOf( f ); 618 } 619 //System.out.println("k, mt = " + k + ", " + mt); 620 if ( ! mt ) { 621 F.add( a ); 622 ix.add( k ); 623 } else { // drop polynomial and corresponding row and column 624 // F.add( a.ring.getZERO() ); 625 jx.add( k ); 626 } 627 k++; 628 } 629 if ( debug ) { 630 logger.debug("ix, #M, jx = " + ix + ", " + Mg.size() + ", " + jx); 631 } 632 int fix = -1; // copied polys 633 // copy Mg to Mf as indicated by ix 634 for ( int i = 0; i < ix.size(); i++ ) { 635 int u = ix.get(i); 636 if ( u >= flen && fix == -1 ) { 637 fix = Mf.size(); 638 } 639 //System.out.println("copy u, fix = " + u + ", " + fix); 640 if ( u >= 0 ) { 641 row = Mg.get( u ); 642 Mf.add( row ); 643 } 644 } 645 if ( F.size() <= 1 || fix == -1 ) { 646 return new ExtendedGB<C>(null,F,null,Mf); 647 } 648 // must return, since extended normalform has not correct order of polys 649 /* 650 G = F; 651 F = new ArrayList<GenPolynomial<C>>( G.size() ); 652 List<GenPolynomial<C>> temp; 653 k = 0; 654 final int len = G.size(); 655 while ( G.size() > 0 ) { 656 a = G.remove(0); 657 if ( k >= fix ) { // dont touch copied polys 658 row = Mf.get( k ); 659 //System.out.println("doing k = " + k + ", " + a); 660 // must keep order, but removed polys missing 661 temp = new ArrayList<GenPolynomial<C>>( len ); 662 temp.addAll( F ); 663 temp.add( a.ring.getZERO() ); // ?? 664 temp.addAll( G ); 665 //System.out.println("row before = " + row); 666 a = red.normalform( row, temp, a ); 667 //System.out.println("row after = " + row); 668 } 669 F.add( a ); 670 k++; 671 } 672 // does Mf need renormalization? 673 */ 674 return new ExtendedGB<C>(null,F,null,Mf); 675 } 676 677 678 /** 679 * Univariate head term degrees. 680 * @param A list of polynomials. 681 * @return a list of the degrees of univariate head terms. 682 */ 683 public List<Long> univariateDegrees(List<GenPolynomial<C>> A) { 684 List<Long> ud = new ArrayList<Long>(); 685 if ( A == null || A.size() == 0 ) { 686 return ud; 687 } 688 GenPolynomialRing<C> pfac = A.get(0).ring; 689 if ( pfac.nvar <= 0) { 690 return ud; 691 } 692 //int uht = 0; 693 Map<Integer, Long> v = new TreeMap<Integer, Long>(); // for non reduced GBs 694 for (GenPolynomial<C> p : A) { 695 ExpVector e = p.leadingExpVector(); 696 if (e == null) { 697 continue; 698 } 699 int[] u = e.dependencyOnVariables(); 700 if (u == null) { 701 continue; 702 } 703 if (u.length == 1) { 704 //uht++; 705 Long d = v.get(u[0]); 706 if (d == null) { 707 v.put(u[0], e.getVal(u[0])); 708 } 709 } 710 } 711 for (int i = 0; i < pfac.nvar; i++) { 712 Long d = v.get(i); 713 ud.add(d); 714 } 715 //Collections.reverse(ud); 716 return ud; 717 } 718 719 720 /** 721 * Construct univariate polynomial of minimal degree in variable i of a zero 722 * dimensional ideal(G). 723 * @param i variable index. 724 * @param G list of polynomials, a monic reduced Gröbner base of a zero 725 * dimensional ideal. 726 * @return univariate polynomial of minimal degree in variable i in ideal(G) 727 */ 728 public GenPolynomial<C> constructUnivariate(int i, List<GenPolynomial<C>> G) { 729 if (G == null || G.size() == 0) { 730 throw new IllegalArgumentException("G may not be null or empty"); 731 } 732 List<Long> ud = univariateDegrees(G); 733 if (ud.size() <= i) { 734 //logger.info("univ pol, ud = " + ud); 735 throw new IllegalArgumentException("ideal(G) not zero dimensional " + ud); 736 } 737 int ll = 0; 738 Long di = ud.get(i); 739 if (di != null) { 740 ll = (int) (long) di; 741 } else { 742 throw new IllegalArgumentException("ideal(G) not zero dimensional"); 743 } 744 long vsdim = 1; 745 for ( Long d : ud ) { 746 if ( d != null ) { 747 vsdim *= d; 748 } 749 } 750 logger.info("univariate construction, deg = " + ll + ", vsdim = " + vsdim); 751 GenPolynomialRing<C> pfac = G.get(0).ring; 752 RingFactory<C> cfac = pfac.coFac; 753 String var = pfac.getVars()[pfac.nvar - 1 - i]; 754 GenPolynomialRing<C> ufac = new GenPolynomialRing<C>(cfac, 1, new TermOrder(TermOrder.INVLEX), 755 new String[] { var }); 756 757 GenPolynomialRing<C> cpfac = new GenPolynomialRing<C>(cfac, ll, new TermOrder(TermOrder.INVLEX)); 758 GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(cpfac, pfac); 759 GenPolynomial<GenPolynomial<C>> P = rfac.getZERO(); 760 for (int k = 0; k < ll; k++) { 761 GenPolynomial<GenPolynomial<C>> Pp = rfac.univariate(i, k); 762 GenPolynomial<C> cp = cpfac.univariate(cpfac.nvar - 1 - k); 763 Pp = Pp.multiply(cp); 764 P = P.sum(Pp); 765 } 766 if ( debug ) { 767 logger.info("univariate construction, P = " + P); 768 logger.info("univariate construction, deg_*(G) = " + ud); 769 //throw new RuntimeException("check"); 770 } 771 GenPolynomial<C> X; 772 GenPolynomial<C> XP; 773 // solve system of linear equations for the coefficients of the univariate polynomial 774 List<GenPolynomial<C>> ls; 775 int z = -1; 776 do { 777 //System.out.println("ll = " + ll); 778 GenPolynomial<GenPolynomial<C>> Pp = rfac.univariate(i, ll); 779 GenPolynomial<C> cp = cpfac.univariate(cpfac.nvar - 1 - ll); 780 Pp = Pp.multiply(cp); 781 P = P.sum(Pp); 782 X = pfac.univariate(i, ll); 783 XP = red.normalform(G, X); 784 //System.out.println("XP = " + XP); 785 GenPolynomial<GenPolynomial<C>> XPp = PolyUtil.<C> toRecursive(rfac, XP); 786 GenPolynomial<GenPolynomial<C>> XPs = XPp.sum(P); 787 ls = new ArrayList<GenPolynomial<C>>(XPs.getMap().values()); 788 //System.out.println("ls,1 = " + ls); 789 ls = red.irreducibleSet(ls); 790 z = commonZeroTest(ls); 791 if (z != 0) { 792 ll++; 793 if ( ll > vsdim ) { 794 logger.info("univariate construction, P = " + P); 795 logger.info("univariate construction, nf(P) = " + XP); 796 logger.info("G = " + G); 797 throw new ArithmeticException("univariate polynomial degree greater than vector space dimansion"); 798 } 799 cpfac = cpfac.extend(1); 800 rfac = new GenPolynomialRing<GenPolynomial<C>>(cpfac, pfac); 801 P = PolyUtil.<C> extendCoefficients(rfac, P, 0, 0L); 802 XPp = PolyUtil.<C> extendCoefficients(rfac, XPp, 0, 1L); 803 P = P.sum(XPp); 804 } 805 } while (z != 0); // && ll <= 5 && !XP.isZERO() 806 // construct result polynomial 807 GenPolynomial<C> pol = ufac.univariate(0, ll); 808 for (GenPolynomial<C> pc : ls) { 809 ExpVector e = pc.leadingExpVector(); 810 if (e == null) { 811 continue; 812 } 813 int[] v = e.dependencyOnVariables(); 814 if (v == null || v.length == 0) { 815 continue; 816 } 817 int vi = v[0]; 818 C tc = pc.trailingBaseCoefficient(); 819 tc = tc.negate(); 820 GenPolynomial<C> pi = ufac.univariate(0, ll - 1 - vi); 821 pi = pi.multiply(tc); 822 pol = pol.sum(pi); 823 } 824 if (logger.isInfoEnabled()) { 825 logger.info("univariate construction, pol = " + pol); 826 } 827 return pol; 828 } 829 830 831 /** 832 * Cleanup and terminate ThreadPool. 833 */ 834 public void terminate() { 835 logger.info("terminate not implemented"); 836 //throw new RuntimeException("get a stack trace"); 837 } 838 839 840 /** 841 * Cancel ThreadPool. 842 */ 843 public int cancel() { 844 logger.info("cancel not implemented"); 845 return 0; 846 } 847 848}