001 /* 002 * $Id: OrderedCPairlist.java 3426 2010-12-24 13:17:58Z kredel $ 003 */ 004 005 package edu.jas.application; 006 007 008 import java.io.Serializable; 009 import java.util.ArrayList; 010 import java.util.BitSet; 011 import java.util.Iterator; 012 import java.util.LinkedList; 013 import java.util.List; 014 import java.util.Map; 015 import java.util.SortedMap; 016 import java.util.TreeMap; 017 018 import org.apache.log4j.Logger; 019 020 import edu.jas.poly.ExpVector; 021 import edu.jas.poly.GenPolynomial; 022 import edu.jas.poly.GenPolynomialRing; 023 import edu.jas.poly.GenSolvablePolynomialRing; 024 import edu.jas.structure.GcdRingElem; 025 import edu.jas.structure.RingFactory; 026 027 028 /** 029 * Pair list management. Implemented for ColorPolynomials using TreeMap and 030 * BitSet. 031 * @author Heinz Kredel 032 */ 033 034 public class OrderedCPairlist<C extends GcdRingElem<C>> implements Serializable, 035 Cloneable { 036 037 038 private static final Logger logger = Logger.getLogger(OrderedCPairlist.class); 039 040 041 protected final GenPolynomialRing<GenPolynomial<C>> ring; 042 043 044 protected final List<ColorPolynomial<C>> P; 045 046 047 protected final SortedMap<ExpVector, LinkedList<CPair<C>>> pairlist; 048 049 050 protected final List<BitSet> red; 051 052 053 protected final CReductionSeq<C> reduction; 054 055 056 protected boolean oneInGB = false; 057 058 059 protected boolean useCriterion4 = false; // unused 060 061 062 protected int putCount; 063 064 065 protected int remCount; 066 067 068 protected final int moduleVars; // unused 069 070 071 /** 072 * Constructor for OrderedPairlist. 073 * @param r polynomial factory. 074 */ 075 public OrderedCPairlist(GenPolynomialRing<GenPolynomial<C>> r) { 076 this(0, r); 077 } 078 079 080 /** 081 * Constructor for OrderedPairlist. 082 * @param m number of module variables. 083 * @param r polynomial factory. 084 */ 085 public OrderedCPairlist(int m, GenPolynomialRing<GenPolynomial<C>> r) { 086 moduleVars = m; 087 ring = r; 088 P = new ArrayList<ColorPolynomial<C>>(); 089 pairlist = new TreeMap<ExpVector, LinkedList<CPair<C>>>(ring.tord 090 .getAscendComparator()); 091 // pairlist = new TreeMap( to.getSugarComparator() ); 092 red = new ArrayList<BitSet>(); 093 putCount = 0; 094 remCount = 0; 095 if (ring instanceof GenSolvablePolynomialRing) { 096 useCriterion4 = false; 097 } 098 RingFactory<GenPolynomial<C>> rf = ring.coFac; 099 GenPolynomialRing<C> cf = (GenPolynomialRing<C>) rf; 100 reduction = new CReductionSeq<C>(cf.coFac); 101 } 102 103 104 /** 105 * Internal constructor for OrderedPairlist. Used to clone this pair list. 106 * @param m number of module variables. 107 * @param r polynomial factory. 108 */ 109 private OrderedCPairlist(int m, GenPolynomialRing<GenPolynomial<C>> ring, 110 List<ColorPolynomial<C>> P, SortedMap<ExpVector, LinkedList<CPair<C>>> pl, 111 List<BitSet> red, CReductionSeq<C> cred, int pc, int rc) { 112 moduleVars = m; 113 this.ring = ring; 114 this.P = P; 115 pairlist = pl; 116 this.red = red; 117 reduction = cred; 118 putCount = pc; 119 remCount = rc; 120 } 121 122 123 /** 124 * Clone this OrderedPairlist. 125 * @return a 2 level clone of this. 126 */ 127 @Override 128 public OrderedCPairlist<C> clone() { 129 return new OrderedCPairlist<C>(moduleVars, ring, 130 new ArrayList<ColorPolynomial<C>>(P), clonePairlist(), cloneBitSet(), 131 reduction, putCount, remCount); 132 } 133 134 135 /** 136 * Clone this pairlist. 137 * @return a 2 level clone of this pairlist. 138 */ 139 private SortedMap<ExpVector, LinkedList<CPair<C>>> clonePairlist() { 140 SortedMap<ExpVector, LinkedList<CPair<C>>> pl = new TreeMap<ExpVector, LinkedList<CPair<C>>>( 141 ring.tord.getAscendComparator()); 142 for (Map.Entry<ExpVector, LinkedList<CPair<C>>> m : pairlist.entrySet()) { 143 ExpVector e = m.getKey(); 144 LinkedList<CPair<C>> l = m.getValue(); 145 l = new LinkedList<CPair<C>>(l); 146 pl.put(e, l); 147 } 148 return pl; 149 } 150 151 152 /** 153 * Count remaining Pairs. 154 * @return number of pairs remaining in this pairlist. 155 */ 156 public int pairCount() { 157 int c = 0; 158 for (Map.Entry<ExpVector, LinkedList<CPair<C>>> m : pairlist.entrySet()) { 159 LinkedList<CPair<C>> l = m.getValue(); 160 c += l.size(); 161 } 162 return c; 163 } 164 165 166 /** 167 * Clone this reduction BitSet. 168 * @return a 2 level clone of this reduction BitSet. 169 */ 170 private List<BitSet> cloneBitSet() { 171 List<BitSet> r = new ArrayList<BitSet>(this.red.size()); 172 for (BitSet b : red) { 173 BitSet n = (BitSet) b.clone(); 174 r.add(n); 175 } 176 return r; 177 } 178 179 180 /** 181 * bitCount. 182 * @return number of bits set in this bitset. 183 */ 184 public int bitCount() { 185 int c = 0; 186 for (BitSet b : red) { 187 c += b.cardinality(); 188 } 189 return c; 190 } 191 192 193 /** 194 * toString. 195 * @return counters of this. 196 */ 197 @Override 198 public String toString() { 199 int p = pairCount(); 200 int b = bitCount(); 201 if (p != b) { 202 return "OrderedCPairlist( pairCount=" + p + ", bitCount=" + b + ", putCount=" 203 + putCount + ", remCount=" + remCount + " )"; 204 } else { 205 return "OrderedCPairlist( pairCount=" + p + ", putCount=" + putCount 206 + ", remCount=" + remCount + " )"; 207 } 208 } 209 210 211 /** 212 * Equals. 213 * @param ob an Object. 214 * @return true if this is equal to o, else false. 215 */ 216 @Override 217 @SuppressWarnings("unchecked") 218 public boolean equals(Object ob) { 219 OrderedCPairlist<C> c = null; 220 try { 221 c = (OrderedCPairlist<C>) ob; 222 } catch (ClassCastException e) { 223 return false; 224 } 225 if (c == null) { 226 return false; 227 } 228 boolean t = getList().equals(c.getList()); 229 if (!t) { 230 return t; 231 } 232 t = pairCount() == c.pairCount(); 233 if (!t) { 234 return t; 235 } 236 return true; 237 } 238 239 240 /** 241 * Hash code for this pair list. 242 * @see java.lang.Object#hashCode() 243 */ 244 @Override 245 public int hashCode() { 246 int h; 247 h = getList().hashCode(); 248 h = h << 7; 249 h = pairCount(); 250 return h; 251 } 252 253 254 /** 255 * Put one Polynomial to the pairlist and reduction matrix. 256 * @param p polynomial. 257 * @return the index of the added polynomial. 258 */ 259 public synchronized int put(ColorPolynomial<C> p) { 260 putCount++; 261 if (oneInGB) { 262 return P.size() - 1; 263 } 264 ExpVector e = p.leadingExpVector(); 265 // System.out.println("p = " + p); 266 int l = P.size(); 267 for (int j = 0; j < l; j++) { 268 ColorPolynomial<C> pj = P.get(j); 269 // System.out.println("pj = " + pj); 270 ExpVector f = pj.leadingExpVector(); 271 if (moduleVars > 0) { 272 if (e.invLexCompareTo(f, 0, moduleVars) != 0) { 273 continue; // skip pair 274 } 275 } 276 // System.out.println("e = " + e + ", f = " + f); 277 ExpVector g = e.lcm(f); // EVLCM( e, f ); 278 CPair<C> pair = new CPair<C>(pj, p, j, l); 279 // redi = (BitSet)red.get(j); 280 // /if ( j < l ) redi.set( l ); 281 // System.out.println("bitset."+j+" = " + redi ); 282 283 // multiple pairs under same keys -> list of pairs 284 LinkedList<CPair<C>> xl = pairlist.get(g); 285 if (xl == null) { 286 xl = new LinkedList<CPair<C>>(); 287 } 288 // xl.addLast( pair ); // first or last ? 289 xl.addFirst(pair); // first or last ? better for d- e-GBs 290 pairlist.put(g, xl); 291 } 292 // System.out.println("pairlist.keys@put = " + pairlist.keySet() ); 293 P.add(p); 294 BitSet redi = new BitSet(); 295 redi.set(0, l); // jdk 1.4 296 red.add(redi); 297 return P.size() - 1; 298 } 299 300 301 /** 302 * Remove the next required pair from the pairlist and reduction matrix. 303 * Appy the criterions 3 and 4 to see if the S-polynomial is required. 304 * @return the next pair if one exists, otherwise null. 305 */ 306 public synchronized CPair<C> removeNext() { 307 if (oneInGB) { 308 return null; 309 } 310 Iterator<Map.Entry<ExpVector, LinkedList<CPair<C>>>> ip = pairlist.entrySet() 311 .iterator(); 312 313 CPair<C> pair = null; 314 boolean c = false; 315 int i, j; 316 317 while (!c && ip.hasNext()) { 318 Map.Entry<ExpVector, LinkedList<CPair<C>>> me = ip.next(); 319 ExpVector g = me.getKey(); 320 LinkedList<CPair<C>> xl = me.getValue(); 321 if (logger.isInfoEnabled()) 322 logger.info("g = " + g); 323 pair = null; 324 while (!c && xl.size() > 0) { 325 pair = xl.removeFirst(); 326 // xl is also modified in pairlist 327 i = pair.i; 328 j = pair.j; 329 // System.out.println("pair(" + j + "," +i+") "); 330 if (useCriterion4) { 331 // c = reduction.criterion4( pair.pi, pair.pj, g ); 332 c = true; 333 } else { 334 c = true; 335 } 336 // System.out.println("c4 = " + c); 337 if (c) { 338 // c = criterion3( i, j, g ); 339 // System.out.println("c3 = " + c); 340 } 341 red.get(j).clear(i); // set(i,false) jdk1.4 342 } 343 if (xl.size() == 0) 344 ip.remove(); 345 // = pairlist.remove( g ); 346 } 347 if (!c) { 348 pair = null; 349 } else { 350 remCount++; // count only real pairs 351 } 352 return pair; 353 } 354 355 356 /** 357 * Test if there is possibly a pair in the list. 358 * @return true if a next pair could exist, otherwise false. 359 */ 360 public synchronized boolean hasNext() { 361 return pairlist.size() > 0; 362 } 363 364 365 /** 366 * Get the list of polynomials. 367 * @return the polynomial list. 368 */ 369 public List<ColorPolynomial<C>> getList() { 370 return P; 371 } 372 373 374 /** 375 * Get the number of polynomials put to the pairlist. 376 * @return the number of calls to put. 377 */ 378 public int putCount() { 379 return putCount; 380 } 381 382 383 /** 384 * Get the number of required pairs removed from the pairlist. 385 * @return the number of non null pairs delivered. 386 */ 387 public int remCount() { 388 return remCount; 389 } 390 391 392 /** 393 * Put to ONE-Polynomial to the pairlist. 394 * @param one polynomial. (no more required) 395 * @return the index of the last polynomial. 396 */ 397 public synchronized int putOne(ColorPolynomial<C> one) { 398 putCount++; 399 if (one == null) { 400 return P.size() - 1; 401 } 402 if (!one.isONE()) { 403 return P.size() - 1; 404 } 405 oneInGB = true; 406 pairlist.clear(); 407 P.clear(); 408 P.add(one); 409 red.clear(); 410 return P.size() - 1; 411 } 412 413 414 /** 415 * GB criterium 3. 416 * @return true if the S-polynomial(i,j) is required. 417 */ 418 public boolean criterion3(int i, int j, ExpVector eij) { 419 // assert i < j; 420 boolean s = red.get(j).get(i); 421 if (!s) { 422 logger.warn("c3.s false for " + j + " " + i); 423 return s; 424 } 425 // now s = true; 426 for (int k = 0; k < P.size(); k++) { 427 if ( i != k && j != k ) { 428 ColorPolynomial<C> A = P.get(k); 429 ExpVector ek = A.leadingExpVector(); 430 boolean m = eij.multipleOf(ek); // EVMT(eij,ek); 431 if (m) { 432 if (k < i) { 433 // System.out.println("k < i "+k+" "+i); 434 s = red.get(i).get(k) || red.get(j).get(k); 435 } else if (i < k && k < j) { 436 // System.out.println("i < k < j "+i+" "+k+" "+j); 437 s = red.get(k).get(i) || red.get(j).get(k); 438 } else if (j < k) { 439 // System.out.println("j < k "+j+" "+k); 440 s = red.get(k).get(i) || red.get(k).get(j); 441 } 442 // System.out.println("s."+k+" = " + s); 443 if (!s) { 444 return s; 445 } 446 } 447 } 448 } 449 return true; 450 } 451 }