001/*
002 * $Id: DGroebnerBaseSeq.java 4948 2014-10-09 22:10:04Z axelclk $
003 */
004
005package edu.jas.gb;
006
007
008import java.util.ArrayList;
009import java.util.List;
010import java.util.ListIterator;
011
012import org.apache.log4j.Logger;
013
014import edu.jas.poly.GenPolynomial;
015import edu.jas.poly.GenPolynomialRing;
016import edu.jas.structure.RingElem;
017
018
019/**
020 * D-Groebner Base sequential algorithm. Implements D-Groebner bases and GB
021 * test. <b>Note:</b> Minimal reduced GBs are not unique. see BWK, section 10.1.
022 * @param <C> coefficient type
023 * @author Heinz Kredel
024 */
025
026public class DGroebnerBaseSeq<C extends RingElem<C>> extends GroebnerBaseAbstract<C> {
027
028
029    private static final Logger logger = Logger.getLogger(DGroebnerBaseSeq.class);
030
031
032    private final boolean debug = logger.isDebugEnabled();
033
034
035    /**
036     * Reduction engine.
037     */
038    protected DReduction<C> dred; // shadow super.red ??
039
040
041    /**
042     * Constructor.
043     */
044    public DGroebnerBaseSeq() {
045        this(new DReductionSeq<C>());
046    }
047
048
049    /**
050     * Constructor.
051     * @param dred D-Reduction engine
052     */
053    public DGroebnerBaseSeq(DReduction<C> dred) {
054        super(dred);
055        this.dred = dred;
056        assert this.dred == super.red;
057    }
058
059
060    /**
061     * D-Groebner base test.
062     * @param modv module variable number.
063     * @param F polynomial list.
064     * @return true, if F is a D-Groebner base, else false.
065     */
066    @Override
067    public boolean isGB(int modv, List<GenPolynomial<C>> F) {
068        GenPolynomial<C> pi, pj, s, d;
069        for (int i = 0; i < F.size(); i++) {
070            pi = F.get(i);
071            for (int j = i + 1; j < F.size(); j++) {
072                pj = F.get(j);
073                if (!red.moduleCriterion(modv, pi, pj)) {
074                    continue;
075                }
076                d = dred.GPolynomial(pi, pj);
077                if (!d.isZERO()) {
078                    // better check for top reduction only
079                    d = red.normalform(F, d);
080                }
081                if (!d.isZERO()) {
082                    System.out.println("d-pol(" + i + "," + j + ") != 0: " + d);
083                    return false;
084                }
085                // works ok
086                if (!red.criterion4(pi, pj)) {
087                    continue;
088                }
089                s = red.SPolynomial(pi, pj);
090                if (!s.isZERO()) {
091                    s = red.normalform(F, s);
092                }
093                if (!s.isZERO()) {
094                    System.out.println("s-pol(" + i + "," + j + ") != 0: " + s);
095                    return false;
096                }
097            }
098        }
099        return true;
100    }
101
102
103    /**
104     * D-Groebner base using pairlist class.
105     * @param modv module variable number.
106     * @param F polynomial list.
107     * @return GB(F) a D-Groebner base of F.
108     */
109    public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) {
110        List<GenPolynomial<C>> G = normalizeZerosOnes(F);
111        if ( G.size() <= 1 ) {
112            return G;
113        }
114        GenPolynomialRing<C> ring = G.get(0).ring;
115        OrderedDPairlist<C> pairlist = new OrderedDPairlist<C>(modv, ring);
116        pairlist.put(G);
117        /*
118          int l = G.size();
119          GenPolynomial<C> p;
120          //new ArrayList<GenPolynomial<C>>();
121          ListIterator<GenPolynomial<C>> it = F.listIterator();
122          while (it.hasNext()) {
123          p = it.next();
124          if (!p.isZERO()) {
125          p = p.abs(); // not monic
126          if (p.isONE()) {
127          G.clear();
128          G.add(p);
129          return G; // since no threads are activated
130          }
131          G.add(p); //G.add( 0, p ); //reverse list
132          if (pairlist == null) {
133          pairlist = new OrderedDPairlist<C>(modv, p.ring);
134          }
135          // putOne not required
136          pairlist.put(p);
137          } else {
138          l--;
139          }
140          }
141          if (l <= 1) {
142          return G; // since no threads are activated
143          }
144        */
145
146        Pair<C> pair;
147        GenPolynomial<C> pi, pj, S, D, H;
148        while (pairlist.hasNext()) {
149            pair = pairlist.removeNext();
150            //System.out.println("pair = " + pair);
151            if (pair == null)
152                continue;
153
154            pi = pair.pi;
155            pj = pair.pj;
156            if (debug) {
157                logger.debug("pi    = " + pi);
158                logger.debug("pj    = " + pj);
159            }
160
161            // D-polynomial case ----------------------
162            D = dred.GPolynomial(pi, pj);
163            //System.out.println("D_d = " + D);
164            if (!D.isZERO() && !red.isTopReducible(G, D)) {
165                H = red.normalform(G, D);
166                if (H.isONE()) {
167                    G.clear();
168                    G.add(H);
169                    return G; // since no threads are activated
170                }
171                if (!H.isZERO()) {
172                    logger.info("Dred = " + H);
173                    //l++;
174                    G.add(H);
175                    pairlist.put(H);
176                }
177            }
178
179            // S-polynomial case -----------------------
180            if (pair.getUseCriterion3() && pair.getUseCriterion4()) {
181                S = red.SPolynomial(pi, pj);
182                //System.out.println("S_d = " + S);
183                if (S.isZERO()) {
184                    pair.setZero();
185                    continue;
186                }
187                if (logger.isDebugEnabled()) {
188                    logger.debug("ht(S) = " + S.leadingExpVector());
189                }
190
191                H = red.normalform(G, S);
192                if (H.isZERO()) {
193                    pair.setZero();
194                    continue;
195                }
196                if (logger.isDebugEnabled()) {
197                    logger.debug("ht(H) = " + H.leadingExpVector());
198                }
199
200                if (H.isONE()) {
201                    G.clear();
202                    G.add(H);
203                    return G; // since no threads are activated
204                }
205                if (logger.isDebugEnabled()) {
206                    logger.debug("H = " + H);
207                }
208                if (!H.isZERO()) {
209                    logger.info("Sred = " + H);
210                    //len = G.size();
211                    //l++;
212                    G.add(H);
213                    pairlist.put(H);
214                }
215            }
216        }
217        logger.debug("#sequential list = " + G.size());
218        G = minimalGB(G);
219        logger.info("" + pairlist);
220        return G;
221    }
222
223}