001/* 002 * $Id: GroebnerBasePseudoRecSeq.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.GroebnerBaseAbstract; 015import edu.jas.gb.OrderedPairlist; 016import edu.jas.gb.Pair; 017import edu.jas.gb.PairList; 018import edu.jas.poly.ExpVector; 019import edu.jas.poly.GenPolynomial; 020import edu.jas.poly.GenPolynomialRing; 021import edu.jas.structure.GcdRingElem; 022import edu.jas.structure.RingFactory; 023import edu.jas.ufd.GCDFactory; 024import edu.jas.ufd.GreatestCommonDivisorAbstract; 025 026 027/** 028 * Groebner Base with pseudo reduction sequential algorithm for integral 029 * function coefficients. Implements polynomial fraction free coefficients 030 * Groebner bases. Coefficients can for example be 031 * (commutative) multivariate polynomials. 032 * @param <C> base coefficient type 033 * @author Heinz Kredel 034 * 035 * @see edu.jas.application.GBAlgorithmBuilder 036 * @see edu.jas.gbufd.GBFactory 037 */ 038 039public class GroebnerBasePseudoRecSeq<C extends GcdRingElem<C>> extends 040 GroebnerBaseAbstract<GenPolynomial<C>> { 041 042 043 private static final Logger logger = Logger.getLogger(GroebnerBasePseudoRecSeq.class); 044 045 046 private static final boolean debug = logger.isDebugEnabled(); 047 048 049 /** 050 * Greatest common divisor engine for coefficient content and primitive 051 * parts. 052 */ 053 protected final GreatestCommonDivisorAbstract<C> engine; 054 055 056 /** 057 * Pseudo reduction engine. 058 */ 059 protected final PseudoReduction<C> redRec; 060 061 062 /** 063 * Pseudo reduction engine. 064 */ 065 protected final PseudoReduction<GenPolynomial<C>> red; 066 067 068 /** 069 * Coefficient ring factory. 070 */ 071 protected final RingFactory<GenPolynomial<C>> cofac; 072 073 074 /** 075 * Base coefficient ring factory. 076 */ 077 protected final RingFactory<C> baseCofac; 078 079 080 /** 081 * Constructor. 082 * @param rf coefficient ring factory. 083 */ 084 public GroebnerBasePseudoRecSeq(RingFactory<GenPolynomial<C>> rf) { 085 this(new PseudoReductionSeq<GenPolynomial<C>>(), rf, new OrderedPairlist<GenPolynomial<C>>( 086 new GenPolynomialRing<GenPolynomial<C>>(rf, 1))); // 1=hack 087 } 088 089 090 /** 091 * Constructor. 092 * @param rf coefficient ring factory. 093 * @param pl pair selection strategy 094 */ 095 public GroebnerBasePseudoRecSeq(RingFactory<GenPolynomial<C>> rf, PairList<GenPolynomial<C>> pl) { 096 this(new PseudoReductionSeq<GenPolynomial<C>>(), rf, pl); 097 } 098 099 100 /** 101 * Constructor. 102 * @param red pseudo reduction engine. <b>Note:</b> red must be an instance 103 * of PseudoReductionSeq. 104 * @param rf coefficient ring factory. 105 * @param pl pair selection strategy 106 */ 107 @SuppressWarnings("unchecked") 108 public GroebnerBasePseudoRecSeq(PseudoReduction<GenPolynomial<C>> red, RingFactory<GenPolynomial<C>> rf, 109 PairList<GenPolynomial<C>> pl) { 110 super(red, pl); 111 this.red = red; 112 this.redRec = (PseudoReduction<C>) (PseudoReduction) red; 113 cofac = rf; 114 GenPolynomialRing<C> rp = (GenPolynomialRing<C>) cofac; 115 baseCofac = rp.coFac; 116 //engine = (GreatestCommonDivisorAbstract<C>)GCDFactory.<C>getImplementation( baseCofac ); 117 //not used: 118 engine = GCDFactory.<C> getProxy(baseCofac); 119 } 120 121 122 /** 123 * Groebner base using pairlist class. 124 * @param modv module variable number. 125 * @param F polynomial list. 126 * @return GB(F) a Groebner base of F. 127 */ 128 //@Override 129 public List<GenPolynomial<GenPolynomial<C>>> GB(int modv, List<GenPolynomial<GenPolynomial<C>>> F) { 130 List<GenPolynomial<GenPolynomial<C>>> G = normalizeZerosOnes(F); 131 G = engine.recursivePrimitivePart(G); 132 if (G.size() <= 1) { 133 return G; 134 } 135 GenPolynomialRing<GenPolynomial<C>> ring = G.get(0).ring; 136 if (ring.coFac.isField()) { // remove ? 137 throw new IllegalArgumentException("coefficients from a field"); 138 } 139 PairList<GenPolynomial<C>> pairlist = strategy.create(modv, ring); 140 pairlist.put(G); 141 142 Pair<GenPolynomial<C>> pair; 143 GenPolynomial<GenPolynomial<C>> pi, pj, S, H; 144 while (pairlist.hasNext()) { 145 pair = pairlist.removeNext(); 146 if (pair == null) 147 continue; 148 149 pi = pair.pi; 150 pj = pair.pj; 151 if (debug) { 152 logger.debug("pi = " + pi); 153 logger.debug("pj = " + pj); 154 } 155 156 S = red.SPolynomial(pi, pj); 157 if (S.isZERO()) { 158 pair.setZero(); 159 continue; 160 } 161 if (debug) { 162 logger.info("ht(S) = " + S.leadingExpVector()); 163 } 164 165 H = redRec.normalformRecursive(G, S); 166 if (H.isZERO()) { 167 pair.setZero(); 168 continue; 169 } 170 if (debug) { 171 logger.info("ht(H) = " + H.leadingExpVector()); 172 } 173 H = engine.recursivePrimitivePart(H); 174 H = H.abs(); 175 if (H.isConstant()) { 176 G.clear(); 177 G.add(H); 178 return G; // since no threads are activated 179 } 180 if (debug) { 181 logger.debug("H = " + H); 182 } 183 if (H.length() > 0) { 184 //l++; 185 G.add(H); 186 pairlist.put(H); 187 } 188 } 189 logger.debug("#sequential list = " + G.size()); 190 G = minimalGB(G); 191 logger.info("" + pairlist); 192 return G; 193 } 194 195 196 /** 197 * Minimal ordered Groebner basis. 198 * @param Gp a Groebner base. 199 * @return a reduced Groebner base of Gp. 200 */ 201 @Override 202 public List<GenPolynomial<GenPolynomial<C>>> minimalGB(List<GenPolynomial<GenPolynomial<C>>> Gp) { 203 List<GenPolynomial<GenPolynomial<C>>> G = normalizeZerosOnes(Gp); 204 if (G.size() <= 1) { 205 return G; 206 } 207 // remove top reducible polynomials 208 GenPolynomial<GenPolynomial<C>> a; 209 List<GenPolynomial<GenPolynomial<C>>> F; 210 F = new ArrayList<GenPolynomial<GenPolynomial<C>>>(G.size()); 211 while (G.size() > 0) { 212 a = G.remove(0); 213 if (red.isTopReducible(G, a) || red.isTopReducible(F, a)) { 214 // drop polynomial 215 if (debug) { 216 System.out.println("dropped " + a); 217 List<GenPolynomial<GenPolynomial<C>>> ff; 218 ff = new ArrayList<GenPolynomial<GenPolynomial<C>>>(G); 219 ff.addAll(F); 220 a = redRec.normalformRecursive(ff, a); 221 if (!a.isZERO()) { 222 System.out.println("error, nf(a) " + a); 223 } 224 } 225 } else { 226 F.add(a); 227 } 228 } 229 G = F; 230 if (G.size() <= 1) { 231 return G; 232 } 233 Collections.reverse(G); // important for lex GB 234 // reduce remaining polynomials 235 int len = G.size(); 236 int i = 0; 237 while (i < len) { 238 a = G.remove(0); 239 //System.out.println("doing " + a.length()); 240 a = redRec.normalformRecursive(G, a); 241 a = engine.recursivePrimitivePart(a); //a.monic(); was not required 242 a = a.abs(); 243 //a = redRec.normalformRecursive( F, a ); 244 G.add(a); // adds as last 245 i++; 246 } 247 Collections.reverse(G); // undo reverse 248 return G; 249 } 250 251 252 /** 253 * Groebner base simple test. 254 * @param modv module variable number. 255 * @param F recursive polynomial list. 256 * @return true, if F is a Groebner base, else false. 257 */ 258 @Override 259 public boolean isGBsimple(int modv, List<GenPolynomial<GenPolynomial<C>>> F) { 260 if (F == null || F.isEmpty()) { 261 return true; 262 } 263 GenPolynomial<GenPolynomial<C>> pi, pj, s, h; 264 ExpVector ei, ej, eij; 265 for (int i = 0; i < F.size(); i++) { 266 pi = F.get(i); 267 ei = pi.leadingExpVector(); 268 for (int j = i + 1; j < F.size(); j++) { 269 pj = F.get(j); 270 ej = pj.leadingExpVector(); 271 if (!red.moduleCriterion(modv, ei, ej)) { 272 continue; 273 } 274 eij = ei.lcm(ej); 275 if (!red.criterion4(ei, ej, eij)) { 276 continue; 277 } 278 //if (!criterion3(i, j, eij, F)) { 279 // continue; 280 //} 281 s = red.SPolynomial(pi, pj); 282 if (s.isZERO()) { 283 continue; 284 } 285 //System.out.println("i, j = " + i + ", " + j); 286 h = redRec.normalformRecursive(F, s); 287 if (!h.isZERO()) { 288 logger.info("no GB: pi = " + pi + ", pj = " + pj); 289 logger.info("s = " + s + ", h = " + h); 290 return false; 291 } 292 } 293 } 294 return true; 295 } 296 297}