001/* 002 * $Id: SolvableGroebnerBasePseudoSeq.java 5841 2018-05-20 21:26:13Z kredel $ 003 */ 004 005package edu.jas.gbufd; 006 007 008import java.util.ArrayList; 009import java.util.Collections; 010import java.util.List; 011 012import org.apache.log4j.Logger; 013 014import edu.jas.gb.OrderedPairlist; 015import edu.jas.gb.Pair; 016import edu.jas.gb.PairList; 017import edu.jas.gb.SolvableExtendedGB; 018import edu.jas.gb.SolvableGroebnerBaseAbstract; 019import edu.jas.poly.GenSolvablePolynomial; 020import edu.jas.poly.GenSolvablePolynomialRing; 021// import edu.jas.poly.GenPolynomialRing; 022import edu.jas.poly.PolynomialList; 023import edu.jas.structure.GcdRingElem; 024import edu.jas.structure.RingFactory; 025import edu.jas.ufd.GCDFactory; 026import edu.jas.ufd.GreatestCommonDivisorAbstract; 027import edu.jas.ufd.GreatestCommonDivisorFake; 028 029 030/** 031 * Solvable Groebner Base with pseudo reduction sequential algorithm. Implements 032 * coefficient fraction free Groebner bases. Coefficients can for example be 033 * integers or (commutative) univariate polynomials. 034 * @param <C> coefficient type 035 * @author Heinz Kredel 036 * 037 * @see edu.jas.application.GBAlgorithmBuilder 038 * @see edu.jas.gbufd.GBFactory 039 */ 040 041public class SolvableGroebnerBasePseudoSeq<C extends GcdRingElem<C>> extends SolvableGroebnerBaseAbstract<C> { 042 043 044 private static final Logger logger = Logger.getLogger(SolvableGroebnerBasePseudoSeq.class); 045 046 047 private static final boolean debug = logger.isDebugEnabled(); 048 049 050 /** 051 * Greatest common divisor engine for coefficient content and primitive 052 * parts. 053 */ 054 protected final GreatestCommonDivisorAbstract<C> engine; 055 056 057 /** 058 * Pseudo reduction engine. 059 */ 060 protected final SolvablePseudoReduction<C> sred; 061 062 063 /** 064 * Coefficient ring factory. 065 */ 066 protected final RingFactory<C> cofac; 067 068 069 /** 070 * Constructor. 071 * @param rf coefficient ring factory. 072 */ 073 public SolvableGroebnerBasePseudoSeq(RingFactory<C> rf) { 074 this(new SolvablePseudoReductionSeq<C>(), rf, new OrderedPairlist<C>()); 075 } 076 077 078 /** 079 * Constructor. 080 * @param rf coefficient ring factory. 081 * @param pl pair selection strategy 082 */ 083 public SolvableGroebnerBasePseudoSeq(RingFactory<C> rf, PairList<C> pl) { 084 this(new SolvablePseudoReductionSeq<C>(), rf, pl); 085 } 086 087 088 /** 089 * Constructor. 090 * @param red pseudo reduction engine. <b>Note:</b> red must be an instance 091 * of PseudoReductionSeq. 092 * @param rf coefficient ring factory. 093 * @param pl pair selection strategy 094 */ 095 public SolvableGroebnerBasePseudoSeq(SolvablePseudoReduction<C> red, RingFactory<C> rf, PairList<C> pl) { 096 super(red, pl); 097 this.sred = red; 098 cofac = rf; 099 if (!cofac.isCommutative()) { 100 logger.warn("right reduction not correct for " + cofac.toScript()); 101 engine = new GreatestCommonDivisorFake<C>(); // only for Ore conditions 102 // TODO check that also coeffTable is empty for recursive solvable poly ring 103 //System.out.println("stack trace = "); 104 //Exception e = new RuntimeException("get stack trace"); 105 //e.printStackTrace(); 106 } else { 107 //engine = GCDFactory.<C> getImplementation(rf); 108 engine = GCDFactory.<C> getProxy(rf); 109 } 110 } 111 112 113 /** 114 * Left Groebner base using pairlist class. 115 * @param modv module variable number. 116 * @param F polynomial list. 117 * @return GB(F) a Groebner base of F. 118 */ 119 @Override 120 public List<GenSolvablePolynomial<C>> leftGB(int modv, List<GenSolvablePolynomial<C>> F) { 121 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(F); 122 G = PolynomialList.<C> castToSolvableList(engine.basePrimitivePart(PolynomialList.<C> castToList(G))); 123 if (G.size() <= 1) { 124 return G; 125 } 126 GenSolvablePolynomialRing<C> ring = G.get(0).ring; 127 if (ring.coFac.isField()) { // remove ? 128 throw new IllegalArgumentException("coefficients from a field"); 129 } 130 PairList<C> pairlist = strategy.create(modv, ring); 131 pairlist.put(PolynomialList.<C> castToList(G)); 132 133 Pair<C> pair; 134 GenSolvablePolynomial<C> pi, pj, S, H; 135 while (pairlist.hasNext()) { 136 pair = pairlist.removeNext(); 137 if (pair == null) 138 continue; 139 140 pi = (GenSolvablePolynomial<C>) pair.pi; 141 pj = (GenSolvablePolynomial<C>) pair.pj; 142 if (debug) { 143 logger.debug("pi = " + pi); 144 logger.debug("pj = " + pj); 145 } 146 147 S = sred.leftSPolynomial(pi, pj); 148 if (S.isZERO()) { 149 pair.setZero(); 150 continue; 151 } 152 if (debug) { 153 logger.debug("ht(S) = " + S.leadingExpVector()); 154 } 155 156 H = sred.leftNormalform(G, S); 157 if (H.isZERO()) { 158 pair.setZero(); 159 continue; 160 } 161 if (debug) { 162 logger.debug("ht(H) = " + H.leadingExpVector()); 163 } 164 H = (GenSolvablePolynomial<C>) engine.basePrimitivePart(H); 165 H = (GenSolvablePolynomial<C>) H.abs(); 166 if (H.isConstant()) { 167 G.clear(); 168 G.add(H); 169 return G; // since no threads are activated 170 } 171 if (logger.isDebugEnabled()) { 172 logger.debug("H = " + H); 173 } 174 if (H.length() > 0) { 175 G.add(H); 176 pairlist.put(H); 177 } 178 } 179 logger.debug("#sequential list = " + G.size()); 180 G = leftMinimalGB(G); 181 logger.info("" + pairlist); 182 return G; 183 } 184 185 186 /** 187 * Minimal ordered Solvable Groebner basis. 188 * @param Gp a Solvable Groebner base. 189 * @return a reduced Solvable Groebner base of Gp. 190 */ 191 @Override 192 public List<GenSolvablePolynomial<C>> leftMinimalGB(List<GenSolvablePolynomial<C>> Gp) { 193 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(Gp); 194 if (G.size() <= 1) { 195 return G; 196 } 197 // remove top reducible polynomials 198 GenSolvablePolynomial<C> a; 199 List<GenSolvablePolynomial<C>> F = new ArrayList<GenSolvablePolynomial<C>>(G.size()); 200 while (G.size() > 0) { 201 a = G.remove(0); 202 if (sred.isTopReducible(G, a) || sred.isTopReducible(F, a)) { 203 // drop polynomial 204 if (debug) { 205 System.out.println("dropped " + a); 206 List<GenSolvablePolynomial<C>> ff; 207 ff = new ArrayList<GenSolvablePolynomial<C>>(G); 208 ff.addAll(F); 209 a = sred.leftNormalform(ff, a); 210 if (!a.isZERO()) { 211 System.out.println("error, nf(a) " + a); 212 } 213 } 214 } else { 215 F.add(a); 216 } 217 } 218 G = F; 219 if (G.size() <= 1) { 220 return G; 221 } 222 Collections.reverse(G); // important for lex GB 223 // reduce remaining polynomials 224 int len = G.size(); 225 int i = 0; 226 while (i < len) { 227 a = G.remove(0); 228 //System.out.println("doing " + a.length()); 229 a = sred.leftNormalform(G, a); 230 a = (GenSolvablePolynomial<C>) engine.basePrimitivePart(a); //a.monic(); not possible 231 a = (GenSolvablePolynomial<C>) a.abs(); 232 //a = sred.normalform( F, a ); 233 G.add(a); // adds as last 234 i++; 235 } 236 return G; 237 } 238 239 240 /** 241 * Twosided Solvable Groebner base using pairlist class. 242 * @param modv number of module variables. 243 * @param Fp solvable polynomial list. 244 * @return tsGB(Fp) a twosided Groebner base of Fp. 245 */ 246 @Override 247 public List<GenSolvablePolynomial<C>> twosidedGB(int modv, List<GenSolvablePolynomial<C>> Fp) { 248 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(Fp); 249 G = PolynomialList.<C> castToSolvableList(engine.basePrimitivePart(PolynomialList.<C> castToList(G))); 250 if (G.size() < 1) { // two-sided! 251 return G; 252 } 253 //System.out.println("G = " + G); 254 GenSolvablePolynomialRing<C> ring = G.get(0).ring; // assert != null 255 if (ring.coFac.isField()) { // remove ? 256 throw new IllegalArgumentException("coefficients from a field"); 257 } 258 // add also coefficient generators 259 List<GenSolvablePolynomial<C>> X; 260 X = PolynomialList.castToSolvableList(ring.generators(modv)); 261 logger.info("right multipliers = " + X); 262 List<GenSolvablePolynomial<C>> F = new ArrayList<GenSolvablePolynomial<C>>(G.size() * (1 + X.size())); 263 F.addAll(G); 264 logger.info("right multipy: F = " + F); 265 GenSolvablePolynomial<C> p, x, q; 266 for (int i = 0; i < F.size(); i++) { // F changes 267 p = F.get(i); 268 for (int j = 0; j < X.size(); j++) { 269 x = X.get(j); 270 q = p.multiply(x); 271 logger.info("right multipy: p = " + p + ", x = " + x + ", q = " + q); 272 q = sred.leftNormalform(F, q); 273 if (!q.isZERO()) { 274 q = (GenSolvablePolynomial<C>) engine.basePrimitivePart(q); 275 q = (GenSolvablePolynomial<C>) q.abs(); 276 logger.info("right multipy: red(q) = " + q); 277 F.add(q); 278 } 279 } 280 } 281 G = F; 282 //System.out.println("G generated = " + G); 283 PairList<C> pairlist = strategy.create(modv, ring); 284 pairlist.put(PolynomialList.<C> castToList(G)); 285 286 Pair<C> pair; 287 GenSolvablePolynomial<C> pi, pj, S, H; 288 while (pairlist.hasNext()) { 289 pair = pairlist.removeNext(); 290 if (pair == null) { 291 continue; 292 } 293 294 pi = (GenSolvablePolynomial<C>) pair.pi; 295 pj = (GenSolvablePolynomial<C>) pair.pj; 296 if (debug) { 297 logger.debug("pi = " + pi); 298 logger.debug("pj = " + pj); 299 } 300 301 S = sred.leftSPolynomial(pi, pj); 302 if (S.isZERO()) { 303 pair.setZero(); 304 continue; 305 } 306 if (debug) { 307 logger.debug("ht(S) = " + S.leadingExpVector()); 308 } 309 310 H = sred.leftNormalform(G, S); 311 if (H.isZERO()) { 312 pair.setZero(); 313 continue; 314 } 315 if (debug) { 316 logger.debug("ht(H) = " + H.leadingExpVector()); 317 } 318 319 H = (GenSolvablePolynomial<C>) engine.basePrimitivePart(H); 320 H = (GenSolvablePolynomial<C>) H.abs(); 321 if (H.isONE()) { 322 G.clear(); 323 G.add(H); 324 return G; // since no threads are activated 325 } 326 if (debug) { 327 logger.debug("H = " + H); 328 } 329 if (H.length() > 0) { 330 G.add(H); 331 pairlist.put(H); 332 for (int j = 0; j < X.size(); j++) { 333 x = X.get(j); 334 p = H.multiply(x); 335 p = sred.leftNormalform(G, p); 336 if (!p.isZERO()) { 337 p = (GenSolvablePolynomial<C>) engine.basePrimitivePart(p); 338 p = (GenSolvablePolynomial<C>) p.abs(); 339 if (p.isONE()) { 340 G.clear(); 341 G.add(p); 342 return G; // since no threads are activated 343 } 344 G.add(p); 345 pairlist.put(p); 346 } 347 } 348 } 349 } 350 logger.debug("#sequential list = " + G.size()); 351 G = leftMinimalGB(G); 352 logger.info("" + pairlist); 353 return G; 354 } 355 356 357 /** 358 * Solvable Extended Groebner base using critical pair class. 359 * @param modv module variable number. 360 * @param F solvable polynomial list. 361 * @return a container for an extended left Groebner base of F. <b>Note: 362 * </b> not implemented; 363 */ 364 //@SuppressWarnings("unchecked") 365 @Override 366 public SolvableExtendedGB<C> extLeftGB(int modv, List<GenSolvablePolynomial<C>> F) { 367 throw new UnsupportedOperationException(); // TODO 368 } 369 370}