001/*
002 * $Id: GBOptimized.java 4655 2013-10-05 10:12:32Z kredel $
003 */
004
005package edu.jas.gb;
006
007
008import java.util.List;
009
010import org.apache.log4j.Logger;
011
012import edu.jas.poly.GenPolynomial;
013import edu.jas.poly.GenPolynomialRing;
014import edu.jas.poly.OptimizedPolynomialList;
015import edu.jas.poly.TermOrderOptimization;
016import edu.jas.structure.GcdRingElem;
017
018
019/**
020 * Groebner bases via optimized variable and term order.
021 * @author Heinz Kredel
022 */
023
024public class GBOptimized<C extends GcdRingElem<C>> extends GroebnerBaseAbstract<C> {
025
026
027    private static final Logger logger = Logger.getLogger(GBOptimized.class);
028
029
030    private final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
031
032
033    /**
034     * GB engine.
035     */
036    public final GroebnerBaseAbstract<C> e1;
037
038
039    /**
040     * Indicator for return of permuted polynomials.
041     */
042    public final boolean retPermuted;
043
044
045    /**
046     * GBOptimized constructor.
047     * @param e1 Groebner base engine.
048     */
049    public GBOptimized(GroebnerBaseAbstract<C> e1) {
050        this(e1, false); // true ??
051    }
052
053
054    /**
055     * GBOptimized constructor.
056     * @param e1 Groebner base engine.
057     * @param rP true for return of permuted polynomials, false for inverse
058     *            permuted polynomials and new GB computation.
059     */
060    public GBOptimized(GroebnerBaseAbstract<C> e1, boolean rP) {
061        this.e1 = e1;
062        this.retPermuted = rP;
063    }
064
065
066    /**
067     * Get the String representation with GB engine.
068     * @see java.lang.Object#toString()
069     */
070    @Override
071    public String toString() {
072        return "GBOptimized[ " + e1.toString() + " ]";
073    }
074
075
076    /**
077     * Cleanup and terminate ThreadPool.
078     */
079    @Override
080    public void terminate() {
081        e1.terminate();
082    }
083
084
085    /**
086     * Cancel ThreadPool.
087     */
088    @Override
089    public int cancel() {
090        int s = e1.cancel();
091        return s;
092    }
093
094
095    /**
096     * Groebner base.
097     * @param modv module variable number.
098     * @param F polynomial list.
099     * @return GB(F) a Groebner base of F.
100     */
101    @Override
102    public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) {
103        if (F == null || F.isEmpty()) {
104            return F;
105        }
106        if (modv != 0) {
107            throw new UnsupportedOperationException("implemented only for modv = 0, not " + modv);
108        }
109        GenPolynomialRing<C> pfac = F.get(0).ring;
110        OptimizedPolynomialList<C> opt = TermOrderOptimization.<C> optimizeTermOrder(pfac, F);
111        List<GenPolynomial<C>> P = opt.list;
112        if (debug) {
113            logger.info("optimized polynomials: " + P);
114        }
115        List<Integer> iperm = TermOrderOptimization.inversePermutation(opt.perm);
116        logger.info("optimize perm: " + opt.perm + ", de-optimize perm: " + iperm);
117
118        // compute GB with backing engine
119        List<GenPolynomial<C>> G = e1.GB(modv, P);
120        if (retPermuted || G.isEmpty()) {
121            return G;
122        }
123        List<GenPolynomial<C>> iopt = TermOrderOptimization.<C> permutation(iperm, pfac, G);
124        if (debug) {
125            logger.info("de-optimized polynomials: " + iopt);
126        }
127        if (iopt.size() == 1) {
128            return iopt;
129        }
130        logger.warn("recomputing GB");
131        G = e1.GB(modv, iopt);
132        return G;
133    }
134
135}