
edu.jas.application.GBAlgorithmBuilder Maven / Gradle / Ivy
The newest version!
/*
* $Id: GBAlgorithmBuilder.java 4368 2013-03-13 22:17:46Z kredel $
*/
package edu.jas.application;
import java.io.Serializable;
import org.apache.log4j.Logger;
import edu.jas.arith.BigInteger;
import edu.jas.arith.BigRational;
import edu.jas.gb.GBOptimized;
import edu.jas.gb.GBProxy;
import edu.jas.gb.GroebnerBaseAbstract;
import edu.jas.gb.GroebnerBaseParallel;
import edu.jas.gb.PairList;
import edu.jas.gb.OrderedPairlist;
import edu.jas.gb.OrderedMinPairlist;
import edu.jas.gb.OrderedSyzPairlist;
import edu.jas.gbufd.GBFactory;
import edu.jas.gbufd.GroebnerBaseFGLM;
import edu.jas.gbufd.GroebnerBasePseudoParallel;
import edu.jas.gbufd.GroebnerBaseRational;
import edu.jas.kern.ComputerThreads;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingFactory;
import edu.jas.ufd.Quotient;
import edu.jas.ufd.QuotientRing;
/**
* Builder for commutative Gröbner bases algorithm implementations.
* @author Heinz Kredel
* @usage To create objects that implement the GroebnerBase
* interface one can use the GBFactory
or this GBAlgorithmBuilder
.
* This class will select and compose an
* appropriate implementation based on the types of polynomial
* coefficients C and the desired properties. To build an implementation start with
* the static method polynomialRing()
to define the polynomial ring.
* Then continue to construct the algorithm with the methods
*
* optimize()
or optimize(boolean)
for term order (variable order)
* optimization (true for return of permuted polynomials),
*
* normalPairlist()
(default), syzygyPairlist()
* or simplePairlist()
* for pair-list selection strategies,
*
* fractionFree()
for clearing denominators and computing with pseudo reduction,
*
* graded()
for using the FGLM algorithm to first compute a
* Gröbner base with respect to a
* graded term order and then constructing a Gröbner base
* wrt. a lexicographical term order,
*
* parallel()
additionaly compute a Gröbner base over
* a field or integral domain in parallel,
*
* euclideanDomain()
for computing a e-Gröbner base,
*
* domainAlgorithm(Algo)
for computing a d- or e-Gröbner base,
*
*
* Finally call the method build()
to obtain an implementaton of
* class GroebnerBaseAbstract
. For example
*
*
*
* GenPolynomialRing<C> pf = new GenPolynomialRing<C>(cofac, vars);
* GroebnerBaseAbstract<C> engine;
* engine = GBAlgorithmBuilder.<C> polynomialRing(pf).fractionFree().parallel().optimize().build();
* c = engine.GB(A);
*
*
* For example, if the coefficient type is BigRational, the usage looks
* like
*
*
*
* GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(cofac, vars);
* GroebnerBaseAbstract<BigRational> engine;
* engine = GBAlgorithmBuilder.<BigRational> polynomialRing(pf).fractionFree().parallel().optimize().build();
* c = engine.GB(A);
*
*
* Note: Not all combinations are meanigful
*
* @see edu.jas.gb.GroebnerBase
* @see edu.jas.gbufd.GBFactory
*/
public class GBAlgorithmBuilder> implements Serializable {
private static final Logger logger = Logger.getLogger(GBAlgorithmBuilder.class);
/**
* The current GB algorithm implementation.
*/
private GroebnerBaseAbstract algo;
/**
* The current polynomial ring.
*/
public final GenPolynomialRing ring;
/**
* Requested pairlist strategy.
*/
public final PairList strategy;
/**
* Constructor not for use.
*/
protected GBAlgorithmBuilder() {
throw new IllegalArgumentException("do not use this constructor");
}
/**
* Constructor.
* @param ring the polynomial ring.
*/
public GBAlgorithmBuilder(GenPolynomialRing ring) {
this(ring, null);
}
/**
* Constructor.
* @param ring the polynomial ring.
* @param algo already determined algorithm.
*/
public GBAlgorithmBuilder(GenPolynomialRing ring, GroebnerBaseAbstract algo) {
this(ring, algo, null);
}
/**
* Constructor.
* @param ring the polynomial ring.
* @param algo already determined algorithm.
* @param strategy pairlist strategy.
*/
public GBAlgorithmBuilder(GenPolynomialRing ring,
GroebnerBaseAbstract algo,
PairList strategy) {
if ( ring == null ) {
throw new IllegalArgumentException("ring may not be null");
}
this.ring = ring;
this.algo = algo; // null accepted
if ( strategy == null ) {
strategy = new OrderedPairlist();
}
this.strategy = strategy;
}
/**
* Build the GB algorithm implementaton.
* @return GB algorithm implementaton as GroebnerBaseAbstract object.
*/
public GroebnerBaseAbstract build() {
if (algo == null) {
if ( strategy == null ) { // should not happen
algo = GBFactory. getImplementation(ring.coFac);
} else {
algo = GBFactory. getImplementation(ring.coFac,strategy);
}
}
return algo;
}
/**
* Define polynomial ring.
* @param fac the commutative polynomial ring.
* @return GBAlgorithmBuilder object.
*/
public static > GBAlgorithmBuilder polynomialRing(GenPolynomialRing fac) {
return new GBAlgorithmBuilder(fac);
}
/**
* Select syzygy critical pair-list strategy.
* Gebauer and Möller algorithm.
* @return GBAlgorithmBuilder object.
*/
public GBAlgorithmBuilder syzygyPairlist() {
return new GBAlgorithmBuilder(ring, algo, new OrderedSyzPairlist());
}
/**
* Select normal critical pair-list strategy.
* Buchberger, Winkler and Kredel algorithm.
* @return GBAlgorithmBuilder object.
*/
public GBAlgorithmBuilder normalPairlist() {
return new GBAlgorithmBuilder(ring, algo, new OrderedPairlist());
}
/**
* Select simple critical pair-list strategy.
* Original Buchberger algorithm.
* @return GBAlgorithmBuilder object.
*/
public GBAlgorithmBuilder simplePairlist() {
return new GBAlgorithmBuilder(ring, algo, new OrderedMinPairlist());
}
/**
* Request term order optimization.
* Call optimize(true) for return of permuted polynomials.
* @return GBAlgorithmBuilder object.
*/
public GBAlgorithmBuilder optimize() {
return optimize(true);
}
/**
* Request term order optimization.
* @param rP true for return of permuted polynomials, false for inverse
* permuted polynomials and new GB computation.
* @return GBAlgorithmBuilder object.
*/
public GBAlgorithmBuilder optimize(boolean rP) {
if (algo == null) {
algo = GBFactory. getImplementation(ring.coFac,strategy);
}
GroebnerBaseAbstract bb = new GBOptimized(algo, rP);
return new GBAlgorithmBuilder(ring, bb);
}
/**
* Request fraction free algorithm. For BigRational and Quotient
* coefficients denominators are cleared and pseudo reduction is
* used.
* @return GBAlgorithmBuilder object.
*/
@SuppressWarnings("unchecked")
public GBAlgorithmBuilder fractionFree() {
if (algo != null) {
logger.warn("selected algorithm ignored: " + algo + ", use fractionFree before");
}
if (((Object)ring.coFac) instanceof BigRational) {
BigRational cf = (BigRational) (Object) ring.coFac;
PairList sty = (PairList) strategy;
GroebnerBaseAbstract bb
= GBFactory.getImplementation(cf, GBFactory.Algo.ffgb, sty);
GroebnerBaseAbstract cbb = (GroebnerBaseAbstract) (GroebnerBaseAbstract) bb;
return new GBAlgorithmBuilder(ring, cbb);
}
if (((Object)ring.coFac) instanceof QuotientRing) {
QuotientRing cf = (QuotientRing) (Object) ring.coFac;
PairList> sty = (PairList) strategy;
GroebnerBaseAbstract> bb
= GBFactory. getImplementation(cf, GBFactory.Algo.ffgb, sty);
GroebnerBaseAbstract cbb = (GroebnerBaseAbstract) (GroebnerBaseAbstract) bb;
return new GBAlgorithmBuilder(ring, cbb);
}
logger.warn("no fraction free algorithm implemented for " + ring);
return this;
}
/**
* Request e-GB algorithm.
* @return GBAlgorithmBuilder object.
*/
public GBAlgorithmBuilder euclideanDomain() {
return domainAlgorithm(GBFactory.Algo.egb);
}
/**
* Request d- or e-GB algorithm.
* @param a algorithm from GBFactory.Algo.
* @return GBAlgorithmBuilder object.
*/
@SuppressWarnings("unchecked")
public GBAlgorithmBuilder domainAlgorithm(GBFactory.Algo a) {
if (((Object)ring.coFac) instanceof BigInteger) {
BigInteger cf = (BigInteger) (Object) ring.coFac;
GroebnerBaseAbstract bb = GBFactory.getImplementation(cf, a);
GroebnerBaseAbstract cbb = (GroebnerBaseAbstract) (GroebnerBaseAbstract) bb;
return new GBAlgorithmBuilder(ring, cbb);
}
logger.warn("no domain algorithm implemented for " + ring);
return this;
}
/**
* Request parallel algorithm.
* Additionaly run a parallel algorithm via GBProxy.
* @return GBAlgorithmBuilder object.
*/
@SuppressWarnings("unchecked")
public GBAlgorithmBuilder parallel() {
return parallel(ComputerThreads.N_CPUS);
}
/**
* Request parallel algorithm.
* Additionaly run a parallel algorithm via GBProxy.
* @param threads number of threads requested.
* @return GBAlgorithmBuilder object.
*/
@SuppressWarnings("unchecked")
public GBAlgorithmBuilder parallel(int threads) {
if (ComputerThreads.NO_THREADS) {
logger.warn("parallel algorithms disabled");
return this;
}
if (algo == null) {
algo = GBFactory. getImplementation(ring.coFac, strategy);
}
if ( ((RingFactory)ring.coFac) instanceof BigRational) {
GroebnerBaseAbstract bb;
if (algo instanceof GroebnerBaseRational) { // fraction free requested
bb = (GroebnerBaseAbstract) new GroebnerBaseRational(threads);
} else {
bb = (GroebnerBaseAbstract) new GroebnerBaseParallel(threads,strategy);
}
GroebnerBaseAbstract pbb = new GBProxy(algo, bb);
return new GBAlgorithmBuilder(ring, pbb);
} else if (ring.coFac.isField()) {
GroebnerBaseAbstract bb = new GroebnerBaseParallel(threads, strategy);
GroebnerBaseAbstract pbb = new GBProxy(algo, bb);
return new GBAlgorithmBuilder(ring, pbb);
} else if (ring.coFac.getONE() instanceof GcdRingElem) {
GroebnerBaseAbstract bb = new GroebnerBasePseudoParallel(threads,ring.coFac,strategy);
GroebnerBaseAbstract pbb = new GBProxy(algo, bb);
return new GBAlgorithmBuilder(ring, pbb);
}
logger.warn("no parallel algorithm implemented for " + ring);
return this;
}
/**
* Request FGLM algorithm.
* @return GBAlgorithmBuilder object.
*/
@SuppressWarnings("unchecked")
public GBAlgorithmBuilder graded() {
if (ring.coFac.isField()) {
GroebnerBaseAbstract bb;
if (algo == null) {
bb = new GroebnerBaseFGLM();
} else {
bb = new GroebnerBaseFGLM(algo);
}
return new GBAlgorithmBuilder(ring, bb);
}
logger.warn("no FGLM algorithm implemented for " + ring);
return this;
}
/**
* String representation of the GB algorithm implementation.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer s = new StringBuffer(" ");
if ( algo != null ) {
s.append(algo.toString());
s.append(" for ");
}
s.append(ring.toString());
return s.toString();
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this Element.
* @see edu.jas.structure.Element#toScript()
*/
public String toScript() {
// Python case
StringBuffer s = new StringBuffer(" ");
if ( algo != null ) {
s.append(algo.toString()); // nonsense
s.append(" ");
}
s.append(ring.toScript());
return s.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy