001 /* 002 * $Id: GroebnerBaseSeq.java 3420 2010-12-19 21:34:25Z kredel $ 003 */ 004 005 package edu.jas.gb; 006 007 import java.util.ArrayList; 008 import java.util.List; 009 import java.util.ListIterator; 010 011 import org.apache.log4j.Logger; 012 013 import edu.jas.structure.RingElem; 014 015 //import edu.jas.poly.ExpVector; 016 import edu.jas.gb.OrderedPairlist; 017 import edu.jas.poly.GenPolynomial; 018 import edu.jas.poly.GenPolynomialRing; 019 020 021 /** 022 * Groebner Base sequential algorithm. 023 * Implements Groebner bases and GB test. 024 * @param <C> coefficient type 025 * @author Heinz Kredel 026 */ 027 028 public class GroebnerBaseSeq<C extends RingElem<C>> 029 extends GroebnerBaseAbstract<C> { 030 031 private static final Logger logger = Logger.getLogger(GroebnerBaseSeq.class); 032 private final boolean debug = logger.isDebugEnabled(); 033 034 035 /** 036 * Constructor. 037 */ 038 public GroebnerBaseSeq() { 039 super(); 040 } 041 042 043 /** 044 * Constructor. 045 * @param red Reduction engine 046 */ 047 public GroebnerBaseSeq(Reduction<C> red) { 048 super(red); 049 } 050 051 052 /** 053 * Constructor. 054 * @param red Reduction engine 055 * @param pl pair selection strategy 056 */ 057 public GroebnerBaseSeq(Reduction<C> red, PairList<C> pl) { 058 super(red,pl); 059 } 060 061 062 /** 063 * Groebner base using pairlist class. 064 * @param modv module variable number. 065 * @param F polynomial list. 066 * @return GB(F) a Groebner base of F. 067 */ 068 public List<GenPolynomial<C>> 069 GB( int modv, 070 List<GenPolynomial<C>> F ) { 071 GenPolynomial<C> p; 072 List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>(); 073 PairList<C> pairlist = null; 074 int l = F.size(); 075 ListIterator<GenPolynomial<C>> it = F.listIterator(); 076 while ( it.hasNext() ) { 077 p = it.next(); 078 if ( p.length() > 0 ) { 079 p = p.monic(); 080 if ( p.isONE() ) { 081 G.clear(); G.add( p ); 082 return G; // since no threads are activated 083 } 084 G.add( p ); 085 if ( pairlist == null ) { 086 //pairlist = new OrderedPairlist<C>( modv, p.ring ); 087 pairlist = strategy.create( modv, p.ring ); 088 if ( ! p.ring.coFac.isField() ) { 089 throw new IllegalArgumentException("coefficients not from a field"); 090 } 091 } 092 // putOne not required 093 pairlist.put( p ); 094 } else { 095 l--; 096 } 097 } 098 if ( l <= 1 ) { 099 return G; // since no threads are activated 100 } 101 logger.info("start " + pairlist); 102 103 Pair<C> pair; 104 GenPolynomial<C> pi; 105 GenPolynomial<C> pj; 106 GenPolynomial<C> S; 107 GenPolynomial<C> H; 108 while ( pairlist.hasNext() ) { 109 pair = pairlist.removeNext(); 110 //logger.debug("pair = " + pair); 111 if ( pair == null ) { 112 continue; 113 } 114 pi = pair.pi; 115 pj = pair.pj; 116 if ( /*false &&*/ debug ) { 117 logger.debug("pi = " + pi ); 118 logger.debug("pj = " + pj ); 119 } 120 121 S = red.SPolynomial( pi, pj ); 122 if ( S.isZERO() ) { 123 pair.setZero(); 124 continue; 125 } 126 if ( debug ) { 127 logger.debug("ht(S) = " + S.leadingExpVector() ); 128 } 129 130 H = red.normalform( G, S ); 131 if ( debug ) { 132 //logger.info("pair = " + pair); 133 //logger.info("ht(S) = " + S.monic()); //.leadingExpVector() ); 134 logger.info("ht(H) = " + H.monic()); //.leadingExpVector() ); 135 } 136 if ( H.isZERO() ) { 137 pair.setZero(); 138 continue; 139 } 140 H = H.monic(); 141 if ( debug ) { 142 logger.info("ht(H) = " + H.leadingExpVector() ); 143 } 144 145 H = H.monic(); 146 if ( H.isONE() ) { 147 G.clear(); G.add( H ); 148 return G; // since no threads are activated 149 } 150 if ( debug ) { 151 logger.info("H = " + H ); 152 } 153 if ( H.length() > 0 ) { 154 l++; 155 G.add( H ); 156 pairlist.put( H ); 157 } 158 } 159 logger.debug("#sequential list = "+G.size()); 160 G = minimalGB(G); 161 logger.info("" + pairlist); 162 return G; 163 } 164 165 166 /** 167 * Extended Groebner base using critical pair class. 168 * @param modv module variable number. 169 * @param F polynomial list. 170 * @return a container for an extended Groebner base of F. 171 */ 172 @Override 173 public ExtendedGB<C> 174 extGB( int modv, 175 List<GenPolynomial<C>> F ) { 176 List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>(); 177 List<List<GenPolynomial<C>>> F2G = new ArrayList<List<GenPolynomial<C>>>(); 178 List<List<GenPolynomial<C>>> G2F = new ArrayList<List<GenPolynomial<C>>>(); 179 PairList<C> pairlist = null; 180 boolean oneInGB = false; 181 int len = F.size(); 182 183 List<GenPolynomial<C>> row = null; 184 List<GenPolynomial<C>> rows = null; 185 List<GenPolynomial<C>> rowh = null; 186 GenPolynomialRing<C> ring = null; 187 GenPolynomial<C> H; 188 GenPolynomial<C> p; 189 190 int nzlen = 0; 191 for ( GenPolynomial<C> f : F ) { 192 if ( f.length() > 0 ) { 193 nzlen++; 194 } 195 if ( ring == null ) { 196 ring = f.ring; 197 } 198 } 199 GenPolynomial<C> mone = ring.getONE(); //.negate(); 200 int k = 0; 201 ListIterator<GenPolynomial<C>> it = F.listIterator(); 202 while ( it.hasNext() ) { 203 p = it.next(); 204 if ( p.length() > 0 ) { 205 row = new ArrayList<GenPolynomial<C>>( nzlen ); 206 for ( int j = 0; j < nzlen; j++ ) { 207 row.add(null); 208 } 209 //C c = p.leadingBaseCoefficient(); 210 //c = c.inverse(); 211 //p = p.multiply( c ); 212 row.set( k, mone ); //.multiply(c) ); 213 k++; 214 if ( p.isUnit() ) { 215 G.clear(); G.add( p ); 216 G2F.clear(); G2F.add( row ); 217 oneInGB = true; 218 break; 219 } 220 G.add( p ); 221 G2F.add( row ); 222 if ( pairlist == null ) { 223 //pairlist = new OrderedPairlist<C>( modv, p.ring ); 224 pairlist = strategy.create( modv, p.ring ); 225 if ( ! p.ring.coFac.isField() ) { 226 throw new RuntimeException("coefficients not from a field"); 227 } 228 } 229 // putOne not required 230 pairlist.put( p ); 231 } else { 232 len--; 233 } 234 } 235 ExtendedGB<C> exgb; 236 if ( len <= 1 || oneInGB ) { 237 // adjust F2G 238 for ( GenPolynomial<C> f : F ) { 239 row = new ArrayList<GenPolynomial<C>>( G.size() ); 240 for ( int j = 0; j < G.size(); j++ ) { 241 row.add(null); 242 } 243 H = red.normalform( row, G, f ); 244 if ( ! H.isZERO() ) { 245 logger.error("nonzero H = " + H ); 246 } 247 F2G.add( row ); 248 } 249 exgb = new ExtendedGB<C>(F,G,F2G,G2F); 250 //System.out.println("exgb 1 = " + exgb); 251 return exgb; 252 } 253 254 Pair<C> pair; 255 int i, j; 256 GenPolynomial<C> pi; 257 GenPolynomial<C> pj; 258 GenPolynomial<C> S; 259 GenPolynomial<C> x; 260 GenPolynomial<C> y; 261 //GenPolynomial<C> z; 262 while ( pairlist.hasNext() && ! oneInGB ) { 263 pair = pairlist.removeNext(); 264 if ( pair == null ) { 265 continue; 266 } 267 i = pair.i; 268 j = pair.j; 269 pi = pair.pi; 270 pj = pair.pj; 271 if ( debug ) { 272 logger.info("i, pi = " + i + ", " + pi ); 273 logger.info("j, pj = " + j + ", " + pj ); 274 } 275 276 rows = new ArrayList<GenPolynomial<C>>( G.size() ); 277 for ( int m = 0; m < G.size(); m++ ) { 278 rows.add(null); 279 } 280 S = red.SPolynomial( rows, i, pi, j, pj ); 281 if ( debug ) { 282 logger.debug("is reduction S = " 283 + red.isReductionNF( rows, G, ring.getZERO(), S ) ); 284 } 285 if ( S.isZERO() ) { 286 // do not add to G2F 287 continue; 288 } 289 if ( debug ) { 290 logger.debug("ht(S) = " + S.leadingExpVector() ); 291 } 292 293 rowh = new ArrayList<GenPolynomial<C>>( G.size() ); 294 for ( int m = 0; m < G.size(); m++ ) { 295 rowh.add(null); 296 } 297 H = red.normalform( rowh, G, S ); 298 if ( debug ) { 299 logger.debug("is reduction H = " 300 + red.isReductionNF( rowh, G, S, H ) ); 301 } 302 if ( H.isZERO() ) { 303 // do not add to G2F 304 continue; 305 } 306 if ( debug ) { 307 logger.debug("ht(H) = " + H.leadingExpVector() ); 308 } 309 310 row = new ArrayList<GenPolynomial<C>>( G.size()+1 ); 311 for ( int m = 0; m < G.size(); m++ ) { 312 x = rows.get(m); 313 if ( x != null ) { 314 //System.out.println("ms = " + m + " " + x); 315 x = x.negate(); 316 } 317 y = rowh.get(m); 318 if ( y != null ) { 319 y = y.negate(); 320 //System.out.println("mh = " + m + " " + y); 321 } 322 if ( x == null ) { 323 x = y; 324 } else { 325 x = x.sum( y ); 326 } 327 //System.out.println("mx = " + m + " " + x); 328 row.add( x ); 329 } 330 if ( debug ) { 331 logger.debug("is reduction 0+sum(row,G) == H : " 332 + red.isReductionNF( row, G, H, ring.getZERO() ) ); 333 } 334 row.add( null ); 335 336 337 // H = H.monic(); 338 C c = H.leadingBaseCoefficient(); 339 c = c.inverse(); 340 H = H.multiply( c ); 341 row = blas.scalarProduct( mone.multiply(c), row ); 342 row.set( G.size(), mone ); 343 if ( H.isONE() ) { 344 // G.clear(); 345 G.add( H ); 346 G2F.add( row ); 347 oneInGB = true; 348 break; 349 } 350 if ( debug ) { 351 logger.debug("H = " + H ); 352 } 353 G.add( H ); 354 pairlist.put( H ); 355 G2F.add( row ); 356 } 357 if ( debug ) { 358 exgb = new ExtendedGB<C>(F,G,F2G,G2F); 359 logger.info("exgb unnorm = " + exgb); 360 } 361 G2F = normalizeMatrix( F.size(), G2F ); 362 if ( debug ) { 363 exgb = new ExtendedGB<C>(F,G,F2G,G2F); 364 logger.info("exgb nonmin = " + exgb); 365 boolean t2 = isReductionMatrix( exgb ); 366 logger.info("exgb t2 = " + t2); 367 } 368 exgb = minimalExtendedGB(F.size(),G,G2F); 369 G = exgb.G; 370 G2F = exgb.G2F; 371 logger.debug("#sequential list = " + G.size()); 372 logger.info("" + pairlist); 373 // setup matrices F and F2G 374 for ( GenPolynomial<C> f : F ) { 375 row = new ArrayList<GenPolynomial<C>>( G.size() ); 376 for ( int m = 0; m < G.size(); m++ ) { 377 row.add(null); 378 } 379 H = red.normalform( row, G, f ); 380 if ( ! H.isZERO() ) { 381 logger.error("nonzero H = " + H ); 382 } 383 F2G.add( row ); 384 } 385 exgb = new ExtendedGB<C>(F,G,F2G,G2F); 386 if ( debug ) { 387 logger.info("exgb nonmin = " + exgb); 388 boolean t2 = isReductionMatrix( exgb ); 389 logger.info("exgb t2 = " + t2); 390 } 391 return exgb; 392 } 393 394 }