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