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