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