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