001/*
002 * $Id: GroebnerBaseRational.java 4791 2014-04-09 09:36:41Z kredel $
003 */
004
005package edu.jas.gbufd;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import org.apache.log4j.Logger;
012
013import edu.jas.arith.BigInteger;
014import edu.jas.arith.BigRational;
015import edu.jas.gb.GroebnerBaseAbstract;
016import edu.jas.gb.PairList;
017import edu.jas.poly.GenPolynomial;
018import edu.jas.poly.GenPolynomialRing;
019import edu.jas.poly.PolyUtil;
020
021
022/**
023 * Groebner Base sequential algorithm for rational coefficients, fraction free
024 * computation. Implements Groebner bases.
025 * @param <C> BigRational coefficient type
026 * @author Heinz Kredel
027 */
028
029public class GroebnerBaseRational<C extends BigRational> extends GroebnerBaseAbstract<BigRational> {
030
031
032    private static final Logger logger = Logger.getLogger(GroebnerBaseRational.class);
033
034
035    private final boolean debug = logger.isDebugEnabled();
036
037
038    public final GroebnerBaseAbstract<BigInteger> bba;
039
040
041    /**
042     * Constructor.
043     */
044    public GroebnerBaseRational() {
045        this(new GroebnerBasePseudoSeq<BigInteger>(new BigInteger()));
046    }
047
048
049    /**
050     * Constructor.
051     * @param threads the number of parallel threads.
052     */
053    public GroebnerBaseRational(int threads) {
054        this(new GroebnerBasePseudoParallel<BigInteger>(threads, new BigInteger()));
055    }
056
057
058    /**
059     * Constructor.
060     * @param pl pair selection strategy
061     */
062    public GroebnerBaseRational(PairList<BigInteger> pl) {
063        this(new GroebnerBasePseudoSeq<BigInteger>(new BigInteger(), pl));
064    }
065
066
067    /**
068     * Constructor.
069     * @param threads the number of parallel threads.
070     * @param pl pair selection strategy
071     */
072    public GroebnerBaseRational(int threads, PairList<BigInteger> pl) {
073        this(new GroebnerBasePseudoParallel<BigInteger>(threads, new BigInteger(), pl));
074    }
075
076
077    /**
078     * Constructor.
079     * @param bba Groebner base algorithm for BigInteger coefficients.
080     */
081    public GroebnerBaseRational(GroebnerBaseAbstract<BigInteger> bba) {
082        super();
083        this.bba = bba;
084    }
085
086
087    /**
088     * Get the String representation with GB engines.
089     * @see java.lang.Object#toString()
090     */
091    @Override
092    public String toString() {
093        return this.getClass().getSimpleName() + "(" + bba.toString() + ")";
094    }
095
096
097    /**
098     * Groebner base using fraction free computation.
099     * @param modv module variable number.
100     * @param F polynomial list.
101     * @return GB(F) a Groebner base of F.
102     */
103    @Override
104    public List<GenPolynomial<BigRational>> GB(int modv, List<GenPolynomial<BigRational>> F) {
105        List<GenPolynomial<BigRational>> G = F;
106        if (F == null || F.isEmpty()) {
107            return G;
108        }
109        GenPolynomialRing<BigRational> rring = F.get(0).ring;
110        BigInteger cf = new BigInteger();
111        GenPolynomialRing<BigInteger> iring = new GenPolynomialRing<BigInteger>(cf, rring);
112        List<GenPolynomial<BigInteger>> Fi = PolyUtil.integerFromRationalCoefficients(iring, F);
113        //System.out.println("Fi = " + Fi);
114        logger.info("#Fi = " + Fi.size());
115
116        List<GenPolynomial<BigInteger>> Gi = bba.GB(modv, Fi);
117        //System.out.println("Gi = " + Gi);
118        logger.info("#Gi = " + Gi.size());
119
120        G = PolyUtil.<BigRational> fromIntegerCoefficients(rring, Gi);
121        G = PolyUtil.<BigRational> monic(G);
122        return G;
123    }
124
125
126    /**
127     * Minimal ordered Groebner basis.
128     * @param Gp a Groebner base.
129     * @return a reduced Groebner base of Gp.
130     */
131    @Override
132    public List<GenPolynomial<BigRational>> minimalGB(List<GenPolynomial<BigRational>> Gp) {
133        if (Gp == null || Gp.size() <= 1) {
134            return Gp;
135        }
136        // remove zero polynomials
137        List<GenPolynomial<BigRational>> G = new ArrayList<GenPolynomial<BigRational>>(Gp.size());
138        for (GenPolynomial<BigRational> a : Gp) {
139            if (a != null && !a.isZERO()) { // always true in GB()
140                // already positive a = a.abs();
141                G.add(a);
142            }
143        }
144        if (G.size() <= 1) {
145            return G;
146        }
147        // remove top reducible polynomials
148        GenPolynomial<BigRational> a;
149        List<GenPolynomial<BigRational>> F;
150        F = new ArrayList<GenPolynomial<BigRational>>(G.size());
151        while (G.size() > 0) {
152            a = G.remove(0);
153            if (red.isTopReducible(G, a) || red.isTopReducible(F, a)) {
154                // drop polynomial 
155                if (debug) {
156                    System.out.println("dropped " + a);
157                    List<GenPolynomial<BigRational>> ff;
158                    ff = new ArrayList<GenPolynomial<BigRational>>(G);
159                    ff.addAll(F);
160                    a = red.normalform(ff, a);
161                    if (!a.isZERO()) {
162                        System.out.println("error, nf(a) " + a);
163                    }
164                }
165            } else {
166                F.add(a);
167            }
168        }
169        G = F;
170        if (G.size() <= 1) {
171            return G;
172        }
173
174        // reduce remaining polynomials
175        GenPolynomialRing<BigRational> rring = G.get(0).ring;
176        BigInteger cf = new BigInteger();
177        GenPolynomialRing<BigInteger> iring = new GenPolynomialRing<BigInteger>(cf, rring);
178        List<GenPolynomial<BigInteger>> Fi = PolyUtil.integerFromRationalCoefficients(iring, F);
179        logger.info("#Fi = " + Fi.size());
180
181        List<GenPolynomial<BigInteger>> Gi = bba.minimalGB(Fi);
182        logger.info("#Gi = " + Gi.size());
183
184        G = PolyUtil.<BigRational> fromIntegerCoefficients(rring, Gi);
185        G = PolyUtil.<BigRational> monic(G);
186        return G;
187    }
188
189
190    /**
191     * Cleanup and terminate ThreadPool.
192     */
193    @Override
194    public void terminate() {
195        bba.terminate();
196    }
197
198
199    /**
200     * Cancel ThreadPool.
201     */
202    @Override
203    public int cancel() {
204        return bba.cancel();
205    }
206
207}