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