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 }