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