001/* 002 * $Id: FactorFactory.java 5611 2016-10-03 22:06:32Z 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( 096 ComplexRing<C> fac) { 097 return new FactorComplex<C>(fac); 098 } 099 100 101 /** 102 * Determine suitable implementation of factorization algorithms, case 103 * Quotient<C>. 104 * @param fac QuotientRing<C>. 105 * @param <C> coefficient type, e.g. BigRational, ModInteger. 106 * @return factorization algorithm implementation. 107 */ 108 public static <C extends GcdRingElem<C>> FactorAbstract<Quotient<C>> getImplementation( 109 QuotientRing<C> fac) { 110 return new FactorQuotient<C>(fac, FactorFactory.<C> getImplementation(fac.ring.coFac)); 111 } 112 113 114 /** 115 * Determine suitable implementation of factorization algorithms, case 116 * recursive GenPolynomial<C>. Use <code>recursiveFactors()</code>. 117 * @param fac GenPolynomialRing<C>. 118 * @param <C> coefficient type, e.g. BigRational, ModInteger. 119 * @return factorization algorithm implementation. 120 */ 121 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 122 return getImplementation(fac.coFac); 123 } 124 125 126 /** 127 * Determine suitable implementation of factorization algorithms, case 128 * RealAlgebraicNumber<C>. 129 * @param fac RealAlgebraicRing<C>. 130 * @param <C> coefficient type, e.g. BigRational. 131 * @return factorization algorithm implementation. 132 */ 133 public static <C extends GcdRingElem<C> & Rational> FactorAbstract<RealAlgebraicNumber<C>> getImplementation( 134 RealAlgebraicRing<C> fac) { 135 return new FactorRealAlgebraic<C>(fac, 136 FactorFactory.<AlgebraicNumber<C>> getImplementation(fac.algebraic)); 137 } 138 139 140 /** 141 * Determine suitable implementation of factorization algorithms, case 142 * RealAlgebraicNumber<C>. 143 * @param fac RealAlgebraicRing<C>. 144 * @param <C> coefficient type, e.g. BigRational. 145 * @return factorization algorithm implementation. 146 */ 147 @SuppressWarnings("unchecked") 148 public static <C extends GcdRingElem<C> & Rational> FactorAbstract<edu.jas.application.RealAlgebraicNumber<C>> getImplementation( 149 edu.jas.application.RealAlgebraicRing<C> fac) { 150 edu.jas.root.RealAlgebraicRing<C> rar = (edu.jas.root.RealAlgebraicRing<C>) (Object) fac.realRing; 151 return new FactorRealReal<C>(fac, 152 FactorFactory.<edu.jas.root.RealAlgebraicNumber<C>> getImplementation(rar)); 153 } 154 155 156 /** 157 * Determine suitable implementation of factorization algorithms, other 158 * cases. 159 * @param <C> coefficient type 160 * @param fac RingFactory<C>. 161 * @return factorization algorithm implementation. 162 */ 163 @SuppressWarnings("cast") 164 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(RingFactory<C> fac) { 165 logger.info("app factor factory = " + fac.getClass().getName()); 166 //System.out.println("fac_o = " + fac.getClass().getName()); 167 FactorAbstract/*raw type<C>*/ ufd = null; 168 edu.jas.application.RealAlgebraicRing rrfac = null; 169 RealAlgebraicRing rfac = null; 170 AlgebraicNumberRing afac = null; 171 ComplexRing cfac = null; 172 QuotientRing qfac = null; 173 GenPolynomialRing pfac = null; 174 Object ofac = fac; 175 if (ofac instanceof edu.jas.application.RealAlgebraicRing) { 176 //System.out.println("rrfac_o = " + ofac); 177 rrfac = (edu.jas.application.RealAlgebraicRing) ofac; 178 //ofac = rrfac.realRing; 179 ufd = new FactorRealReal/*raw <C>*/(rrfac, 180 FactorFactory.<edu.jas.root.RealAlgebraicNumber> getImplementation( 181 rrfac.realRing)); 182 } else if (ofac instanceof edu.jas.root.RealAlgebraicRing) { 183 //System.out.println("rfac_o = " + ofac); 184 rfac = (edu.jas.root.RealAlgebraicRing) ofac; 185 //ofac = rfac.algebraic; 186 ufd = new FactorRealAlgebraic/*raw <C>*/(rfac, 187 FactorFactory.<AlgebraicNumber<C>> getImplementation(rfac.algebraic)); 188 } else if (ofac instanceof ComplexRing) { 189 cfac = (ComplexRing<C>) ofac; 190 afac = cfac.algebraicRing(); 191 ufd = new FactorComplex(cfac, FactorFactory.<C> getImplementation(afac)); 192 } else if (ofac instanceof AlgebraicNumberRing) { 193 //System.out.println("afac_o = " + ofac); 194 afac = (AlgebraicNumberRing) ofac; 195 //ofac = afac.ring.coFac; 196 ufd = new FactorAlgebraic/*raw <C>*/(afac, FactorFactory.<C> getImplementation(afac.ring.coFac)); 197 } else if (ofac instanceof QuotientRing) { 198 //System.out.println("qfac_o = " + ofac); 199 qfac = (QuotientRing) ofac; 200 ufd = new FactorQuotient/*raw <C>*/(qfac, FactorFactory.<C> getImplementation(qfac.ring.coFac)); 201 } else if (ofac instanceof GenPolynomialRing) { 202 //System.out.println("qfac_o = " + ofac); 203 pfac = (GenPolynomialRing) ofac; 204 ufd = getImplementation(pfac.coFac); 205 } else { 206 //System.out.println("no fac = " + fac.getClass().getName()); 207 ufd = edu.jas.ufd.FactorFactory.getImplementation(fac); 208 //return (FactorAbstract<C>) ufd; 209 } 210 //logger.info("implementation = " + ufd); 211 return (FactorAbstract<C>) ufd; 212 } 213 214}