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