001/* 002 * $Id: FactorFactory.java 6010 2020-04-01 10:39:15Z kredel $ 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 //System.out.println("fac_o = " + fac.getClass().getName()); 168 FactorAbstract/*raw type<C>*/ ufd = null; 169 edu.jas.application.RealAlgebraicRing rrfac = null; 170 RealAlgebraicRing rfac = null; 171 AlgebraicNumberRing afac = null; 172 ComplexRing cfac = null; 173 QuotientRing qfac = null; 174 GenPolynomialRing pfac = null; 175 Object ofac = fac; 176 if (ofac instanceof edu.jas.application.RealAlgebraicRing) { 177 //System.out.println("rrfac_o = " + ofac); 178 rrfac = (edu.jas.application.RealAlgebraicRing) ofac; 179 //ofac = rrfac.realRing; 180 ufd = new FactorRealReal/*raw <C>*/(rrfac, 181 FactorFactory.<edu.jas.root.RealAlgebraicNumber> getImplementation( 182 rrfac.realRing)); 183 } else if (ofac instanceof edu.jas.root.RealAlgebraicRing) { 184 //System.out.println("rfac_o = " + ofac); 185 rfac = (edu.jas.root.RealAlgebraicRing) ofac; 186 //ofac = rfac.algebraic; 187 ufd = new FactorRealAlgebraic/*raw <C>*/(rfac, 188 FactorFactory.<AlgebraicNumber<C>> getImplementation(rfac.algebraic)); 189 } else if (ofac instanceof ComplexRing) { 190 cfac = (ComplexRing<C>) ofac; 191 afac = cfac.algebraicRing(); 192 ufd = new FactorComplex(cfac, FactorFactory.<C> getImplementation(afac)); 193 } else if (ofac instanceof AlgebraicNumberRing) { 194 //System.out.println("afac_o = " + ofac); 195 afac = (AlgebraicNumberRing) ofac; 196 //ofac = afac.ring.coFac; 197 ufd = new FactorAlgebraic/*raw <C>*/(afac, FactorFactory.<C> getImplementation(afac.ring.coFac)); 198 } else if (ofac instanceof QuotientRing) { 199 //System.out.println("qfac_o = " + ofac); 200 qfac = (QuotientRing) ofac; 201 ufd = new FactorQuotient/*raw <C>*/(qfac, FactorFactory.<C> getImplementation(qfac.ring.coFac)); 202 } else if (ofac instanceof GenPolynomialRing) { 203 //System.out.println("qfac_o = " + ofac); 204 pfac = (GenPolynomialRing) ofac; 205 ufd = getImplementation(pfac.coFac); 206 } else { 207 //System.out.println("no fac = " + fac.getClass().getName()); 208 ufd = edu.jas.ufd.FactorFactory.getImplementation(fac); 209 //return (FactorAbstract<C>) ufd; 210 } 211 //logger.info("implementation = " + ufd); 212 return (FactorAbstract<C>) ufd; 213 } 214 215}