001 /* 002 * $Id: StandardBaseSeq.java 3349 2010-10-15 20:54:27Z kredel $ 003 */ 004 005 package edu.jas.ps; 006 007 008 import java.util.ArrayList; 009 import java.util.List; 010 import java.util.ListIterator; 011 012 import org.apache.log4j.Logger; 013 014 import edu.jas.structure.RingElem; 015 import edu.jas.poly.ExpVector; 016 017 018 /** 019 * Standard Base sequential algorithm. Implements Standard bases and GB test. 020 * <b>Note: </b> Currently the term order is fixed to the order defined by the 021 * iterator over exponent vectors <code>ExpVectorIterator</code>. 022 * @param <C> coefficient type 023 * @author Heinz Kredel 024 */ 025 026 public class StandardBaseSeq<C extends RingElem<C>> 027 /*todo: extends StandardBaseAbstract<C>*/{ 028 029 030 private static final Logger logger = Logger.getLogger(StandardBaseSeq.class); 031 032 033 private final boolean debug = logger.isDebugEnabled(); 034 035 036 /** 037 * Reduction engine. 038 */ 039 public final ReductionSeq<C> red; 040 041 042 /** 043 * Constructor. 044 */ 045 public StandardBaseSeq() { 046 //super(); 047 this(new ReductionSeq<C>()); 048 } 049 050 051 /** 052 * Constructor. 053 * @param red Reduction engine 054 */ 055 public StandardBaseSeq(ReductionSeq<C> red) { 056 this.red = red; //super(red); 057 } 058 059 060 /** 061 * Standard base test. 062 * @param F power series list. 063 * @return true, if F is a Standard base, else false. 064 */ 065 public boolean isSTD(List<MultiVarPowerSeries<C>> F) { 066 return isSTD(0, F); 067 } 068 069 070 /** 071 * Standard base test. 072 * @param modv module variable number. 073 * @param F power series list. 074 * @return true, if F is a Standard base, else false. 075 */ 076 public boolean isSTD(int modv, List<MultiVarPowerSeries<C>> F) { 077 if (F == null) { 078 return true; 079 } 080 MultiVarPowerSeries<C> pi, pj, s, h; 081 for (int i = 0; i < F.size(); i++) { 082 pi = F.get(i); 083 for (int j = i + 1; j < F.size(); j++) { 084 pj = F.get(j); 085 if (!red.moduleCriterion(modv, pi, pj)) { 086 continue; 087 } 088 // if ( ! red.criterion4( pi, pj ) ) { 089 // continue; 090 // } 091 s = red.SPolynomial(pi, pj); 092 if (s.isZERO()) { 093 continue; 094 } 095 h = red.normalform(F, s); 096 if (!h.isZERO()) { 097 System.out.println("pi = " + pi + ", pj = " + pj); 098 System.out.println("s = " + s + ", h = " + h); 099 return false; 100 } 101 } 102 } 103 return true; 104 } 105 106 107 /** 108 * Standard base using pairlist class. 109 * @param F power series list. 110 * @return STD(F) a Standard base of F. 111 */ 112 public List<MultiVarPowerSeries<C>> STD(List<MultiVarPowerSeries<C>> F) { 113 return STD(0, F); 114 } 115 116 117 /** 118 * Standard base using pairlist class. 119 * @param modv module variable number. 120 * @param F power series list. 121 * @return STD(F) a Standard base of F. 122 */ 123 public List<MultiVarPowerSeries<C>> STD(int modv, List<MultiVarPowerSeries<C>> F) { 124 MultiVarPowerSeries<C> p = null; 125 List<MultiVarPowerSeries<C>> G = new ArrayList<MultiVarPowerSeries<C>>(); 126 OrderedPairlist<C> pairlist = null; 127 int l = F.size(); 128 ListIterator<MultiVarPowerSeries<C>> it = F.listIterator(); 129 while (it.hasNext()) { 130 p = it.next(); 131 if (!p.isZERO()) { 132 //p = p.monic(); 133 if (p.isUnit()) { 134 G.clear(); 135 G.add(p); 136 return G; // since no threads are activated 137 } 138 G.add(p); 139 if (pairlist == null) { 140 pairlist = new OrderedPairlist<C>(modv, p.ring); 141 if (!p.ring.coFac.isField()) { 142 throw new IllegalArgumentException("coefficients not from a field"); 143 } 144 } 145 // putOne not required 146 pairlist.put(p); 147 } else { 148 l--; 149 } 150 } 151 if (l <= 1) { 152 return G; // since no threads are activated 153 } 154 155 Pair<C> pair; 156 MultiVarPowerSeries<C> pi; 157 MultiVarPowerSeries<C> pj; 158 MultiVarPowerSeries<C> S; 159 MultiVarPowerSeries<C> H; 160 while (pairlist.hasNext()) { 161 pair = pairlist.removeNext(); 162 //logger.debug("pair = " + pair); 163 if (pair == null) { 164 continue; 165 } 166 pi = pair.pi; 167 pj = pair.pj; 168 if ( /*false &&*/debug) { 169 logger.debug("pi = " + pi); 170 logger.debug("pj = " + pj); 171 } 172 173 S = red.SPolynomial(pi, pj); 174 //S.setTruncate(p.ring.truncate()); // ?? 175 if (S.isZERO()) { 176 pair.setZero(); 177 continue; 178 } 179 if (logger.isInfoEnabled()) { 180 ExpVector es = S.orderExpVector(); 181 logger.info("ht(S) = " + es.toString(S.ring.vars) + ", " + es); // + ", S = " + S); 182 } 183 184 //long t = System.currentTimeMillis(); 185 H = red.normalform(G, S); 186 if (H.isZERO()) { 187 pair.setZero(); 188 continue; 189 } 190 //t = System.currentTimeMillis() - t; 191 //System.out.println("time = " + t); 192 if (logger.isInfoEnabled()) { 193 ExpVector eh = H.orderExpVector(); 194 logger.info("ht(H) = " + eh.toString(S.ring.vars) + ", " + eh); // + ", coeff(HT(H)) = " + H.coefficient(eh)); 195 } 196 197 //H = H.monic(); 198 if (H.isUnit()) { 199 G.clear(); 200 G.add(H); 201 return G; // since no threads are activated 202 } 203 if (logger.isDebugEnabled()) { 204 logger.info("H = " + H); 205 } 206 //if (!H.isZERO()) { 207 l++; 208 G.add(H); 209 pairlist.put(H); 210 //} 211 } 212 logger.debug("#sequential list = " + G.size()); 213 G = minimalSTD(G); 214 logger.info("" + pairlist); 215 return G; 216 } 217 218 219 /** 220 * Minimal ordered Standard basis. 221 * @param Gp a Standard base. 222 * @return a minimal Standard base of Gp, not auto reduced. 223 */ 224 public List<MultiVarPowerSeries<C>> minimalSTD(List<MultiVarPowerSeries<C>> Gp) { 225 if (Gp == null || Gp.size() <= 1) { 226 return Gp; 227 } 228 // remove zero power series 229 List<MultiVarPowerSeries<C>> G = new ArrayList<MultiVarPowerSeries<C>>(Gp.size()); 230 for (MultiVarPowerSeries<C> a : Gp) { 231 if (a != null && !a.isZERO()) { // always true in GB() 232 // make positive a = a.abs(); ? 233 a = a.monic(); 234 G.add(a); 235 } 236 } 237 if (G.size() <= 1) { 238 return G; 239 } 240 // remove top reducible power series 241 MultiVarPowerSeries<C> a; 242 List<MultiVarPowerSeries<C>> F = new ArrayList<MultiVarPowerSeries<C>>(G.size()); 243 while (G.size() > 0) { 244 a = G.remove(0); 245 if (red.isTopReducible(G, a) || red.isTopReducible(F, a)) { 246 // drop power series 247 if (debug) { 248 System.out.println("dropped " + a); 249 List<MultiVarPowerSeries<C>> ff = new ArrayList<MultiVarPowerSeries<C>>(G); 250 ff.addAll(F); 251 a = red.normalform(ff, a); 252 if (!a.isZERO()) { 253 System.out.println("error, nf(a) " + a); 254 } 255 } 256 } else { 257 F.add(a); 258 } 259 } 260 G = F; 261 // power series not reduced 262 return G; 263 } 264 265 }