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