001/*
002 * $Id: GroebnerBaseF5zSigSeqIter.java 5869 2018-07-20 15:53:10Z kredel $
003 */
004
005package edu.jas.gb;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import org.apache.logging.log4j.Logger;
012import org.apache.logging.log4j.LogManager; 
013
014import edu.jas.poly.ExpVector;
015import edu.jas.poly.GenPolynomial;
016import edu.jas.structure.RingElem;
017
018
019/**
020 * Groebner Base F5z signature based sequential iterative algorithm. Implements
021 * Groebner bases.
022 * @param <C> coefficient type
023 * @author Heinz Kredel
024 * 
025 * @see edu.jas.application.GBAlgorithmBuilder
026 * @see edu.jas.gbufd.GBFactory
027 */
028
029public class GroebnerBaseF5zSigSeqIter<C extends RingElem<C>> extends GroebnerBaseSigSeqIter<C> {
030
031
032    private static final Logger logger = LogManager.getLogger(GroebnerBaseF5zSigSeqIter.class);
033
034
035    //private static final boolean debug = logger.isDebugEnabled();
036
037
038    /**
039     * Constructor.
040     */
041    public GroebnerBaseF5zSigSeqIter() {
042        this(new SigReductionSeq<C>());
043    }
044
045
046    /**
047     * Constructor.
048     * @param red Reduction engine
049     */
050    public GroebnerBaseF5zSigSeqIter(SigReductionSeq<C> red) {
051        super(red);
052    }
053
054
055    /**
056     * Top normalform.
057     * @param A polynomial.
058     * @param F polynomial list.
059     * @param G polynomial list.
060     * @return nf(A) with respect to F and G.
061     */
062    @Override
063    SigPoly<C> sigNormalform(List<GenPolynomial<C>> F, List<SigPoly<C>> G, SigPoly<C> A) {
064        return sred.sigSemiNormalform(F, G, A);
065    }
066
067
068    /**
069     * Prune total pair list P.
070     * @param P pair list.
071     * @param syz list of exponent vectors representing syzygies.
072     * @return updated pair list. <b>Note:<b> stores polynomials not only
073     *         indices.
074     */
075    @Override
076    List<SigPair<C>> pruneP(List<SigPair<C>> P, List<ExpVector> syz) {
077        List<SigPair<C>> res = new ArrayList<SigPair<C>>(P.size());
078        for (SigPair<C> p : P) {
079            ExpVector f = p.sigma.leadingExpVector();
080            if (f == null) {
081                continue;
082            }
083            boolean div = false;
084            for (ExpVector e : syz) {
085                if (f.multipleOf(e)) {
086                    div = true;
087                    break;
088                }
089            }
090            if (div) {
091                continue;
092            }
093            res.add(p);
094        }
095        return res;
096    }
097
098
099    /**
100     * Prune pair list of degree d.
101     * @param S pair list.
102     * @param syz list of exponent vectors representing syzygies.
103     * @param done list of treated polynomials.
104     * @param G polynomial with signature list.
105     * @return updated pair list.
106     */
107    @Override
108    List<SigPair<C>> pruneS(List<SigPair<C>> S, List<ExpVector> syz, List<SigPoly<C>> done, List<SigPoly<C>> G) {
109        List<SigPair<C>> res = new ArrayList<SigPair<C>>(S.size());
110        for (SigPair<C> p : S) {
111            if (p.sigma.isZERO()) {
112                continue;
113            }
114            ExpVector f = p.sigma.leadingExpVector();
115            boolean div = false;
116            for (ExpVector e : syz) {
117                if (f.multipleOf(e)) {
118                    div = true;
119                    break;
120                }
121            }
122            if (div) {
123                continue;
124            }
125            if (p.pi.sigma.isZERO()) {
126                logger.info("pruneS, p.pi.sigma = 0");
127                res.add(p);
128                continue;
129            }
130            ExpVector fi = p.pi.poly.leadingExpVector();
131            ExpVector fj = p.pj.poly.leadingExpVector();
132            ExpVector fu = fi.lcm(fj).subtract(fi);
133            f = p.pi.sigma.leadingExpVector();
134            fu = fu.sum(f);
135            div = false;
136            for (SigPoly<C> q : done) {
137                ExpVector e = q.sigma.leadingExpVector();
138                if (e == null) {
139                    continue;
140                }
141                if (fu.multipleOf(e)) {
142                    if (q.sigma.compareTo(p.pi.sigma) > 0) {
143                        div = true;
144                        break;
145                    }
146                }
147            }
148            if (div) {
149                continue;
150            }
151            res.add(p);
152            logger.debug("added p = " + p.sigma);
153        }
154        return res;
155    }
156
157
158    /**
159     * Initializes syzygy list.
160     * @param F polynomial list.
161     * @param G polynomial with signature list.
162     * @return list of exponent vectors representing syzygies.
163     */
164    @Override
165    List<ExpVector> initializeSyz(List<GenPolynomial<C>> F, List<SigPoly<C>> G) {
166        List<ExpVector> P = new ArrayList<ExpVector>();
167        for (GenPolynomial<C> p : F) {
168            if (p.isZERO()) {
169                continue;
170            }
171            P.add(p.leadingExpVector());
172        }
173        return P;
174    }
175
176
177    /**
178     * Update syzygy list.
179     * @param syz list of exponent vectors representing syzygies.
180     * @param r polynomial. <b>Note:</b> szy is modified to represent updated
181     *            list of exponent vectors.
182     */
183    @Override
184    void updateSyz(List<ExpVector> syz, SigPoly<C> r) {
185        if (r.poly.isZERO() && !r.sigma.isZERO()) {
186            //logger.info("update_syz, sigma = " + r.sigma);
187            syz.add(r.sigma.leadingExpVector());
188        }
189        return;
190    }
191
192}