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