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