001/* 002 * $Id: FactorFactory.java 6010 2020-04-01 10:39:15Z kredel $ 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 public static <C extends GcdRingElem<C>> FactorAbstract<AlgebraicNumber<C>> getImplementation( 141 AlgebraicNumberRing<C> fac) { 142 return new FactorAlgebraic<C>(fac); 143 } 144 145 146 /** 147 * Determine suitable implementation of factorization algorithms, case 148 * Complex<C>. 149 * @param fac ComplexRing<C>. 150 * @param <C> coefficient type, e.g. BigRational, ModInteger. 151 * @return factorization algorithm implementation. 152 */ 153 public static <C extends GcdRingElem<C>> FactorAbstract<Complex<C>> getImplementation( 154 ComplexRing<C> fac) { 155 return new FactorComplex<C>(fac); 156 } 157 158 159 /** 160 * Determine suitable implementation of factorization algorithms, case 161 * Quotient<C>. 162 * @param fac QuotientRing<C>. 163 * @param <C> coefficient type, e.g. BigRational, ModInteger. 164 * @return factorization algorithm implementation. 165 */ 166 public static <C extends GcdRingElem<C>> FactorAbstract<Quotient<C>> getImplementation( 167 QuotientRing<C> fac) { 168 return new FactorQuotient<C>(fac); 169 } 170 171 172 /** 173 * Determine suitable implementation of factorization algorithms, case 174 * recursive GenPolynomial<C>. Use <code>recursiveFactors()</code>. 175 * @param fac GenPolynomialRing<C>. 176 * @param <C> coefficient type, e.g. BigRational, ModInteger. 177 * @return factorization algorithm implementation. 178 */ 179 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 180 return getImplementation(fac.coFac); 181 } 182 183 184 /** 185 * Determine suitable implementation of factorization algorithms, other 186 * cases. 187 * @param <C> coefficient type 188 * @param fac RingFactory<C>. 189 * @return factorization algorithm implementation. 190 */ 191 @SuppressWarnings({ "unchecked", "cast" }) 192 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(RingFactory<C> fac) { 193 logger.info("factor factory = " + fac.getClass().getName()); 194 //System.out.println("fac_o_ufd = " + fac.getClass().getName()); 195 FactorAbstract/*raw type<C>*/ ufd = null; 196 AlgebraicNumberRing afac = null; 197 ComplexRing cfac = null; 198 QuotientRing qfac = null; 199 GenPolynomialRing pfac = null; 200 Object ofac = fac; 201 if (ofac instanceof BigInteger) { 202 ufd = new FactorInteger(); 203 } else if (ofac instanceof BigRational) { 204 ufd = new FactorRational(); 205 } else if (ofac instanceof ModIntegerRing) { 206 ufd = new FactorModular(fac); 207 } else if (ofac instanceof ModLongRing) { 208 ufd = new FactorModular(fac); 209 } else if (ofac instanceof ModIntRing) { 210 ufd = new FactorModular(fac); 211 } else if (ofac instanceof ComplexRing) { 212 cfac = (ComplexRing<C>) ofac; 213 ufd = new FactorComplex(cfac); 214 } else if (ofac instanceof AlgebraicNumberRing) { 215 //System.out.println("afac_o = " + ofac); 216 afac = (AlgebraicNumberRing) ofac; 217 //ofac = afac.ring.coFac; 218 ufd = new FactorAlgebraic/*raw <C>*/(afac); 219 } else if (ofac instanceof QuotientRing) { 220 //System.out.println("qfac_o = " + ofac); 221 qfac = (QuotientRing) ofac; 222 ufd = new FactorQuotient/*raw <C>*/(qfac); 223 } else if (ofac instanceof GenPolynomialRing) { 224 //System.out.println("qfac_o = " + ofac); 225 pfac = (GenPolynomialRing) ofac; 226 ufd = getImplementation(pfac.coFac); 227 } else { 228 throw new IllegalArgumentException( 229 "no factorization implementation for " + fac.getClass().getName()); 230 } 231 //logger.info("implementation = " + ufd); 232 return (FactorAbstract<C>) ufd; 233 } 234 235}