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