001/* 002 * $Id: FactorFactory.java 5047 2014-12-30 17:44:11Z 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 @SuppressWarnings("unused") 098 public static FactorAbstract<BigInteger> getImplementation(BigInteger fac) { 099 return new FactorInteger<ModLong>(); 100 } 101 102 103 /** 104 * Determine suitable implementation of factorization algorithms, case 105 * BigRational. 106 * @param fac BigRational. 107 * @return factorization algorithm implementation. 108 */ 109 @SuppressWarnings("unused") 110 public static FactorAbstract<BigRational> getImplementation(BigRational fac) { 111 return new FactorRational(); 112 } 113 114 115 /** 116 * Determine suitable implementation of factorization algorithms, case 117 * AlgebraicNumber<C>. 118 * @param fac AlgebraicNumberRing<C>. 119 * @param <C> coefficient type, e.g. BigRational, ModInteger. 120 * @return factorization algorithm implementation. 121 */ 122 public static <C extends GcdRingElem<C>> FactorAbstract<AlgebraicNumber<C>> getImplementation( 123 AlgebraicNumberRing<C> fac) { 124 return new FactorAlgebraic<C>(fac); 125 } 126 127 128 /** 129 * Determine suitable implementation of factorization algorithms, case 130 * Complex<C>. 131 * @param fac ComplexRing<C>. 132 * @param <C> coefficient type, e.g. BigRational, ModInteger. 133 * @return factorization algorithm implementation. 134 */ 135 public static <C extends GcdRingElem<C>> FactorAbstract<Complex<C>> getImplementation(ComplexRing<C> fac) { 136 return new FactorComplex<C>(fac); 137 } 138 139 140 /** 141 * Determine suitable implementation of factorization algorithms, case 142 * Quotient<C>. 143 * @param fac QuotientRing<C>. 144 * @param <C> coefficient type, e.g. BigRational, ModInteger. 145 * @return factorization algorithm implementation. 146 */ 147 public static <C extends GcdRingElem<C>> FactorAbstract<Quotient<C>> getImplementation(QuotientRing<C> fac) { 148 return new FactorQuotient<C>(fac); 149 } 150 151 152 /** 153 * Determine suitable implementation of factorization algorithms, case 154 * recursive GenPolynomial<C>. Use <code>recursiveFactors()</code>. 155 * @param fac GenPolynomialRing<C>. 156 * @param <C> coefficient type, e.g. BigRational, ModInteger. 157 * @return factorization algorithm implementation. 158 */ 159 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 160 return getImplementation(fac.coFac); 161 } 162 163 164 /** 165 * Determine suitable implementation of factorization algorithms, other 166 * cases. 167 * @param <C> coefficient type 168 * @param fac RingFactory<C>. 169 * @return factorization algorithm implementation. 170 */ 171 @SuppressWarnings("unchecked") 172 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(RingFactory<C> fac) { 173 logger.info("factor factory = " + fac.getClass().getName()); 174 //System.out.println("fac_o_ufd = " + fac.getClass().getName()); 175 FactorAbstract/*raw type<C>*/ufd = null; 176 AlgebraicNumberRing afac = null; 177 ComplexRing cfac = null; 178 QuotientRing qfac = null; 179 GenPolynomialRing pfac = null; 180 Object ofac = fac; 181 if (ofac instanceof BigInteger) { 182 ufd = new FactorInteger(); 183 } else if (ofac instanceof BigRational) { 184 ufd = new FactorRational(); 185 } else if (ofac instanceof ModIntegerRing) { 186 ufd = new FactorModular(fac); 187 } else if (ofac instanceof ModLongRing) { 188 ufd = new FactorModular(fac); 189 } else if (ofac instanceof ComplexRing) { 190 cfac = (ComplexRing<C>) ofac; 191 ufd = new FactorComplex(cfac); 192 } else if (ofac instanceof AlgebraicNumberRing) { 193 //System.out.println("afac_o = " + ofac); 194 afac = (AlgebraicNumberRing) ofac; 195 //ofac = afac.ring.coFac; 196 ufd = new FactorAlgebraic/*raw <C>*/(afac); 197 } else if (ofac instanceof QuotientRing) { 198 //System.out.println("qfac_o = " + ofac); 199 qfac = (QuotientRing) ofac; 200 ufd = new FactorQuotient/*raw <C>*/(qfac); 201 } else if (ofac instanceof GenPolynomialRing) { 202 //System.out.println("qfac_o = " + ofac); 203 pfac = (GenPolynomialRing) ofac; 204 ufd = getImplementation(pfac.coFac); 205 } else { 206 throw new IllegalArgumentException("no factorization implementation for " 207 + fac.getClass().getName()); 208 } 209 //logger.info("implementation = " + ufd); 210 return (FactorAbstract<C>) ufd; 211 } 212 213}