001/* 002 * $Id$ 003 */ 004 005package edu.jas.application; 006 007 008import org.apache.logging.log4j.LogManager; 009import org.apache.logging.log4j.Logger; 010 011import edu.jas.arith.Rational; 012import edu.jas.poly.AlgebraicNumber; 013import edu.jas.poly.AlgebraicNumberRing; 014import edu.jas.poly.Complex; 015import edu.jas.poly.ComplexRing; 016import edu.jas.poly.GenPolynomialRing; 017import edu.jas.root.RealAlgebraicNumber; 018import edu.jas.root.RealAlgebraicRing; 019import edu.jas.structure.GcdRingElem; 020import edu.jas.structure.RingFactory; 021import edu.jas.ufd.FactorAbstract; 022import edu.jas.ufd.FactorAlgebraic; 023import edu.jas.ufd.FactorComplex; 024import edu.jas.ufd.FactorQuotient; 025import edu.jas.ufd.Quotient; 026import edu.jas.ufd.QuotientRing; 027import edu.jas.ufdroot.FactorRealAlgebraic; 028 029 030/** 031 * Factorization algorithms factory. Select appropriate factorization engine 032 * based on the coefficient types. 033 * <p> 034 * <b>Usage:</b> To create objects that implement the <code>Factorization</code> 035 * interface use the <code>FactorFactory</code>. It will select an appropriate 036 * implementation based on the types of polynomial coefficients C. To obtain an 037 * implementation use <code>getImplementation()</code>, it returns an object of 038 * a class 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 * <p> 047 * For example, if the coefficient type is BigInteger, the usage looks 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 * @author Heinz Kredel 057 * 058 * @see edu.jas.ufd.Factorization#factors(edu.jas.poly.GenPolynomial P) 059 * @see edu.jas.ufd.FactorFactory#getImplementation(edu.jas.structure.RingFactory 060 * P) 061 */ 062 063public class FactorFactory extends edu.jas.ufd.FactorFactory { 064 065 066 private static final Logger logger = LogManager.getLogger(FactorFactory.class); 067 068 069 /** 070 * Protected factory constructor. 071 */ 072 protected FactorFactory() { 073 } 074 075 076 /** 077 * Determine suitable implementation of factorization algorithms, case 078 * AlgebraicNumber<C>. 079 * @param fac AlgebraicNumberRing<C>. 080 * @param <C> coefficient type, e.g. BigRational, ModInteger. 081 * @return factorization algorithm implementation. 082 */ 083 public static <C extends GcdRingElem<C>> FactorAbstract<AlgebraicNumber<C>> getImplementation( 084 AlgebraicNumberRing<C> fac) { 085 return new FactorAlgebraic<C>(fac, FactorFactory.<C> getImplementation(fac.ring.coFac)); 086 } 087 088 089 /** 090 * Determine suitable implementation of factorization algorithms, case 091 * Complex<C>. 092 * @param fac ComplexRing<C>. 093 * @param <C> coefficient type, e.g. BigRational, ModInteger. 094 * @return factorization algorithm implementation. 095 */ 096 public static <C extends GcdRingElem<C>> FactorAbstract<Complex<C>> getImplementation( 097 ComplexRing<C> fac) { 098 return new FactorComplex<C>(fac); 099 } 100 101 102 /** 103 * Determine suitable implementation of factorization algorithms, case 104 * Quotient<C>. 105 * @param fac QuotientRing<C>. 106 * @param <C> coefficient type, e.g. BigRational, ModInteger. 107 * @return factorization algorithm implementation. 108 */ 109 public static <C extends GcdRingElem<C>> FactorAbstract<Quotient<C>> getImplementation( 110 QuotientRing<C> fac) { 111 return new FactorQuotient<C>(fac, FactorFactory.<C> getImplementation(fac.ring.coFac)); 112 } 113 114 115 /** 116 * Determine suitable implementation of factorization algorithms, case 117 * recursive GenPolynomial<C>. Use <code>recursiveFactors()</code>. 118 * @param fac GenPolynomialRing<C>. 119 * @param <C> coefficient type, e.g. BigRational, ModInteger. 120 * @return factorization algorithm implementation. 121 */ 122 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(GenPolynomialRing<C> fac) { 123 return getImplementation(fac.coFac); 124 } 125 126 127 /** 128 * Determine suitable implementation of factorization algorithms, case 129 * RealAlgebraicNumber<C>. 130 * @param fac RealAlgebraicRing<C>. 131 * @param <C> coefficient type, e.g. BigRational. 132 * @return factorization algorithm implementation. 133 */ 134 public static <C extends GcdRingElem<C> & Rational> FactorAbstract<RealAlgebraicNumber<C>> getImplementation( 135 RealAlgebraicRing<C> fac) { 136 return new FactorRealAlgebraic<C>(fac, 137 FactorFactory.<AlgebraicNumber<C>> getImplementation(fac.algebraic)); 138 } 139 140 141 /** 142 * Determine suitable implementation of factorization algorithms, case 143 * RealAlgebraicNumber<C>. 144 * @param fac RealAlgebraicRing<C>. 145 * @param <C> coefficient type, e.g. BigRational. 146 * @return factorization algorithm implementation. 147 */ 148 @SuppressWarnings("unchecked") 149 public static <C extends GcdRingElem<C> & Rational> FactorAbstract<edu.jas.application.RealAlgebraicNumber<C>> getImplementation( 150 edu.jas.application.RealAlgebraicRing<C> fac) { 151 edu.jas.root.RealAlgebraicRing<C> rar = (edu.jas.root.RealAlgebraicRing<C>) (Object) fac.realRing; 152 return new FactorRealReal<C>(fac, 153 FactorFactory.<edu.jas.root.RealAlgebraicNumber<C>> getImplementation(rar)); 154 } 155 156 157 /** 158 * Determine suitable implementation of factorization algorithms, other 159 * cases. 160 * @param <C> coefficient type 161 * @param fac RingFactory<C>. 162 * @return factorization algorithm implementation. 163 */ 164 @SuppressWarnings("unchecked") 165 public static <C extends GcdRingElem<C>> FactorAbstract<C> getImplementation(RingFactory<C> fac) { 166 logger.info("app factor factory = {}", 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}