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