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