001/* 002 * $Id: OrderedMinPairlist.java 5869 2018-07-20 15:53:10Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007import java.util.ArrayList; 008import java.util.BitSet; 009import java.util.Iterator; 010import java.util.LinkedList; 011import java.util.Map; 012import java.util.TreeMap; 013 014import org.apache.logging.log4j.Logger; 015import org.apache.logging.log4j.LogManager; 016 017import edu.jas.poly.ExpVector; 018import edu.jas.poly.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.poly.GenSolvablePolynomialRing; 021import edu.jas.structure.RingElem; 022 023/** 024 * Pair list management. 025 * The original Buchberger algorithm with criterions 026 * using early pair exclusion. 027 * Implemented using GenPolynomial, TreeMap and BitSet. 028 * @author Heinz Kredel 029 */ 030 031public class OrderedMinPairlist<C extends RingElem<C> > extends OrderedPairlist<C> { 032 033 private static final Logger logger = LogManager.getLogger(OrderedMinPairlist.class); 034 035 036 /** 037 * Constructor. 038 */ 039 public OrderedMinPairlist() { 040 super(); 041 } 042 043 044 /** 045 * Constructor. 046 * @param r polynomial factory. 047 */ 048 public OrderedMinPairlist(GenPolynomialRing<C> r) { 049 this(0,r); 050 } 051 052 053 /** 054 * Constructor. 055 * @param m number of module variables. 056 * @param r polynomial factory. 057 */ 058 public OrderedMinPairlist(int m, GenPolynomialRing<C> r) { 059 super(m,r); 060 } 061 062 063 /** 064 * Create a new PairList. 065 * @param r polynomial ring. 066 */ 067 public PairList<C> create(GenPolynomialRing<C> r) { 068 return new OrderedMinPairlist<C>(r); 069 } 070 071 072 /** 073 * Create a new PairList. 074 * @param m number of module variables. 075 * @param r polynomial ring. 076 */ 077 public PairList<C> create(int m, GenPolynomialRing<C> r) { 078 return new OrderedMinPairlist<C>(m,r); 079 } 080 081 082 /** 083 * Put one Polynomial to the pairlist and reduction matrix. 084 * @param p polynomial. 085 * @return the index of the added polynomial. 086 */ 087 public synchronized int put(GenPolynomial<C> p) { 088 putCount++; 089 if ( oneInGB ) { 090 return P.size()-1; 091 } 092 ExpVector e = p.leadingExpVector(); 093 int l = P.size(); 094 BitSet redi = new BitSet(); 095 redi.set( 0, l ); // [0..l-1] = true 096 red.add( redi ); 097 P.add( p ); 098 for ( int j = 0; j < l; j++ ) { 099 GenPolynomial<C> pj = P.get(j); 100 ExpVector f = pj.leadingExpVector(); 101 if ( moduleVars > 0 ) { 102 if ( !reduction.moduleCriterion( moduleVars, e, f) ) { 103 red.get(j).clear(l); 104 continue; // skip pair 105 } 106 } 107 ExpVector g = e.lcm( f ); 108 //System.out.println("g = " + g); 109 Pair<C> pair = new Pair<C>( pj, p, j, l); 110 boolean c = true; 111 if ( useCriterion4 ) { 112 c = reduction.criterion4( pair.pi, pair.pj, g ); 113 } 114 //System.out.println("c4 = " + c); 115 if ( c ) { 116 c = criterion3( j, l, g ); 117 //System.out.println("c3 = " + c); 118 } 119 if ( !c ) { // skip pair 120 red.get(j).clear(l); 121 //System.out.println("c_skip = " + g); 122 continue; 123 } 124 //multiple pairs under same keys -> list of pairs 125 LinkedList<Pair<C>> xl = pairlist.get( g ); 126 if ( xl == null ) { 127 xl = new LinkedList<Pair<C>>(); 128 } 129 //xl.addLast( pair ); // first or last ? 130 xl.addFirst( pair ); // first or last ? better for d- e-GBs 131 pairlist.put( g, xl ); 132 } 133 // System.out.println("pairlist.keys@put = " + pairlist.keySet() ); 134 return P.size()-1; 135 } 136 137 138 /** 139 * Remove the next required pair from the pairlist and reduction matrix. 140 * Appy the criterions 3 and 4 to see if the S-polynomial is required. 141 * @return the next pair if one exists, otherwise null. 142 */ 143 public synchronized Pair<C> removeNext() { 144 if ( oneInGB ) { 145 return null; 146 } 147 Iterator< Map.Entry<ExpVector,LinkedList<Pair<C>>> > ip 148 = pairlist.entrySet().iterator(); 149 150 Pair<C> pair = null; 151 boolean c = false; 152 int i, j; 153 154 while ( !c && ip.hasNext() ) { 155 Map.Entry<ExpVector,LinkedList<Pair<C>>> me = ip.next(); 156 ExpVector g = me.getKey(); 157 LinkedList<Pair<C>> xl = me.getValue(); 158 if ( logger.isInfoEnabled() ) { 159 logger.info("g = " + g); 160 } 161 pair = null; 162 while ( !c && xl.size() > 0 ) { 163 pair = xl.removeFirst(); 164 // xl is also modified in pairlist 165 i = pair.i; 166 j = pair.j; 167 // System.out.println("pair(" + j + "," +i+") "); 168 if ( !red.get(j).get(i) ) { 169 System.out.println("c_y = " + g); // + ", " + red.get(j).get(i)); 170 continue; 171 } 172 c = true; 173 if ( useCriterion4 ) { 174 c = reduction.criterion4( pair.pi, pair.pj, g ); 175 } 176 //System.out.println("c4_x = " + c); 177 if ( c ) { 178 c = criterion3( i, j, g ); 179 //System.out.println("c3_x = " + c); 180 } 181 if ( !c ) { 182 //System.out.println("c_x = " + g); 183 } 184 red.get( j ).clear(i); // set(i,false) jdk1.4 185 } 186 if ( xl.size() == 0 ) { 187 ip.remove(); 188 // = pairlist.remove( g ); 189 } 190 } 191 if ( ! c ) { 192 pair = null; 193 } else { 194 pair.maxIndex(P.size()-1); 195 remCount++; // count only real pairs 196 if ( logger.isDebugEnabled() ) { 197 logger.info("pair(" + pair.j + "," + pair.i + ")"); 198 } 199 } 200 return pair; 201 } 202 203 204 /** 205 * GB criterium 3. 206 * @return true if the S-polynomial(i,j) is required. 207 */ 208 public boolean criterion3(int i, int j, ExpVector eij) { 209 // assert i < j; 210 boolean s; 211 s = red.get( j ).get(i); 212 if ( ! s ) { 213 logger.warn("c3.s false for " + j + " " + i); 214 return s; 215 } 216 s = true; 217 boolean m; 218 GenPolynomial<C> A; 219 ExpVector ek; 220 for ( int k = 0; k < P.size(); k++ ) { 221 A = P.get( k ); 222 ek = A.leadingExpVector(); 223 m = eij.multipleOf(ek) && eij.compareTo(ek) != 0; 224 if ( m ) { 225 if ( k < i ) { 226 // System.out.println("k < i "+k+" "+i); 227 s = red.get( i ).get(k) 228 || red.get( j ).get(k); 229 } 230 if ( i < k && k < j ) { 231 // System.out.println("i < k < j "+i+" "+k+" "+j); 232 s = red.get( k ).get(i) 233 || red.get( j ).get(k); 234 } 235 if ( j < k ) { 236 //System.out.println("j < k "+j+" "+k); 237 s = red.get( k ).get(i) 238 || red.get( k ).get(j); 239 } 240 //System.out.println("s."+k+" = " + s); 241 if ( ! s ) return s; 242 } 243 } 244 return true; 245 } 246 247}