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