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