001/* 002 * $Id: FactorFactory.java 4067 2012-07-27 16:17:35Z kredel $ 003 */ 004 005package edu.jas.ufd; 006 007 008import org.apache.log4j.Logger; 009 010import edu.jas.arith.BigInteger; 011import edu.jas.arith.BigRational; 012import edu.jas.arith.ModInteger; 013import edu.jas.arith.ModIntegerRing; 014import edu.jas.arith.ModLong; 015import edu.jas.arith.ModLongRing; 016import edu.jas.poly.AlgebraicNumber; 017import edu.jas.poly.AlgebraicNumberRing; 018import edu.jas.poly.Complex; 019import edu.jas.poly.ComplexRing; 020import edu.jas.poly.GenPolynomialRing; 021import edu.jas.structure.GcdRingElem; 022import edu.jas.structure.RingFactory; 023 024 025/** 026 * Factorization algorithms factory. Select appropriate factorization engine 027 * based on the coefficient types. 028 * @author Heinz Kredel 029 * @usage To create objects that implement the <code>Factorization</code> 030 * interface use the <code>FactorFactory</code>. It will select an 031 * appropriate implementation based on the types of polynomial 032 * coefficients C. To obtain an implementation use 033 * <code>getImplementation()</code>, it returns an object of a class 034 * which extends the <code>FactorAbstract</code> class which implements 035 * the <code>Factorization</code> interface. 036 * 037 * <pre> 038 * Factorization<CT> engine; 039 * engine = FactorFactory.<CT> getImplementation(cofac); 040 * c = engine.factors(a); 041 * </pre> 042 * 043 * For example, if the coefficient type is BigInteger, the usage looks 044 * like 045 * 046 * <pre> 047 * BigInteger cofac = new BigInteger(); 048 * Factorization<BigInteger> engine; 049 * engine = FactorFactory.getImplementation(cofac); 050 * Sm = engine.factors(poly); 051 * </pre> 052 * 053 * @see edu.jas.ufd.Factorization#factors(edu.jas.poly.GenPolynomial P) 054 */ 055 056public class FactorFactory { 057 058 059 private static final Logger logger = Logger.getLogger(FactorFactory.class); 060 061 062 /** 063 * Protected factory constructor. 064 */ 065 protected FactorFactory() { 066 } 067 068 069 /** 070 * Determine suitable implementation of factorization algorithm, case 071 * ModInteger. 072 * @param fac ModIntegerRing. 073 * @return factorization algorithm implementation. 074 */ 075 public static FactorAbstract<ModInteger> getImplementation(ModIntegerRing fac) { 076 return new FactorModular<ModInteger>(fac); 077 } 078 079 080 /** 081 * Determine suitable implementation of factorization algorithm, case 082 * ModInteger. 083 * @param fac ModIntegerRing. 084 * @return factorization algorithm implementation. 085 */ 086 public static FactorAbstract<ModLong> getImplementation(ModLongRing fac) { 087 return new FactorModular<ModLong>(fac); 088 } 089 090 091 /** 092 * Determine suitable implementation of factorization algorithm, case 093 * BigInteger. 094 * @param fac BigInteger. 095 * @return factorization algorithm implementation. 096 */ 097 public static FactorAbstract<BigInteger> getImplementation(BigInteger fac) { 098 return new FactorInteger<ModLong>(); 099 } 100 101 102 /** 103 * Determine suitable implementation of factorization algorithms, case 104 * BigRational. 105 * @param fac BigRational. 106 * @return factorization algorithm implementation. 107 */ 108 public static FactorAbstract<BigRational> getImplementation(BigRational fac) { 109 return new FactorRational(); 110 } 111 112 113 /** 114 * Determine suitable implementation of factorization algorithms, case 115 * AlgebraicNumber<C>. 116 * @param fac AlgebraicNumberRing<C>. 117 * @param <C> coefficient type, e.g. BigRational, ModInteger. 118 * @return factorization algorithm implementation. 119 */ 120 public static <C extends GcdRingElem<C>> FactorAbstract<AlgebraicNumber<C>> getImplementation( 121 AlgebraicNumberRing<C> fac) { 122 return new FactorAlgebraic<C>(fac); 123 } 124 125 126 /** 127 * Determine suitable implementation of factorization algorithms, case 128 * Complex<C>. 129 * @param fac ComplexRing<C>. 130 * @param <C> coefficient type, e.g. BigRational, ModInteger. 131 * @return factorization algorithm implementation. 132 */ 133 public static <C extends GcdRingElem<C>> FactorAbstract<Complex<C>> getImplementation(ComplexRing<C> fac) { 134 return new FactorComplex<C>(fac); 135 } 136 137 138 /** 139 * Determine suitable implementation of factorization algorithms, case 140 * Quotient<C>. 141 * @param fac QuotientRing<C>. 142 * @param <C> coefficient type, e.g. BigRational, ModInteger. 143 * @return factorization algorithm implementation. 144 */ 145 public static <C extends GcdRingElem<C>> FactorAbstract<Quotient<C>> getImplementation(QuotientRing<C> fac) { 146 return new FactorQuotient<C>(fac); 147 } 148 149 150 /** 151 * Determine suitable implementation of factorization algorithms, case 152 * recursive GenPolynomial<C>. Use <code>recursiveFactors()</code>. 153 * @param fac GenPolynomialRing<C>. 154 * @param <C> coefficient type, e.g. BigRational, ModInteger. 155 * @return factorization algorithm implementation. 156 */ 157 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 158 return getImplementation(fac.coFac); 159 } 160 161 162 /** 163 * Determine suitable implementation of factorization algorithms, other 164 * cases. 165 * @param <C> coefficient type 166 * @param fac RingFactory<C>. 167 * @return factorization algorithm implementation. 168 */ 169 @SuppressWarnings("unchecked") 170 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(RingFactory<C> fac) { 171 logger.info("factor factory = " + fac.getClass().getName()); 172 //System.out.println("fac_o_ufd = " + fac.getClass().getName()); 173 FactorAbstract/*raw type<C>*/ufd = null; 174 AlgebraicNumberRing afac = null; 175 ComplexRing cfac = null; 176 QuotientRing qfac = null; 177 GenPolynomialRing pfac = null; 178 Object ofac = fac; 179 if (ofac instanceof BigInteger) { 180 ufd = new FactorInteger(); 181 } else if (ofac instanceof BigRational) { 182 ufd = new FactorRational(); 183 } else if (ofac instanceof ModIntegerRing) { 184 ufd = new FactorModular(fac); 185 } else if (ofac instanceof ModLongRing) { 186 ufd = new FactorModular(fac); 187 } else if (ofac instanceof ComplexRing) { 188 cfac = (ComplexRing<C>) ofac; 189 ufd = new FactorComplex(cfac); 190 } else if (ofac instanceof AlgebraicNumberRing) { 191 //System.out.println("afac_o = " + ofac); 192 afac = (AlgebraicNumberRing) ofac; 193 //ofac = afac.ring.coFac; 194 ufd = new FactorAlgebraic/*raw <C>*/(afac); 195 } else if (ofac instanceof QuotientRing) { 196 //System.out.println("qfac_o = " + ofac); 197 qfac = (QuotientRing) ofac; 198 ufd = new FactorQuotient/*raw <C>*/(qfac); 199 } else if (ofac instanceof GenPolynomialRing) { 200 //System.out.println("qfac_o = " + ofac); 201 pfac = (GenPolynomialRing) ofac; 202 ufd = getImplementation(pfac.coFac); 203 } else { 204 throw new IllegalArgumentException("no factorization implementation for " 205 + fac.getClass().getName()); 206 } 207 //logger.info("implementation = " + ufd); 208 return (FactorAbstract<C>) ufd; 209 } 210 211}