001/* 002 * $Id$ 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 logger.debug("ht(S) = {}", S.leadingExpVector()); 154 155 H = sred.leftNormalform(G, S); 156 if (H.isZERO()) { 157 pair.setZero(); 158 continue; 159 } 160 logger.debug("ht(H) = {}", H.leadingExpVector()); 161 H = (GenSolvablePolynomial<C>) engine.basePrimitivePart(H); 162 H = (GenSolvablePolynomial<C>) H.abs(); 163 if (H.isConstant()) { 164 G.clear(); 165 G.add(H); 166 return G; // since no threads are activated 167 } 168 logger.debug("H = {}", H); 169 if (H.length() > 0) { 170 G.add(H); 171 pairlist.put(H); 172 } 173 } 174 logger.debug("#sequential list = {}", G.size()); 175 G = leftMinimalGB(G); 176 logger.info("{}", pairlist); 177 return G; 178 } 179 180 181 /** 182 * Minimal ordered Solvable Groebner basis. 183 * @param Gp a Solvable Groebner base. 184 * @return a reduced Solvable Groebner base of Gp. 185 */ 186 @Override 187 public List<GenSolvablePolynomial<C>> leftMinimalGB(List<GenSolvablePolynomial<C>> Gp) { 188 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(Gp); 189 if (G.size() <= 1) { 190 return G; 191 } 192 // remove top reducible polynomials 193 GenSolvablePolynomial<C> a; 194 List<GenSolvablePolynomial<C>> F = new ArrayList<GenSolvablePolynomial<C>>(G.size()); 195 while (G.size() > 0) { 196 a = G.remove(0); 197 if (sred.isTopReducible(G, a) || sred.isTopReducible(F, a)) { 198 // drop polynomial 199 if (debug) { 200 System.out.println("dropped " + a); 201 List<GenSolvablePolynomial<C>> ff; 202 ff = new ArrayList<GenSolvablePolynomial<C>>(G); 203 ff.addAll(F); 204 a = sred.leftNormalform(ff, a); 205 if (!a.isZERO()) { 206 System.out.println("error, nf(a) " + a); 207 } 208 } 209 } else { 210 F.add(a); 211 } 212 } 213 G = F; 214 if (G.size() <= 1) { 215 return G; 216 } 217 Collections.reverse(G); // important for lex GB 218 // reduce remaining polynomials 219 int len = G.size(); 220 int i = 0; 221 while (i < len) { 222 a = G.remove(0); 223 //System.out.println("doing " + a.length()); 224 a = sred.leftNormalform(G, a); 225 a = (GenSolvablePolynomial<C>) engine.basePrimitivePart(a); //a.monic(); not possible 226 a = (GenSolvablePolynomial<C>) a.abs(); 227 //a = sred.normalform( F, a ); 228 G.add(a); // adds as last 229 i++; 230 } 231 return G; 232 } 233 234 235 /** 236 * Twosided Solvable Groebner base using pairlist class. 237 * @param modv number of module variables. 238 * @param Fp solvable polynomial list. 239 * @return tsGB(Fp) a twosided Groebner base of Fp. 240 */ 241 @Override 242 public List<GenSolvablePolynomial<C>> twosidedGB(int modv, List<GenSolvablePolynomial<C>> Fp) { 243 List<GenSolvablePolynomial<C>> G = normalizeZerosOnes(Fp); 244 G = PolynomialList.<C> castToSolvableList(engine.basePrimitivePart(PolynomialList.<C> castToList(G))); 245 if (G.size() < 1) { // two-sided! 246 return G; 247 } 248 //System.out.println("G = " + G); 249 GenSolvablePolynomialRing<C> ring = G.get(0).ring; // assert != null 250 if (ring.coFac.isField()) { // remove ? 251 throw new IllegalArgumentException("coefficients from a field"); 252 } 253 // add also coefficient generators 254 List<GenSolvablePolynomial<C>> X; 255 X = PolynomialList.castToSolvableList(ring.generators(modv)); 256 logger.info("right multipliers = {}", X); 257 List<GenSolvablePolynomial<C>> F = new ArrayList<GenSolvablePolynomial<C>>(G.size() * (1 + X.size())); 258 F.addAll(G); 259 logger.info("right multipy: F = {}", F); 260 GenSolvablePolynomial<C> p, x, q; 261 for (int i = 0; i < F.size(); i++) { // F changes 262 p = F.get(i); 263 for (int j = 0; j < X.size(); j++) { 264 x = X.get(j); 265 q = p.multiply(x); 266 logger.info("right multipy: p = {}, x = {}, q = {}", p, x, q); 267 q = sred.leftNormalform(F, q); 268 if (!q.isZERO()) { 269 q = (GenSolvablePolynomial<C>) engine.basePrimitivePart(q); 270 q = (GenSolvablePolynomial<C>) q.abs(); 271 logger.info("right multipy: red(q) = {}", q); 272 F.add(q); 273 } 274 } 275 } 276 G = F; 277 //System.out.println("G generated = " + G); 278 PairList<C> pairlist = strategy.create(modv, ring); 279 pairlist.put(PolynomialList.<C> castToList(G)); 280 281 Pair<C> pair; 282 GenSolvablePolynomial<C> pi, pj, S, H; 283 while (pairlist.hasNext()) { 284 pair = pairlist.removeNext(); 285 if (pair == null) { 286 continue; 287 } 288 289 pi = (GenSolvablePolynomial<C>) pair.pi; 290 pj = (GenSolvablePolynomial<C>) pair.pj; 291 if (debug) { 292 logger.debug("pi = {}", pi); 293 logger.debug("pj = {}", pj); 294 } 295 296 S = sred.leftSPolynomial(pi, pj); 297 if (S.isZERO()) { 298 pair.setZero(); 299 continue; 300 } 301 logger.debug("ht(S) = {}", S.leadingExpVector()); 302 303 H = sred.leftNormalform(G, S); 304 if (H.isZERO()) { 305 pair.setZero(); 306 continue; 307 } 308 logger.debug("ht(H) = {}", H.leadingExpVector()); 309 310 H = (GenSolvablePolynomial<C>) engine.basePrimitivePart(H); 311 H = (GenSolvablePolynomial<C>) H.abs(); 312 if (H.isONE()) { 313 G.clear(); 314 G.add(H); 315 return G; // since no threads are activated 316 } 317 logger.debug("H = {}", H); 318 if (H.length() > 0) { 319 G.add(H); 320 pairlist.put(H); 321 for (int j = 0; j < X.size(); j++) { 322 x = X.get(j); 323 p = H.multiply(x); 324 p = sred.leftNormalform(G, p); 325 if (!p.isZERO()) { 326 p = (GenSolvablePolynomial<C>) engine.basePrimitivePart(p); 327 p = (GenSolvablePolynomial<C>) p.abs(); 328 if (p.isONE()) { 329 G.clear(); 330 G.add(p); 331 return G; // since no threads are activated 332 } 333 G.add(p); 334 pairlist.put(p); 335 } 336 } 337 } 338 } 339 logger.debug("#sequential list = {}", G.size()); 340 G = leftMinimalGB(G); 341 logger.info("{}", pairlist); 342 return G; 343 } 344 345 346 /** 347 * Solvable Extended Groebner base using critical pair class. 348 * @param modv module variable number. 349 * @param F solvable polynomial list. 350 * @return a container for an extended left Groebner base of F. <b>Note: 351 * </b> not implemented; 352 */ 353 //@SuppressWarnings("unchecked") 354 @Override 355 public SolvableExtendedGB<C> extLeftGB(int modv, List<GenSolvablePolynomial<C>> F) { 356 throw new UnsupportedOperationException(); // TODO 357 } 358 359}