001 /* 002 * $Id: OrderedPairlist.java 3419 2010-12-19 18:44:03Z kredel $ 003 */ 004 005 package edu.jas.ps; 006 007 008 import java.util.ArrayList; 009 import java.util.BitSet; 010 import java.util.Iterator; 011 import java.util.LinkedList; 012 import java.util.List; 013 import java.util.Map; 014 import java.util.TreeMap; 015 016 import org.apache.log4j.Logger; 017 018 import edu.jas.poly.ExpVector; 019 import edu.jas.structure.RingElem; 020 021 022 /** 023 * Pair list management. Implemented using MultiVarPowerSeries, TreeMap and 024 * BitSet. 025 * @author Heinz Kredel 026 */ 027 028 public class OrderedPairlist<C extends RingElem<C>> { 029 030 031 protected final ArrayList<MultiVarPowerSeries<C>> P; 032 033 034 protected final TreeMap<ExpVector, LinkedList<Pair<C>>> pairlist; 035 036 037 protected final ArrayList<BitSet> red; 038 039 040 protected final MultiVarPowerSeriesRing<C> ring; 041 042 043 protected final ReductionSeq<C> reduction; 044 045 046 protected boolean oneInGB = false; 047 048 049 protected boolean useCriterion4 = true; 050 051 052 protected boolean useCriterion3 = true; 053 054 055 protected int putCount; 056 057 058 protected int remCount; 059 060 061 protected final int moduleVars; 062 063 064 private static final Logger logger = Logger.getLogger(OrderedPairlist.class); 065 066 067 /** 068 * Constructor for OrderedPairlist. 069 * @param r power series factory. 070 */ 071 public OrderedPairlist(MultiVarPowerSeriesRing<C> r) { 072 this(0, r); 073 } 074 075 076 /** 077 * Constructor for OrderedPairlist. 078 * @param m number of module variables. 079 * @param r power series factory. 080 */ 081 public OrderedPairlist(int m, MultiVarPowerSeriesRing<C> r) { 082 moduleVars = m; 083 ring = r; 084 P = new ArrayList<MultiVarPowerSeries<C>>(); 085 pairlist = new TreeMap<ExpVector, LinkedList<Pair<C>>>(ring.polyRing().tord.getAscendComparator()); 086 //pairlist = new TreeMap<ExpVector, LinkedList<Pair<C>>>(ring.polyRing().tord.getDescendComparator()); 087 red = new ArrayList<BitSet>(); 088 putCount = 0; 089 remCount = 0; 090 reduction = new ReductionSeq<C>(); 091 } 092 093 094 /** 095 * toString. 096 */ 097 @Override 098 public String toString() { 099 StringBuffer s = new StringBuffer("OrderedPairlist("); 100 //s.append("ps="+P.size()); 101 s.append("#put=" + putCount); 102 s.append(", #rem=" + remCount); 103 if (pairlist.size() != 0) { 104 s.append(", size=" + pairlist.size()); 105 } 106 s.append(")"); 107 return s.toString(); 108 } 109 110 111 /** 112 * Put one power Series to the pairlist and reduction matrix. 113 * @param p power series. 114 * @return the index of the added power series. 115 */ 116 public synchronized int put(MultiVarPowerSeries<C> p) { 117 putCount++; 118 if (oneInGB) { 119 return P.size() - 1; 120 } 121 ExpVector e = p.orderExpVector(); 122 int l = P.size(); 123 for (int j = 0; j < l; j++) { 124 MultiVarPowerSeries<C> pj = P.get(j); 125 ExpVector f = pj.orderExpVector(); 126 if (moduleVars > 0) { 127 if (!reduction.moduleCriterion(moduleVars, e, f)) { 128 continue; // skip pair 129 } 130 } 131 ExpVector g = e.lcm(f); 132 Pair<C> pair = new Pair<C>(pj, p, j, l); 133 // redi = (BitSet)red.get(j); 134 ///if ( j < l ) redi.set( l ); 135 // System.out.println("bitset."+j+" = " + redi ); 136 137 //multiple pairs under same keys -> list of pairs 138 LinkedList<Pair<C>> xl = pairlist.get(g); 139 if (xl == null) { 140 xl = new LinkedList<Pair<C>>(); 141 } 142 //xl.addLast( pair ); // first or last ? 143 xl.addFirst(pair); // first or last ? better for d- e-GBs 144 pairlist.put(g, xl); 145 } 146 // System.out.println("pairlist.keys@put = " + pairlist.keySet() ); 147 P.add(p); 148 BitSet redi = new BitSet(); 149 redi.set(0, l); // jdk 1.4 150 red.add(redi); 151 return P.size() - 1; 152 } 153 154 155 /** 156 * Remove the next required pair from the pairlist and reduction matrix. 157 * Apply the criterions 3 and 4 to see if the S-power-series is required. 158 * @return the next pair if one exists, otherwise null. 159 */ 160 public synchronized Pair<C> removeNext() { 161 if (oneInGB) { 162 return null; 163 } 164 Iterator<Map.Entry<ExpVector, LinkedList<Pair<C>>>> ip = pairlist.entrySet().iterator(); 165 166 Pair<C> pair = null; 167 boolean c = false; 168 int i, j; 169 170 while (!c && ip.hasNext()) { 171 Map.Entry<ExpVector, LinkedList<Pair<C>>> me = ip.next(); 172 ExpVector g = me.getKey(); 173 LinkedList<Pair<C>> xl = me.getValue(); 174 if (logger.isInfoEnabled()) 175 logger.info("g = " + g); 176 pair = null; 177 while (!c && xl.size() > 0) { 178 pair = xl.removeFirst(); 179 // xl is also modified in pairlist 180 i = pair.i; 181 j = pair.j; 182 // System.out.println("pair(" + j + "," +i+") "); 183 c = true; 184 if (useCriterion4) { 185 c = reduction.criterion4(pair.pi, pair.pj, g); 186 } 187 //System.out.println("c4 = " + c); 188 if (c && useCriterion3) { 189 c = criterion3(i, j, g); 190 //System.out.println("c3 = " + c); 191 } 192 red.get(j).clear(i); // set(i,false) jdk1.4 193 } 194 if (xl.size() == 0) 195 ip.remove(); 196 // = pairlist.remove( g ); 197 } 198 if (!c) { 199 pair = null; 200 } else { 201 remCount++; // count only real pairs 202 } 203 return pair; 204 } 205 206 207 /** 208 * Test if there is possibly a pair in the list. 209 * @return true if a next pair could exist, otherwise false. 210 */ 211 public synchronized boolean hasNext() { 212 return pairlist.size() > 0; 213 } 214 215 216 /** 217 * Get the list of power series. 218 * @return the power series list. 219 */ 220 public List<MultiVarPowerSeries<C>> getList() { 221 return P; 222 } 223 224 225 /** 226 * Get the number of power series put to the pairlist. 227 * @return the number of calls to put. 228 */ 229 public int putCount() { 230 return putCount; 231 } 232 233 234 /** 235 * Get the number of required pairs removed from the pairlist. 236 * @return the number of non null pairs delivered. 237 */ 238 public int remCount() { 239 return remCount; 240 } 241 242 243 /** 244 * Put to ONE-power-series to the pairlist. 245 * @param one power series. (no more required) 246 * @return the index of the last power series. 247 */ 248 public synchronized int putOne(MultiVarPowerSeries<C> one) { 249 putCount++; 250 if (one == null) { 251 return P.size() - 1; 252 } 253 if (!one.isONE()) { 254 return P.size() - 1; 255 } 256 return putOne(); 257 } 258 259 260 /** 261 * Put the ONE-power-series to the pairlist. 262 * @return the index of the last power-series. 263 */ 264 public synchronized int putOne() { 265 oneInGB = true; 266 pairlist.clear(); 267 P.clear(); 268 P.add(ring.getONE()); 269 red.clear(); 270 return P.size() - 1; 271 } 272 273 274 /** 275 * GB criterion 3. 276 * @return true if the S-power-series(i,j) is required. 277 */ 278 public boolean criterion3(int i, int j, ExpVector eij) { 279 // assert i < j; 280 boolean s = red.get(j).get(i); 281 if (!s) { 282 logger.warn("c3.s false for " + j + " " + i); 283 return s; 284 } 285 // now s = true; 286 for (int k = 0; k < P.size(); k++) { 287 MultiVarPowerSeries<C> A = P.get(k); 288 ExpVector ek = A.orderExpVector(); 289 boolean m = eij.multipleOf(ek); 290 if (m) { 291 if (k < i) { 292 // System.out.println("k < i "+k+" "+i); 293 s = red.get(i).get(k) || red.get(j).get(k); 294 } else if (i < k && k < j) { 295 // System.out.println("i < k < j "+i+" "+k+" "+j); 296 s = red.get(k).get(i) || red.get(j).get(k); 297 } else if (j < k) { 298 //System.out.println("j < k "+j+" "+k); 299 s = red.get(k).get(i) || red.get(k).get(j); 300 } 301 //System.out.println("s."+k+" = " + s); 302 if (!s) { 303 return s; 304 } 305 } 306 } 307 return true; 308 } 309 310 }