/*
 * $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.