001/*
002 * $Id: GroebnerBaseArriSigSeqIter.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 Arri 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 GroebnerBaseArriSigSeqIter<C extends RingElem<C>> extends GroebnerBaseSigSeqIter<C> {
030
031
032    private static final Logger logger = LogManager.getLogger(GroebnerBaseArriSigSeqIter.class);
033
034
035    //private static final boolean debug = logger.isDebugEnabled();
036
037
038    /**
039     * Constructor.
040     */
041    public GroebnerBaseArriSigSeqIter() {
042        this(new SigReductionSeq<C>());
043    }
044
045
046    /**
047     * Constructor.
048     * @param red Reduction engine
049     */
050    public GroebnerBaseArriSigSeqIter(SigReductionSeq<C> red) {
051        super(red);
052    }
053
054
055    /**
056     * S-Polynomial.
057     * @param P pair.
058     * @return spol(A,B) the S-polynomial of the pair (A,B).
059     */
060    @Override
061    GenPolynomial<C> SPolynomial(SigPair<C> P) {
062        return P.pi.poly;
063    }
064
065
066    /**
067     * Pair with signature.
068     * @param A polynomial with signature.
069     * @param B polynomial with signature.
070     * @param G polynomial ith signature list.
071     * @return signature pair according to algorithm.
072     */
073    @Override
074    SigPair<C> newPair(SigPoly<C> A, SigPoly<C> B, List<SigPoly<C>> G) {
075        ExpVector e = A.poly.leadingExpVector().lcm(B.poly.leadingExpVector())
076                        .subtract(A.poly.leadingExpVector());
077        GenPolynomial<C> sp = SPolynomial(A, B);
078        GenPolynomial<C> sig = sp.ring.valueOf(e);
079        return new SigPair<C>(sig, new SigPoly<C>(sig, sp), B, G);
080    }
081
082
083    /**
084     * Pair with signature.
085     * @param s signature for pair.
086     * @param A polynomial with signature.
087     * @param B polynomial with signature.
088     * @param G polynomial ith signature list.
089     * @return signature pair according to algorithm.
090     */
091    @Override
092    SigPair<C> newPair(GenPolynomial<C> s, SigPoly<C> A, SigPoly<C> B, List<SigPoly<C>> G) {
093        GenPolynomial<C> sp = SPolynomial(A, B);
094        return new SigPair<C>(s, new SigPoly<C>(s, sp), B, G);
095    }
096
097
098    /**
099     * Top normalform.
100     * @param A polynomial.
101     * @param F polynomial list.
102     * @param G polynomial list.
103     * @return nf(A) with respect to F and G.
104     */
105    @Override
106    SigPoly<C> sigNormalform(List<GenPolynomial<C>> F, List<SigPoly<C>> G, SigPoly<C> A) {
107        return sred.sigSemiNormalform(F, G, A);
108    }
109
110
111    /**
112     * Prune total pair list P.
113     * @param P pair list.
114     * @param syz list of exponent vectors representing syzygies.
115     * @return updated pair list.
116     */
117    @Override
118    List<SigPair<C>> pruneP(List<SigPair<C>> P, List<ExpVector> syz) {
119        List<SigPair<C>> res = new ArrayList<SigPair<C>>(P.size());
120        for (SigPair<C> p : P) {
121            ExpVector f = p.sigma.leadingExpVector();
122            if (f == null) {
123                continue;
124            }
125            boolean div = false;
126            for (ExpVector e : syz) {
127                if (f.multipleOf(e)) {
128                    div = true;
129                    break;
130                }
131            }
132            if (div) {
133                continue;
134            }
135            res.add(p);
136        }
137        return res;
138    }
139
140
141    /**
142     * Prune pair list of degree d.
143     * @param S pair list.
144     * @param syz list of exponent vectors representing syzygies.
145     * @param done list of treated polynomials.
146     * @param G polynomial with signature list.
147     * @return updated pair list.
148     */
149    @Override
150    List<SigPair<C>> pruneS(List<SigPair<C>> S, List<ExpVector> syz, List<SigPoly<C>> done, List<SigPoly<C>> G) {
151        List<SigPair<C>> res = new ArrayList<SigPair<C>>(S.size());
152        for (SigPair<C> p : S) {
153            ExpVector f = p.sigma.leadingExpVector();
154            if (f == null) {
155                continue;
156            }
157            boolean div = false;
158            for (ExpVector e : syz) {
159                if (f.multipleOf(e)) {
160                    div = true;
161                    break;
162                }
163            }
164            if (div) {
165                continue;
166            }
167            div = false;
168            for (SigPair<C> q : S) {
169                if (p.sigma.equals(q.sigma)) {
170                    if (p.pi.poly.compareTo(q.pi.poly) > 0) {
171                        div = true;
172                        break;
173                    }
174                }
175            }
176            if (div) {
177                continue;
178            }
179            div = false;
180            for (SigPoly<C> q : done) {
181                ExpVector e = q.sigma.leadingExpVector();
182                if (e == null) {
183                    continue;
184                }
185                if (f.multipleOf(e)) {
186                    ExpVector g = f.subtract(e);
187                    ExpVector f1 = g.sum(q.poly.leadingExpVector());
188                    ExpVector e1 = p.pi.poly.leadingExpVector();
189                    if (e1 == null) {
190                        continue;
191                    }
192                    if (f1.compareTo(e1) < 0) {
193                        div = true;
194                        break;
195                    }
196                }
197            }
198            if (div) {
199                continue;
200            }
201            res.add(p);
202            logger.debug("added p = " + p.sigma);
203        }
204        return res;
205    }
206
207
208    /**
209     * Initializes syzygy list.
210     * @param F polynomial list.
211     * @param G polynomial with signature list.
212     * @return list of exponent vectors representing syzygies.
213     */
214    @Override
215    List<ExpVector> initializeSyz(List<GenPolynomial<C>> F, List<SigPoly<C>> G) {
216        List<ExpVector> P = new ArrayList<ExpVector>();
217        for (GenPolynomial<C> p : F) {
218            if (p.isZERO()) {
219                continue;
220            }
221            P.add(p.leadingExpVector());
222        }
223        return P;
224    }
225
226
227    /**
228     * Update syzygy list.
229     * @param syz list of exponent vectors representing syzygies.
230     * @param r polynomial. <b>Note:</b> szy is modified to represent updated
231     *            list of exponent vectors.
232     */
233    @Override
234    void updateSyz(List<ExpVector> syz, SigPoly<C> r) {
235        if (r.poly.isZERO() && !r.sigma.isZERO()) {
236            syz.add(r.sigma.leadingExpVector());
237        }
238        return;
239    }
240
241}