/*
* $Id$
*/
package edu.jas.ufd;
import org.apache.log4j.Logger;
import edu.jas.arith.BigInteger;
import edu.jas.arith.BigRational;
import edu.jas.arith.ModInteger;
import edu.jas.arith.ModIntegerRing;
import edu.jas.arith.ModLong;
import edu.jas.arith.ModLongRing;
import edu.jas.kern.ComputerThreads;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingFactory;
/**
* Greatest common divisor algorithms factory. Select appropriate GCD engine
* based on the coefficient types.
* @author Heinz Kredel
* @usage To create objects that implement the
* GreatestCommonDivisor interface use the
* GCDFactory. It will select an appropriate implementation
* based on the types of polynomial coefficients C. There are two methods
* to obtain an implementation: getProxy() and
* getImplementation(). getImplementation()
* returns an object of a class which implements the
* GreatestCommonDivisor interface. getProxy()
* returns a proxy object of a class which implements the
* GreatestCommonDivisorr interface. The proxy will run two
* implementations in parallel, return the first computed result and
* cancel the second running task. On systems with one CPU the computing
* time will be two times the time of the fastest algorithm
* implmentation. On systems with more than two CPUs the computing time
* will be the time of the fastest algorithm implmentation.
*
*
* GreatestCommonDivisor<CT> engine;
* engine = GCDFactory.<CT> getImplementation(cofac);
* or engine = GCDFactory.<CT> getProxy(cofac);
* c = engine.gcd(a, b);
*
*
* For example, if the coefficient type is BigInteger, the usage looks
* like
*
*
* BigInteger cofac = new BigInteger();
* GreatestCommonDivisor<BigInteger> engine;
* engine = GCDFactory.getImplementation(cofac);
* or engine = GCDFactory.getProxy(cofac);
* c = engine.gcd(a, b);
*
*
* @see edu.jas.ufd.GreatestCommonDivisor#gcd(edu.jas.poly.GenPolynomial P,
* edu.jas.poly.GenPolynomial S)
* Todo: Base decision also on degree vectors and number of variables of
* polynomials. Incorporate also number of CPUs / threads available (done
* with GCDProxy).
*/
public class GCDFactory {
private static final Logger logger = Logger.getLogger(GCDFactory.class);
/**
* Protected factory constructor.
*/
protected GCDFactory() {
}
/**
* Determine suitable implementation of gcd algorithms, case ModLong.
* @param fac ModLongRing.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getImplementation(ModLongRing fac) {
GreatestCommonDivisorAbstract ufd;
if (fac.isField()) {
ufd = new GreatestCommonDivisorModEval();
return ufd;
}
ufd = new GreatestCommonDivisorSubres();
return ufd;
}
/**
* Determine suitable proxy for gcd algorithms, case ModLong.
* @param fac ModLongRing.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getProxy(ModLongRing fac) {
GreatestCommonDivisorAbstract ufd1, ufd2;
ufd1 = new GreatestCommonDivisorSubres();
if (fac.isField()) {
ufd2 = new GreatestCommonDivisorModEval();
} else {
ufd2 = new GreatestCommonDivisorSimple();
}
return new GCDProxy(ufd1, ufd2);
}
/**
* Determine suitable implementation of gcd algorithms, case ModInteger.
* @param fac ModIntegerRing.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getImplementation(ModIntegerRing fac) {
GreatestCommonDivisorAbstract ufd;
if (fac.isField()) {
ufd = new GreatestCommonDivisorModEval();
return ufd;
}
ufd = new GreatestCommonDivisorSubres();
return ufd;
}
/**
* Determine suitable proxy for gcd algorithms, case ModInteger.
* @param fac ModIntegerRing.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getProxy(ModIntegerRing fac) {
GreatestCommonDivisorAbstract ufd1, ufd2;
ufd1 = new GreatestCommonDivisorSubres();
if (fac.isField()) {
ufd2 = new GreatestCommonDivisorModEval();
} else {
ufd2 = new GreatestCommonDivisorSimple();
}
return new GCDProxy(ufd1, ufd2);
}
/**
* Determine suitable implementation of gcd algorithms, case BigInteger.
* @param fac BigInteger.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getImplementation(BigInteger fac) {
GreatestCommonDivisorAbstract ufd;
if (true) {
ufd = new GreatestCommonDivisorModular(); // dummy type
} else {
ufd = new GreatestCommonDivisorSubres();
}
return ufd;
}
/**
* Determine suitable procy for gcd algorithms, case BigInteger.
* @param fac BigInteger.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getProxy(BigInteger fac) {
GreatestCommonDivisorAbstract ufd1, ufd2;
ufd1 = new GreatestCommonDivisorSubres();
ufd2 = new GreatestCommonDivisorModular(); // dummy type
return new GCDProxy(ufd1, ufd2);
}
/**
* Determine suitable implementation of gcd algorithms, case BigRational.
* @param fac BigRational.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getImplementation(BigRational fac) {
GreatestCommonDivisorAbstract ufd;
ufd = new GreatestCommonDivisorPrimitive();
return ufd;
}
/**
* Determine suitable proxy for gcd algorithms, case BigRational.
* @param fac BigRational.
* @return gcd algorithm implementation.
*/
public static GreatestCommonDivisorAbstract getProxy(BigRational fac) {
GreatestCommonDivisorAbstract ufd1, ufd2;
ufd1 = new GreatestCommonDivisorSubres();
ufd2 = new GreatestCommonDivisorSimple();
return new GCDProxy(ufd1, ufd2);
}
/**
* Determine suitable implementation of gcd algorithms, other cases.
* @param fac RingFactory<C>.
* @return gcd algorithm implementation.
*/
@SuppressWarnings("unchecked")
public static > GreatestCommonDivisorAbstract getImplementation(
RingFactory fac) {
GreatestCommonDivisorAbstract/*raw type*/ufd;
logger.debug("fac = " + fac.getClass().getName());
Object ofac = fac;
if (ofac instanceof BigInteger) {
ufd = new GreatestCommonDivisorModular();
//ufd = new GreatestCommonDivisorSubres();
//ufd = new GreatestCommonDivisorModular(true);
} else if (ofac instanceof ModIntegerRing) {
ufd = new GreatestCommonDivisorModEval();
} else if (ofac instanceof ModLongRing) {
ufd = new GreatestCommonDivisorModEval();
} else if (ofac instanceof BigRational) {
ufd = new GreatestCommonDivisorSubres();
} else {
if (fac.isField()) {
ufd = new GreatestCommonDivisorSimple();
} else {
ufd = new GreatestCommonDivisorSubres();
}
}
logger.debug("implementation = " + ufd);
return ufd;
}
/**
* Determine suitable proxy for gcd algorithms, other cases.
* @param fac RingFactory<C>.
* @return gcd algorithm implementation. Note: This method contains a
* hack for Google app engine to not use threads.
* @see edu.jas.kern.ComputerThreads#NO_THREADS
*/
@SuppressWarnings("unchecked")
public static > GreatestCommonDivisorAbstract getProxy(RingFactory fac) {
if (ComputerThreads.NO_THREADS) { // hack for Google app engine
return GCDFactory. getImplementation(fac);
}
GreatestCommonDivisorAbstract/*raw type*/ufd;
logger.debug("fac = " + fac.getClass().getName());
Object ofac = fac;
if (ofac instanceof BigInteger) {
ufd = new GCDProxy(new GreatestCommonDivisorSubres(),
new GreatestCommonDivisorModular());
} else if (ofac instanceof ModIntegerRing) {
ufd = new GCDProxy(new GreatestCommonDivisorSimple(), // Subres
new GreatestCommonDivisorModEval());
} else if (ofac instanceof ModLongRing) {
ufd = new GCDProxy(new GreatestCommonDivisorSimple(), // Subres
new GreatestCommonDivisorModEval());
} else if (ofac instanceof BigRational) {
ufd = new GCDProxy(new GreatestCommonDivisorSubres(),
new GreatestCommonDivisorSimple());
} else {
if (fac.isField()) {
ufd = new GCDProxy(new GreatestCommonDivisorSimple(),
new GreatestCommonDivisorSubres());
} else {
ufd = new GCDProxy(new GreatestCommonDivisorSubres(),
new GreatestCommonDivisorPrimitive()); // no resultant
}
}
logger.debug("ufd = " + ufd);
return ufd;
}
}
Ads help maintain this website.