001 /* 002 * $Id: GBFactory.java 3432 2010-12-24 14:28:19Z kredel $ 003 */ 004 005 package edu.jas.gbufd; 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.Product; 017 import edu.jas.arith.ProductRing; 018 import edu.jas.gb.DGroebnerBaseSeq; 019 import edu.jas.gb.EGroebnerBaseSeq; 020 import edu.jas.gb.GBProxy; 021 import edu.jas.gb.GroebnerBase; 022 import edu.jas.gb.GroebnerBaseAbstract; 023 import edu.jas.gb.GroebnerBaseParallel; 024 import edu.jas.gb.GroebnerBaseSeq; 025 import edu.jas.kern.ComputerThreads; 026 import edu.jas.poly.GenPolynomial; 027 import edu.jas.poly.GenPolynomialRing; 028 import edu.jas.structure.GcdRingElem; 029 import edu.jas.structure.RingElem; 030 import edu.jas.structure.RingFactory; 031 032 033 /** 034 * Groebner bases algorithms factory. Select appropriate Groebner bases engine 035 * based on the coefficient types. 036 * @author Heinz Kredel 037 * @usage To create objects that implement the <code>GroebnerBase</code> 038 * interface use the <code>GBFactory</code>. It will select an 039 * appropriate implementation based on the types of polynomial 040 * coefficients C. The method to obtain an implementation is 041 * <code>getImplementation()</code>. <code>getImplementation()</code> 042 * returns an object of a class which implements the 043 * <code>GroebnerBase</code> interface, more precisely an object of 044 * abstract class <code>GroebnerBaseAbstract</code>. 045 * 046 * <pre> 047 * GroebnerBase<CT> engine; 048 * engine = GBFactory.<CT> getImplementation(cofac); 049 * c = engine.GB(A); 050 * </pre> 051 * 052 * For example, if the coefficient type is BigInteger, the usage looks 053 * like 054 * 055 * <pre> 056 * BigInteger cofac = new BigInteger(); 057 * GroebnerBase<BigInteger> engine; 058 * engine = GBFactory.getImplementation(cofac); 059 * c = engine.GB(A); 060 * </pre> 061 * 062 * @see edu.jas.gb.GroebnerBase#GB(java.util.List P) 063 */ 064 065 public class GBFactory { 066 067 068 private static final Logger logger = Logger.getLogger(GBFactory.class); 069 070 071 public enum Algo { 072 igb, egb, dgb 073 }; 074 075 076 /** 077 * Protected factory constructor. 078 */ 079 protected GBFactory() { 080 } 081 082 083 /** 084 * Determine suitable implementation of GB algorithms, no factory case. 085 * @return GB algorithm implementation for field coefficients. 086 */ 087 public static <C extends GcdRingElem<C>> GroebnerBaseAbstract<C> getImplementation() { 088 logger.warn("no coefficent factory given, assuming field coeffcients"); 089 GroebnerBaseAbstract<C> bba = new GroebnerBaseSeq<C>(); 090 return bba; 091 } 092 093 094 /** 095 * Determine suitable implementation of GB algorithms, case ModLong. 096 * @param fac ModLongRing. 097 * @return GB algorithm implementation. 098 */ 099 public static GroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac) { 100 GroebnerBaseAbstract<ModLong> bba; 101 if (fac.isField()) { 102 bba = new GroebnerBaseSeq<ModLong>(); 103 } else { 104 bba = new GroebnerBasePseudoSeq<ModLong>(fac); 105 } 106 return bba; 107 } 108 109 110 /** 111 * Determine suitable implementation of GB algorithms, case ModInteger. 112 * @param fac ModIntegerRing. 113 * @return GB algorithm implementation. 114 */ 115 public static GroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac) { 116 GroebnerBaseAbstract<ModInteger> bba; 117 if (fac.isField()) { 118 bba = new GroebnerBaseSeq<ModInteger>(); 119 } else { 120 bba = new GroebnerBasePseudoSeq<ModInteger>(fac); 121 } 122 return bba; 123 } 124 125 126 /** 127 * Determine suitable implementation of GB algorithms, case BigInteger. 128 * @param fac BigInteger. 129 * @return GB algorithm implementation. 130 */ 131 public static GroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac) { 132 return getImplementation(fac, Algo.igb); 133 } 134 135 136 /** 137 * Determine suitable implementation of GB algorithms, case BigInteger. 138 * @param fac BigInteger. 139 * @param a algorithm. 140 * @return GB algorithm implementation. 141 */ 142 public static GroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, Algo a) { 143 GroebnerBaseAbstract<BigInteger> bba; 144 switch (a) { 145 case igb: 146 bba = new GroebnerBasePseudoSeq<BigInteger>(fac); 147 break; 148 case egb: 149 bba = new EGroebnerBaseSeq<BigInteger>(); 150 break; 151 case dgb: 152 bba = new DGroebnerBaseSeq<BigInteger>(); 153 break; 154 default: 155 throw new IllegalArgumentException("algorithm not available " + a); 156 } 157 return bba; 158 } 159 160 161 /** 162 * Determine suitable implementation of GB algorithms, case BigRational. 163 * @param fac BigRational. 164 * @return GB algorithm implementation. 165 */ 166 public static GroebnerBaseAbstract<BigRational> getImplementation(BigRational fac) { 167 GroebnerBaseAbstract<BigRational> bba; 168 bba = new GroebnerBaseSeq<BigRational>(); 169 return bba; 170 } 171 172 173 /** 174 * Determine suitable implementation of GB algorithms, case (recursive) 175 * polynomial. 176 * @param fac GenPolynomialRing<C>. 177 * @return GB algorithm implementation. 178 */ 179 public static <C extends GcdRingElem<C>> 180 GroebnerBaseAbstract<GenPolynomial<C>> getImplementation(GenPolynomialRing<C> fac) { 181 GroebnerBaseAbstract<GenPolynomial<C>> bba; 182 bba = new GroebnerBasePseudoRecSeq<C>(fac); 183 return bba; 184 } 185 186 187 /** 188 * Determine suitable implementation of GB algorithms, case regular rings. 189 * @param fac RegularRing. 190 * @return GB algorithm implementation. 191 */ 192 public static <C extends RingElem<C>> 193 GroebnerBaseAbstract<Product<C>> getImplementation(ProductRing<C> fac) { 194 GroebnerBaseAbstract<Product<C>> bba; 195 if (fac.onlyFields()) { 196 bba = new RGroebnerBaseSeq<Product<C>>(); 197 } else { 198 bba = new RGroebnerBasePseudoSeq<Product<C>>(fac); 199 } 200 return bba; 201 } 202 203 204 /** 205 * Determine suitable implementation of GB algorithms, other cases. 206 * @param fac RingFactory<C>. 207 * @return GB algorithm implementation. 208 */ 209 //@SuppressWarnings("unchecked") 210 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 211 GroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac) { 212 logger.debug("fac = " + fac.getClass().getName()); 213 if (fac.isField()) { 214 return new GroebnerBaseSeq<C>(); 215 //return new GroebnerBaseSeq<C>(new ReductionSeq<C>(),new OrderedSyzPairlist<C>()); 216 } 217 GroebnerBaseAbstract bba = null; 218 Object ofac = fac; 219 if (ofac instanceof GenPolynomialRing) { 220 GenPolynomialRing<C> rofac = (GenPolynomialRing<C>) ofac; 221 GroebnerBaseAbstract<GenPolynomial<C>> bbr = new GroebnerBasePseudoRecSeq<C>(rofac); 222 bba = (GroebnerBaseAbstract) bbr; 223 } else if (ofac instanceof ProductRing) { 224 ProductRing pfac = (ProductRing) ofac; 225 if (pfac.onlyFields()) { 226 bba = new RGroebnerBaseSeq<Product<C>>(); 227 } else { 228 bba = new RGroebnerBasePseudoSeq<Product<C>>(pfac); 229 } 230 } else { 231 bba = new GroebnerBasePseudoSeq<C>(fac); 232 } 233 logger.debug("bba = " + bba.getClass().getName()); 234 return bba; 235 } 236 237 238 /** 239 * Determine suitable concurrent implementation of GB algorithms if 240 * possible. 241 * @param fac RingFactory<C>. 242 * @return GB proxy algorithm implementation. 243 */ 244 //@SuppressWarnings("unchecked") 245 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 246 GroebnerBaseAbstract<C> getProxy(RingFactory<C> fac) { 247 logger.debug("fac = " + fac.getClass().getName()); 248 if (fac.isField()) { 249 if (ComputerThreads.NO_THREADS) { 250 return new GroebnerBaseSeq<C>(); 251 } 252 GroebnerBaseAbstract<C> e1 = new GroebnerBaseSeq<C>(); 253 //GroebnerBaseAbstract<C> e1 = new GroebnerBaseSeq<C>(new ReductionSeq<C>(),new OrderedSyzPairlist<C>()); 254 GroebnerBaseAbstract<C> e2 = new GroebnerBaseParallel<C>(ComputerThreads.N_CPUS); 255 //GroebnerBaseAbstract<C> e2 = new GroebnerBaseParallel<C>(ComputerThreads.N_CPUS, 256 // new ReductionPar<C>(),new OrderedSyzPairlist<C>()); 257 return new GBProxy<C>(e1, e2); 258 } 259 GroebnerBaseAbstract bba = null; 260 Object ofac = fac; 261 if (ofac instanceof GenPolynomialRing) { 262 GenPolynomialRing<C> rofac = (GenPolynomialRing<C>) ofac; 263 GroebnerBaseAbstract<GenPolynomial<C>> bbr = new GroebnerBasePseudoRecSeq<C>(rofac); 264 bba = (GroebnerBaseAbstract) bbr; 265 } else if (ofac instanceof ProductRing) { 266 ProductRing pfac = (ProductRing) ofac; 267 if (pfac.onlyFields()) { 268 bba = new RGroebnerBaseSeq<Product<C>>(); 269 } else { 270 bba = new RGroebnerBasePseudoSeq<Product<C>>(pfac); 271 } 272 } else { 273 bba = new GroebnerBasePseudoSeq<C>(fac); 274 } 275 logger.debug("bba = " + bba.getClass().getName()); 276 return bba; 277 } 278 279 }