001/* 002 * $Id: GroebnerBasePseudoSeq.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.GenPolynomial; 019import edu.jas.poly.GenPolynomialRing; 020import edu.jas.structure.GcdRingElem; 021import edu.jas.structure.RingFactory; 022import edu.jas.ufd.GCDFactory; 023import edu.jas.ufd.GreatestCommonDivisorAbstract; 024 025 026/** 027 * Groebner Base with pseudo reduction sequential algorithm. Implements 028 * coefficient fraction free Groebner bases. 029 * Coefficients can for example be integers or (commutative) univariate polynomials. 030 * @param <C> coefficient type 031 * @author Heinz Kredel 032 * 033 * @see edu.jas.application.GBAlgorithmBuilder 034 * @see edu.jas.gbufd.GBFactory 035 */ 036 037public class GroebnerBasePseudoSeq<C extends GcdRingElem<C>> extends GroebnerBaseAbstract<C> { 038 039 040 private static final Logger logger = Logger.getLogger(GroebnerBasePseudoSeq.class); 041 042 043 private static final boolean debug = logger.isDebugEnabled(); 044 045 046 /** 047 * Greatest common divisor engine for coefficient content and primitive 048 * parts. 049 */ 050 protected final GreatestCommonDivisorAbstract<C> engine; 051 052 053 /** 054 * Pseudo reduction engine. 055 */ 056 protected final PseudoReduction<C> red; 057 058 059 /** 060 * Coefficient ring factory. 061 */ 062 protected final RingFactory<C> cofac; 063 064 065 /** 066 * Constructor. 067 * @param rf coefficient ring factory. 068 */ 069 public GroebnerBasePseudoSeq(RingFactory<C> rf) { 070 this(new PseudoReductionSeq<C>(), rf, new OrderedPairlist<C>()); 071 } 072 073 074 /** 075 * Constructor. 076 * @param rf coefficient ring factory. 077 * @param pl pair selection strategy 078 */ 079 public GroebnerBasePseudoSeq(RingFactory<C> rf, PairList<C> pl) { 080 this(new PseudoReductionSeq<C>(), rf, pl); 081 } 082 083 084 /** 085 * Constructor. 086 * @param red pseudo reduction engine. <b>Note:</b> red must be an instance 087 * of PseudoReductionSeq. 088 * @param rf coefficient ring factory. 089 * @param pl pair selection strategy 090 */ 091 public GroebnerBasePseudoSeq(PseudoReduction<C> red, RingFactory<C> rf, PairList<C> pl) { 092 super(red, pl); 093 this.red = red; 094 cofac = rf; 095 engine = GCDFactory.<C> getImplementation(rf); 096 //not used: engine = (GreatestCommonDivisorAbstract<C>)GCDFactory.<C>getProxy( rf ); 097 } 098 099 100 /** 101 * Groebner base using pairlist class. 102 * @param modv module variable number. 103 * @param F polynomial list. 104 * @return GB(F) a Groebner base of F. 105 */ 106 public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) { 107 List<GenPolynomial<C>> G = normalizeZerosOnes(F); 108 G = engine.basePrimitivePart(G); 109 if (G.size() <= 1) { 110 return G; 111 } 112 GenPolynomialRing<C> ring = G.get(0).ring; 113 if (ring.coFac.isField()) { // remove ? 114 throw new IllegalArgumentException("coefficients from a field"); 115 } 116 PairList<C> pairlist = strategy.create(modv, ring); 117 pairlist.put(G); 118 119 Pair<C> pair; 120 GenPolynomial<C> pi, pj, S, H; 121 while (pairlist.hasNext()) { 122 pair = pairlist.removeNext(); 123 if (pair == null) 124 continue; 125 126 pi = pair.pi; 127 pj = pair.pj; 128 if (debug) { 129 logger.debug("pi = " + pi); 130 logger.debug("pj = " + pj); 131 } 132 133 S = red.SPolynomial(pi, pj); 134 if (S.isZERO()) { 135 pair.setZero(); 136 continue; 137 } 138 if (debug) { 139 logger.debug("ht(S) = " + S.leadingExpVector()); 140 } 141 142 H = red.normalform(G, S); 143 if (H.isZERO()) { 144 pair.setZero(); 145 continue; 146 } 147 if (debug) { 148 logger.debug("ht(H) = " + H.leadingExpVector()); 149 } 150 H = engine.basePrimitivePart(H); 151 H = H.abs(); 152 if (H.isConstant()) { 153 G.clear(); 154 G.add(H); 155 return G; // since no threads are activated 156 } 157 if (logger.isDebugEnabled()) { 158 logger.debug("H = " + H); 159 } 160 if (H.length() > 0) { 161 //l++; 162 G.add(H); 163 pairlist.put(H); 164 } 165 } 166 logger.debug("#sequential list = " + G.size()); 167 G = minimalGB(G); 168 logger.info("" + pairlist); 169 return G; 170 } 171 172 173 /** 174 * Minimal ordered Groebner basis. 175 * @param Gp a Groebner base. 176 * @return a reduced Groebner base of Gp. 177 */ 178 @Override 179 public List<GenPolynomial<C>> minimalGB(List<GenPolynomial<C>> Gp) { 180 List<GenPolynomial<C>> G = normalizeZerosOnes(Gp); 181 if (G.size() <= 1) { 182 return G; 183 } 184 // remove top reducible polynomials 185 GenPolynomial<C> a; 186 List<GenPolynomial<C>> F; 187 F = new ArrayList<GenPolynomial<C>>(G.size()); 188 while (G.size() > 0) { 189 a = G.remove(0); 190 if (red.isTopReducible(G, a) || red.isTopReducible(F, a)) { 191 // drop polynomial 192 if (debug) { 193 System.out.println("dropped " + a); 194 List<GenPolynomial<C>> ff; 195 ff = new ArrayList<GenPolynomial<C>>(G); 196 ff.addAll(F); 197 a = red.normalform(ff, a); 198 if (!a.isZERO()) { 199 System.out.println("error, nf(a) " + a); 200 } 201 } 202 } else { 203 F.add(a); 204 } 205 } 206 G = F; 207 if (G.size() <= 1) { 208 return G; 209 } 210 Collections.reverse(G); // important for lex GB 211 // reduce remaining polynomials 212 int len = G.size(); 213 int i = 0; 214 while (i < len) { 215 a = G.remove(0); 216 //System.out.println("doing " + a.length()); 217 a = red.normalform(G, a); 218 a = engine.basePrimitivePart(a); //a.monic(); not possible 219 a = a.abs(); 220 //a = red.normalform( F, a ); 221 G.add(a); // adds as last 222 i++; 223 } 224 Collections.reverse(G); // undo reverse 225 return G; 226 } 227 228}