001/*
002 * $Id: GroebnerBaseSeqIter.java 5657 2016-12-24 12:52:46Z kredel $
003 */
004
005package edu.jas.gb;
006
007
008import java.util.ArrayList;
009import java.util.List;
010// import java.util.Collections;
011
012import org.apache.log4j.Logger;
013
014import edu.jas.poly.GenPolynomial;
015import edu.jas.poly.GenPolynomialRing;
016import edu.jas.poly.OrderedPolynomialList;
017import edu.jas.poly.PolyUtil;
018import edu.jas.structure.RingElem;
019
020
021/**
022 * Groebner Base sequential iterative algorithm. Implements Groebner bases and
023 * GB test.
024 * @param <C> coefficient type
025 * @author Heinz Kredel
026 * 
027 * @see edu.jas.application.GBAlgorithmBuilder
028 * @see edu.jas.gbufd.GBFactory
029 */
030
031public class GroebnerBaseSeqIter<C extends RingElem<C>> extends GroebnerBaseAbstract<C> {
032
033
034    private static final Logger logger = Logger.getLogger(GroebnerBaseSeqIter.class);
035
036
037    private static final boolean debug = logger.isDebugEnabled();
038
039
040    /**
041     * Constructor.
042     */
043    public GroebnerBaseSeqIter() {
044        super();
045    }
046
047
048    /**
049     * Constructor.
050     * @param red Reduction engine
051     */
052    public GroebnerBaseSeqIter(Reduction<C> red) {
053        super(red);
054    }
055
056
057    /**
058     * Constructor.
059     * @param pl pair selection strategy
060     */
061    public GroebnerBaseSeqIter(PairList<C> pl) {
062        super(pl);
063    }
064
065
066    /**
067     * Constructor.
068     * @param red Reduction engine
069     * @param pl pair selection strategy
070     */
071    public GroebnerBaseSeqIter(Reduction<C> red, PairList<C> pl) {
072        super(red, pl);
073    }
074
075
076    /**
077     * Groebner base using pairlist class, iterative algorithm.
078     * @param modv module variable number.
079     * @param F polynomial list.
080     * @return GB(F) a Groebner base of F.
081     */
082    public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) {
083        List<GenPolynomial<C>> G = normalizeZerosOnes(F);
084        G = PolyUtil.<C> monic(G);
085        if (G.size() <= 1) {
086            return G;
087        }
088        // sort, no reverse
089        G = OrderedPolynomialList.<C> sort(G);
090        //no: Collections.reverse(G);
091        logger.info("G-sort = " + G);
092        List<GenPolynomial<C>> Gp = new ArrayList<GenPolynomial<C>>();
093        for (GenPolynomial<C> p : G) {
094            if (debug) {
095                logger.info("p = " + p);
096            }
097            GenPolynomial<C> pp = red.normalform(Gp, p);
098            if (pp.isZERO()) {
099                continue;
100            }
101            Gp = GB(modv, Gp, pp);
102            //System.out.println("GB(Gp+p) = " + Gp);
103            if (Gp.size() > 0) {
104                if (Gp.get(0).isONE()) {
105                    return Gp;
106                }
107            }
108        }
109        return Gp;
110    }
111
112
113    /**
114     * Groebner base using pairlist class.
115     * @param modv module variable number.
116     * @param G polynomial list of a Groebner base.
117     * @param f polynomial.
118     * @return GB(G,f) a Groebner base of G+(f).
119     */
120    public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> G, GenPolynomial<C> f) {
121        List<GenPolynomial<C>> F = new ArrayList<GenPolynomial<C>>(G);
122        GenPolynomial<C> g = f.monic();
123        if (F.isEmpty()) {
124            F.add(g);
125            return F;
126        }
127        if (g.isZERO()) {
128            return F;
129        }
130        if (g.isONE()) {
131            F.clear();
132            F.add(g);
133            return F;
134        }
135        GenPolynomialRing<C> ring = F.get(0).ring;
136        if (!ring.coFac.isField()) {
137            throw new IllegalArgumentException("coefficients not from a field");
138        }
139        G = F;
140        PairList<C> pairlist = strategy.create(modv, ring);
141        pairlist.setList(G);
142        G.add(g);
143        pairlist.put(g);
144        logger.info("start " + pairlist);
145
146        Pair<C> pair;
147        GenPolynomial<C> pi, pj, S, H;
148        while (pairlist.hasNext()) {
149            pair = pairlist.removeNext();
150            //logger.debug("pair = " + pair);
151            if (pair == null) {
152                continue;
153            }
154            pi = pair.pi;
155            pj = pair.pj;
156            if ( /*false &&*/debug) {
157                logger.debug("pi    = " + pi);
158                logger.debug("pj    = " + pj);
159            }
160
161            S = red.SPolynomial(pi, pj);
162            if (S.isZERO()) {
163                pair.setZero();
164                continue;
165            }
166            if (debug) {
167                logger.debug("ht(S) = " + S.leadingExpVector());
168            }
169
170            H = red.normalform(G, S);
171            if (debug) {
172                //logger.info("pair = " + pair); 
173                //logger.info("ht(S) = " + S.monic()); //.leadingExpVector() );
174                logger.info("ht(H) = " + H.monic()); //.leadingExpVector() );
175            }
176            if (H.isZERO()) {
177                pair.setZero();
178                continue;
179            }
180            H = H.monic();
181            if (debug) {
182                logger.info("ht(H) = " + H.leadingExpVector());
183            }
184
185            H = H.monic();
186            if (H.isONE()) {
187                G.clear();
188                G.add(H);
189                pairlist.putOne();
190                logger.info("end " + pairlist);
191                return G; // since no threads are activated
192            }
193            if (debug) {
194                logger.info("H = " + H);
195            }
196            if (H.length() > 0) {
197                //l++;
198                G.add(H);
199                pairlist.put(H);
200            }
201        }
202        logger.debug("#sequential list = " + G.size());
203        G = minimalGB(G);
204        logger.info("end " + pairlist);
205        return G;
206    }
207
208}