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 }