001 /* 002 * $Id: FactorFactory.java 3676 2011-07-02 10:51:16Z kredel $ 003 */ 004 005 package edu.jas.ufd; 006 007 008 import org.apache.log4j.Logger; 009 010 import edu.jas.arith.BigInteger; 011 import edu.jas.arith.BigRational; 012 import edu.jas.arith.ModInteger; 013 import edu.jas.arith.ModIntegerRing; 014 import edu.jas.arith.ModLong; 015 import edu.jas.arith.ModLongRing; 016 import edu.jas.arith.Rational; 017 import edu.jas.poly.AlgebraicNumber; 018 import edu.jas.poly.AlgebraicNumberRing; 019 import edu.jas.poly.Complex; 020 import edu.jas.poly.ComplexRing; 021 import edu.jas.poly.GenPolynomialRing; 022 import edu.jas.root.RealAlgebraicNumber; 023 import edu.jas.root.RealAlgebraicRing; 024 import edu.jas.structure.GcdRingElem; 025 import edu.jas.structure.RingFactory; 026 027 028 /** 029 * Factorization algorithms factory. Select appropriate factorization engine 030 * based on the coefficient types. 031 * @author Heinz Kredel 032 * @usage To create objects that implement the <code>Factorization</code> 033 * interface use the <code>FactorFactory</code>. It will select an 034 * appropriate implementation based on the types of polynomial 035 * coefficients C. To obtain an implementation use 036 * <code>getImplementation()</code>, it returns an object of a class 037 * which extends the <code>FactorAbstract</code> class which implements 038 * the <code>Factorization</code> interface. 039 * 040 * <pre> 041 * Factorization<CT> engine; 042 * engine = FactorFactory.<CT> getImplementation(cofac); 043 * c = engine.factors(a); 044 * </pre> 045 * 046 * For example, if the coefficient type is BigInteger, the usage looks 047 * like 048 * 049 * <pre> 050 * BigInteger cofac = new BigInteger(); 051 * Factorization<BigInteger> engine; 052 * engine = FactorFactory.getImplementation(cofac); 053 * Sm = engine.factors(poly); 054 * </pre> 055 * 056 * @see edu.jas.ufd.Factorization#factors(edu.jas.poly.GenPolynomial P) 057 */ 058 059 public class FactorFactory { 060 061 062 private static final Logger logger = Logger.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 * BigInteger. 097 * @param fac BigInteger. 098 * @return factorization algorithm implementation. 099 */ 100 public static FactorAbstract<BigInteger> getImplementation(BigInteger fac) { 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 return new FactorRational(); 113 } 114 115 116 /** 117 * Determine suitable implementation of factorization algorithms, case 118 * AlgebraicNumber<C>. 119 * @param fac AlgebraicNumberRing<C>. 120 * @param <C> coefficient type, e.g. BigRational, ModInteger. 121 * @return factorization algorithm implementation. 122 */ 123 public static <C extends GcdRingElem<C>> FactorAbstract<AlgebraicNumber<C>> getImplementation( 124 AlgebraicNumberRing<C> fac) { 125 return new FactorAlgebraic<C>(fac); 126 } 127 128 129 /** 130 * Determine suitable implementation of factorization algorithms, case 131 * Complex<C>. 132 * @param fac ComplexRing<C>. 133 * @param <C> coefficient type, e.g. BigRational, ModInteger. 134 * @return factorization algorithm implementation. 135 */ 136 public static <C extends GcdRingElem<C>> FactorAbstract<Complex<C>> getImplementation(ComplexRing<C> fac) { 137 return new FactorComplex<C>(fac); 138 } 139 140 141 /** 142 * Determine suitable implementation of factorization algorithms, case 143 * Quotient<C>. 144 * @param fac QuotientRing<C>. 145 * @param <C> coefficient type, e.g. BigRational, ModInteger. 146 * @return factorization algorithm implementation. 147 */ 148 public static <C extends GcdRingElem<C>> FactorAbstract<Quotient<C>> getImplementation(QuotientRing<C> fac) { 149 return new FactorQuotient<C>(fac); 150 } 151 152 153 /** 154 * Determine suitable implementation of factorization algorithms, case 155 * recursive GenPolynomial<C>. Use <code>recursiveFactors()</code>. 156 * @param fac GenPolynomialRing<C>. 157 * @param <C> coefficient type, e.g. BigRational, ModInteger. 158 * @return factorization algorithm implementation. 159 */ 160 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 161 return getImplementation(fac.coFac); 162 } 163 164 165 /** 166 * Determine suitable implementation of factorization algorithms, case 167 * RealAlgebraicNumber<C>. 168 * @param fac RealAlgebraicRing<C>. 169 * @param <C> coefficient type, e.g. BigRational. 170 * @return factorization algorithm implementation. 171 */ 172 public static <C extends GcdRingElem<C> & Rational> FactorAbstract<RealAlgebraicNumber<C>> getImplementation( 173 RealAlgebraicRing<C> fac) { 174 return new FactorRealAlgebraic<C>(fac); 175 } 176 177 178 /** 179 * Determine suitable implementation of factorization algorithms, other 180 * cases. 181 * @param <C> coefficient type 182 * @param fac RingFactory<C>. 183 * @return factorization algorithm implementation. 184 */ 185 @SuppressWarnings("unchecked") 186 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(RingFactory<C> fac) { 187 //logger.info("fac = " + fac.getClass().getName()); 188 //System.out.println("fac_o = " + fac.getClass().getName()); 189 FactorAbstract/*raw type<C>*/ufd = null; 190 AlgebraicNumberRing afac = null; 191 RealAlgebraicRing rfac = null; 192 QuotientRing qfac = null; 193 GenPolynomialRing pfac = null; 194 Object ofac = fac; 195 if (ofac instanceof BigInteger) { 196 ufd = new FactorInteger(); 197 } else if (ofac instanceof BigRational) { 198 ufd = new FactorRational(); 199 } else if (ofac instanceof ModIntegerRing) { 200 ufd = new FactorModular(fac); 201 } else if (ofac instanceof ModLongRing) { 202 ufd = new FactorModular(fac); 203 } else if (ofac instanceof ComplexRing) { 204 ufd = new FactorComplex(fac); 205 } else if (ofac instanceof AlgebraicNumberRing) { 206 //System.out.println("afac_o = " + ofac); 207 afac = (AlgebraicNumberRing) ofac; 208 ofac = afac.ring.coFac; 209 ufd = new FactorAlgebraic/*raw <C>*/(afac); 210 } else if (ofac instanceof QuotientRing) { 211 //System.out.println("qfac_o = " + ofac); 212 qfac = (QuotientRing) ofac; 213 ufd = new FactorQuotient/*raw <C>*/(qfac); 214 } else if (ofac instanceof GenPolynomialRing) { 215 //System.out.println("qfac_o = " + ofac); 216 pfac = (GenPolynomialRing) ofac; 217 ufd = getImplementation(pfac.coFac); 218 } else if (ofac instanceof RealAlgebraicRing) { 219 //System.out.println("rfac_o = " + ofac); 220 rfac = (RealAlgebraicRing) ofac; 221 ofac = rfac.algebraic; 222 ufd = new FactorRealAlgebraic/*raw <C>*/(rfac); 223 } else { 224 throw new IllegalArgumentException("no factorization implementation for " 225 + fac.getClass().getName()); 226 } 227 logger.info("implementation = " + ufd); 228 return (FactorAbstract<C>) ufd; 229 } 230 231 }