001/* 002 * $Id: SGBFactory.java 5225 2015-04-19 10:08:35Z kredel $ 003 */ 004 005package edu.jas.gbufd; 006 007 008import org.apache.log4j.Logger; 009 010import edu.jas.arith.BigInteger; 011import edu.jas.arith.BigRational; 012import edu.jas.arith.ModInteger; 013import edu.jas.arith.ModIntegerRing; 014import edu.jas.arith.ModLong; 015import edu.jas.arith.ModLongRing; 016import edu.jas.gb.OrderedMinPairlist; 017import edu.jas.gb.OrderedPairlist; 018import edu.jas.gb.OrderedSyzPairlist; 019import edu.jas.gb.PairList; 020import edu.jas.gb.SGBProxy; 021import edu.jas.gb.SolvableGroebnerBaseAbstract; 022import edu.jas.gb.SolvableGroebnerBaseParallel; 023import edu.jas.gb.SolvableGroebnerBaseSeq; 024import edu.jas.gb.SolvableReductionSeq; 025import edu.jas.kern.ComputerThreads; 026import edu.jas.poly.GenPolynomial; 027import edu.jas.poly.GenPolynomialRing; 028import edu.jas.structure.GcdRingElem; 029import edu.jas.structure.QuotPairFactory; 030import edu.jas.structure.RingFactory; 031import edu.jas.structure.ValueFactory; 032import edu.jas.ufd.Quotient; 033import edu.jas.ufd.QuotientRing; 034 035 036// import edu.jas.application.SolvableResidueRing; // package cycle 037 038 039/** 040 * Solvable Groebner bases algorithms factory. Select appropriate Solvable 041 * Groebner bases engine based on the coefficient types. 042 * @author Heinz Kredel 043 * @usage To create objects that implement the <code>SolvableGroebnerBase</code> 044 * interface use the <code>SGBFactory</code>. It will select an 045 * appropriate implementation based on the types of polynomial 046 * coefficients C. The method to obtain an implementation is 047 * <code>getImplementation()</code>. It returns an object of a class 048 * which implements the <code>SolvableGroebnerBase</code> interface, more 049 * precisely an object of abstract class 050 * <code>SolvableGroebnerBaseAbstract</code>. 051 * 052 * <pre> 053 * 054 * SolvableGroebnerBase<CT> engine; 055 * engine = SGBFactory.<CT> getImplementation(cofac); 056 * c = engine.GB(A); 057 * </pre> 058 * 059 * For example, if the coefficient type is BigInteger, the usage looks 060 * like 061 * 062 * <pre> 063 * 064 * BigInteger cofac = new BigInteger(); 065 * SolvableGroebnerBase<BigInteger> engine; 066 * engine = SGBFactory.getImplementation(cofac); 067 * c = engine.GB(A); 068 * </pre> 069 * 070 * @see edu.jas.gb.GroebnerBase 071 * @see edu.jas.gb.SolvableGroebnerBase 072 * @see edu.jas.application.GBAlgorithmBuilder 073 */ 074 075public class SGBFactory { 076 077 078 private static final Logger logger = Logger.getLogger(SGBFactory.class); 079 080 081 /** 082 * Protected factory constructor. 083 */ 084 protected SGBFactory() { 085 } 086 087 088 /** 089 * Determine suitable implementation of GB algorithms, no factory case. 090 * @return GB algorithm implementation for field coefficients. 091 */ 092 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<C> getImplementation() { 093 logger.warn("no coefficent factory given, assuming field coeffcients"); 094 SolvableGroebnerBaseAbstract<C> bba = new SolvableGroebnerBaseSeq<C>(); 095 return bba; 096 } 097 098 099 /** 100 * Determine suitable implementation of GB algorithms, case ModLong. 101 * @param fac ModLongRing. 102 * @return GB algorithm implementation. 103 */ 104 public static SolvableGroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac) { 105 return getImplementation(fac, new OrderedPairlist<ModLong>()); 106 } 107 108 109 /** 110 * Determine suitable implementation of GB algorithms, case ModLong. 111 * @param fac ModLongRing. 112 * @param pl pair selection strategy 113 * @return GB algorithm implementation. 114 */ 115 public static SolvableGroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac, 116 PairList<ModLong> pl) { 117 SolvableGroebnerBaseAbstract<ModLong> bba; 118 if (fac.isField()) { 119 bba = new SolvableGroebnerBaseSeq<ModLong>(pl); 120 } else { 121 bba = new SolvableGroebnerBasePseudoSeq<ModLong>(fac, pl); 122 } 123 return bba; 124 } 125 126 127 /** 128 * Determine suitable implementation of GB algorithms, case ModInteger. 129 * @param fac ModIntegerRing. 130 * @return GB algorithm implementation. 131 */ 132 public static SolvableGroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac) { 133 return getImplementation(fac, new OrderedPairlist<ModInteger>()); 134 } 135 136 137 /** 138 * Determine suitable implementation of GB algorithms, case ModInteger. 139 * @param fac ModIntegerRing. 140 * @param pl pair selection strategy 141 * @return GB algorithm implementation. 142 */ 143 public static SolvableGroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac, 144 PairList<ModInteger> pl) { 145 SolvableGroebnerBaseAbstract<ModInteger> bba; 146 if (fac.isField()) { 147 bba = new SolvableGroebnerBaseSeq<ModInteger>(pl); 148 } else { 149 bba = new SolvableGroebnerBasePseudoSeq<ModInteger>(fac, pl); 150 } 151 return bba; 152 } 153 154 155 /** 156 * Determine suitable implementation of GB algorithms, case BigInteger. 157 * @param fac BigInteger. 158 * @return GB algorithm implementation. 159 */ 160 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac) { 161 return getImplementation(fac, GBFactory.Algo.igb); 162 } 163 164 165 /** 166 * Determine suitable implementation of GB algorithms, case BigInteger. 167 * @param fac BigInteger. 168 * @param a algorithm, a = igb, egb, dgb. 169 * @return GB algorithm implementation. 170 */ 171 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, GBFactory.Algo a) { 172 return getImplementation(fac, a, new OrderedPairlist<BigInteger>()); 173 } 174 175 176 /** 177 * Determine suitable implementation of GB algorithms, case BigInteger. 178 * @param fac BigInteger. 179 * @param pl pair selection strategy 180 * @return GB algorithm implementation. 181 */ 182 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, 183 PairList<BigInteger> pl) { 184 return getImplementation(fac, GBFactory.Algo.igb, pl); 185 } 186 187 188 /** 189 * Determine suitable implementation of GB algorithms, case BigInteger. 190 * @param fac BigInteger. 191 * @param a algorithm, a = igb, egb, dgb. 192 * @param pl pair selection strategy 193 * @return GB algorithm implementation. 194 */ 195 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, 196 GBFactory.Algo a, PairList<BigInteger> pl) { 197 SolvableGroebnerBaseAbstract<BigInteger> bba; 198 switch (a) { 199 case igb: 200 bba = new SolvableGroebnerBasePseudoSeq<BigInteger>(fac, pl); 201 break; 202 case egb: 203 throw new UnsupportedOperationException("egb algorithm not available for BigInteger " + a); 204 case dgb: 205 throw new UnsupportedOperationException("dgb algorithm not available for BigInteger " + a); 206 default: 207 throw new IllegalArgumentException("algorithm not available for BigInteger " + a); 208 } 209 return bba; 210 } 211 212 213 /** 214 * Determine suitable implementation of GB algorithms, case BigRational. 215 * @param fac BigRational. 216 * @return GB algorithm implementation. 217 */ 218 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac) { 219 return getImplementation(fac, GBFactory.Algo.qgb); 220 } 221 222 223 /** 224 * Determine suitable implementation of GB algorithms, case BigRational. 225 * @param fac BigRational. 226 * @param a algorithm, a = qgb, ffgb. 227 * @return GB algorithm implementation. 228 */ 229 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac, 230 GBFactory.Algo a) { 231 return getImplementation(fac, a, new OrderedPairlist<BigRational>()); 232 } 233 234 235 /** 236 * Determine suitable implementation of GB algorithms, case BigRational. 237 * @param fac BigRational. 238 * @param pl pair selection strategy 239 * @return GB algorithm implementation. 240 */ 241 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac, 242 PairList<BigRational> pl) { 243 return getImplementation(fac, GBFactory.Algo.qgb, pl); 244 } 245 246 247 /** 248 * Determine suitable implementation of GB algorithms, case BigRational. 249 * @param fac BigRational. 250 * @param a algorithm, a = qgb, ffgb. 251 * @param pl pair selection strategy 252 * @return GB algorithm implementation. 253 */ 254 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac, 255 GBFactory.Algo a, PairList<BigRational> pl) { 256 SolvableGroebnerBaseAbstract<BigRational> bba; 257 switch (a) { 258 case qgb: 259 bba = new SolvableGroebnerBaseSeq<BigRational>(pl); 260 break; 261 case ffgb: 262 throw new UnsupportedOperationException("ffgb algorithm not available for BigRational " + a); 263 //PairList<BigInteger> pli; 264 //if (pl instanceof OrderedMinPairlist) { 265 // pli = new OrderedMinPairlist<BigInteger>(); 266 //} else if (pl instanceof OrderedSyzPairlist) { 267 // pli = new OrderedSyzPairlist<BigInteger>(); 268 //} else { 269 // pli = new OrderedPairlist<BigInteger>(); 270 //} 271 //bba = new SolvableGroebnerBaseRational<BigRational>(pli); // pl not possible 272 //break; 273 default: 274 throw new IllegalArgumentException("algorithm not available for " + fac.toScriptFactory() 275 + ", Algo = " + a); 276 } 277 return bba; 278 } 279 280 281 /** 282 * Determine suitable implementation of GB algorithms, case Quotient 283 * coefficients. 284 * @param fac QuotientRing. 285 * @return GB algorithm implementation. 286 */ 287 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 288 QuotientRing<C> fac) { 289 return getImplementation(fac, GBFactory.Algo.qgb); 290 } 291 292 293 /** 294 * Determine suitable implementation of GB algorithms, case Quotient 295 * coefficients. 296 * @param fac QuotientRing. 297 * @param a algorithm, a = qgb, ffgb. 298 * @return GB algorithm implementation. 299 */ 300 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 301 QuotientRing<C> fac, GBFactory.Algo a) { 302 return getImplementation(fac, a, new OrderedPairlist<Quotient<C>>()); 303 } 304 305 306 /** 307 * Determine suitable implementation of GB algorithms, case Quotient 308 * coefficients. 309 * @param fac QuotientRing. 310 * @param pl pair selection strategy 311 * @return GB algorithm implementation. 312 */ 313 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 314 QuotientRing<C> fac, PairList<Quotient<C>> pl) { 315 return getImplementation(fac, GBFactory.Algo.qgb, pl); 316 } 317 318 319 /** 320 * Determine suitable implementation of GB algorithms, case Quotient 321 * coefficients. 322 * @param fac QuotientRing. 323 * @param a algorithm, a = qgb, ffgb. 324 * @param pl pair selection strategy 325 * @return GB algorithm implementation. 326 */ 327 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 328 QuotientRing<C> fac, GBFactory.Algo a, PairList<Quotient<C>> pl) { 329 SolvableGroebnerBaseAbstract<Quotient<C>> bba; 330 if (logger.isInfoEnabled()) { 331 logger.info("QuotientRing, fac = " + fac); 332 } 333 switch (a) { 334 case qgb: 335 bba = new SolvableGroebnerBaseSeq<Quotient<C>>(new SolvableReductionSeq<Quotient<C>>(), pl); 336 break; 337 case ffgb: 338 throw new UnsupportedOperationException("ffgb algorithm not available for " + a); 339 //PairList<GenPolynomial<C>> pli; 340 //if (pl instanceof OrderedMinPairlist) { 341 // pli = new OrderedMinPairlist<GenPolynomial<C>>(); 342 //} else if (pl instanceof OrderedSyzPairlist) { 343 // pli = new OrderedSyzPairlist<GenPolynomial<C>>(); 344 //} else { 345 // pli = new OrderedPairlist<GenPolynomial<C>>(); 346 //} 347 //bba = new SolvableGroebnerBaseQuotient<C>(fac, pli); // pl not possible 348 //break; 349 default: 350 throw new IllegalArgumentException("algorithm not available for Quotient " + a); 351 } 352 return bba; 353 } 354 355 356 /** 357 * Determine suitable implementation of GB algorithms, case (recursive) 358 * polynomial. 359 * @param fac GenPolynomialRing<C>. 360 * @return GB algorithm implementation. 361 */ 362 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 363 GenPolynomialRing<C> fac) { 364 return getImplementation(fac, GBFactory.Algo.igb); 365 } 366 367 368 /** 369 * Determine suitable implementation of GB algorithms, case (recursive) 370 * polynomial. 371 * @param fac GenPolynomialRing<C>. 372 * @param a algorithm, a = igb or egb, dgb if fac is univariate over a 373 * field. 374 * @return GB algorithm implementation. 375 */ 376 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 377 GenPolynomialRing<C> fac, GBFactory.Algo a) { 378 return getImplementation(fac, a, new OrderedPairlist<GenPolynomial<C>>()); 379 } 380 381 382 /** 383 * Determine suitable implementation of GB algorithms, case (recursive) 384 * polynomial. 385 * @param fac GenPolynomialRing<C>. 386 * @param pl pair selection strategy 387 * @return GB algorithm implementation. 388 */ 389 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 390 GenPolynomialRing<C> fac, PairList<GenPolynomial<C>> pl) { 391 return getImplementation(fac, GBFactory.Algo.igb, pl); 392 } 393 394 395 /** 396 * Determine suitable implementation of GB algorithms, case (recursive) 397 * polynomial. 398 * @param fac GenPolynomialRing<C>. 399 * @param a algorithm, a = igb or egb, dgb if fac is univariate over a 400 * field. 401 * @param pl pair selection strategy 402 * @return GB algorithm implementation. 403 */ 404 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 405 GenPolynomialRing<C> fac, GBFactory.Algo a, PairList<GenPolynomial<C>> pl) { 406 SolvableGroebnerBaseAbstract<GenPolynomial<C>> bba; 407 switch (a) { 408 case igb: 409 bba = new SolvableGroebnerBasePseudoRecSeq<C>(fac, pl); 410 break; 411 case egb: 412 throw new UnsupportedOperationException("egb algorithm not available for " + a); 413 //if (fac.nvar > 1 || !fac.coFac.isField()) { 414 // throw new IllegalArgumentException("coefficients not univariate or not over a field" + fac); 415 //} 416 //bba = new ESolvableGroebnerBaseSeq<GenPolynomial<C>>(); // pl not suitable 417 //break; 418 case dgb: 419 throw new UnsupportedOperationException("dgb algorithm not available for " + a); 420 //if (fac.nvar > 1 || !fac.coFac.isField()) { 421 // throw new IllegalArgumentException("coefficients not univariate or not over a field" + fac); 422 //} 423 //bba = new DSolvableGroebnerBaseSeq<GenPolynomial<C>>(); // pl not suitable 424 //break; 425 default: 426 throw new IllegalArgumentException("algorithm not available for GenPolynomial<C> " + a); 427 } 428 return bba; 429 } 430 431 432 /* 433 * Determine suitable implementation of GB algorithms, case regular rings. 434 * @param fac RegularRing. 435 * @return GB algorithm implementation. 436 public static <C extends RingElem<C>> SolvableGroebnerBaseAbstract<Product<C>> getImplementation( 437 ProductRing<C> fac) { 438 SolvableGroebnerBaseAbstract<Product<C>> bba; 439 if (fac.onlyFields()) { 440 bba = new RSolvableGroebnerBaseSeq<Product<C>>(); 441 } else { 442 bba = new RSolvableGroebnerBasePseudoSeq<Product<C>>(fac); 443 } 444 return bba; 445 } 446 */ 447 448 449 /** 450 * Determine suitable implementation of GB algorithms, other cases. 451 * @param fac RingFactory<C>. 452 * @return GB algorithm implementation. 453 */ 454 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 455 SolvableGroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac) { 456 return getImplementation(fac, new OrderedPairlist<C>()); 457 } 458 459 460 /** 461 * Determine suitable implementation of GB algorithms, other cases. 462 * @param fac RingFactory<C>. 463 * @param pl pair selection strategy 464 * @return GB algorithm implementation. 465 */ 466 @SuppressWarnings({ "cast", "unchecked" }) 467 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 468 SolvableGroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac, PairList<C> pl) { 469 logger.info("fac = " + fac.getClass().getName()); // + ", fac = " + fac.toScript()); 470 if (fac.isField()) { 471 return new SolvableGroebnerBaseSeq<C>(pl); 472 } 473 if (fac instanceof ValueFactory) { 474 return new SolvableGroebnerBasePseudoSeq<C>(fac, pl); 475 } 476 if (fac instanceof QuotPairFactory) { 477 return new SolvableGroebnerBaseSeq<C>(pl); 478 } 479 SolvableGroebnerBaseAbstract bba = null; 480 Object ofac = fac; 481 if (ofac instanceof GenPolynomialRing) { 482 PairList<GenPolynomial<C>> pli; 483 if (pl instanceof OrderedMinPairlist) { 484 pli = new OrderedMinPairlist<GenPolynomial<C>>(); 485 } else if (pl instanceof OrderedSyzPairlist) { 486 pli = new OrderedSyzPairlist<GenPolynomial<C>>(); 487 } else { 488 pli = new OrderedPairlist<GenPolynomial<C>>(); 489 } 490 GenPolynomialRing<C> rofac = (GenPolynomialRing<C>) ofac; 491 SolvableGroebnerBaseAbstract<GenPolynomial<C>> bbr = new SolvableGroebnerBasePseudoRecSeq<C>( 492 rofac, pli); // not pl 493 bba = (SolvableGroebnerBaseAbstract) bbr; 494 //} else if (ofac instanceof ProductRing) { 495 // ProductRing pfac = (ProductRing) ofac; 496 // if (pfac.onlyFields()) { 497 // bba = new RSolvableGroebnerBaseSeq<Product<C>>(); 498 // } else { 499 // bba = new RSolvableGroebnerBasePseudoSeq<Product<C>>(pfac); 500 // } 501 } else { 502 bba = new SolvableGroebnerBasePseudoSeq<C>(fac, pl); 503 } 504 logger.info("bba = " + bba.getClass().getName()); 505 return bba; 506 } 507 508 509 /** 510 * Determine suitable parallel/concurrent implementation of GB algorithms if 511 * possible. 512 * @param fac RingFactory<C>. 513 * @return GB proxy algorithm implementation. 514 */ 515 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 516 SolvableGroebnerBaseAbstract<C> getProxy(RingFactory<C> fac) { 517 return getProxy(fac, new OrderedPairlist<C>()); 518 } 519 520 521 /** 522 * Determine suitable parallel/concurrent implementation of GB algorithms if 523 * possible. 524 * @param fac RingFactory<C>. 525 * @param pl pair selection strategy 526 * @return GB proxy algorithm implementation. 527 */ 528 @SuppressWarnings({ "unchecked" }) 529 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 530 SolvableGroebnerBaseAbstract<C> getProxy(RingFactory<C> fac, PairList<C> pl) { 531 if (ComputerThreads.NO_THREADS) { 532 return SGBFactory.<C> getImplementation(fac, pl); 533 } 534 logger.info("proxy fac = " + fac.getClass().getName()); 535 int th = (ComputerThreads.N_CPUS > 2 ? ComputerThreads.N_CPUS - 1 : 2); 536 if (fac.isField()) { 537 SolvableGroebnerBaseAbstract<C> e1 = new SolvableGroebnerBaseSeq<C>(pl); 538 SolvableGroebnerBaseAbstract<C> e2 = new SolvableGroebnerBaseParallel<C>(th, pl); 539 return new SGBProxy<C>(e1, e2); 540 } else if (fac.characteristic().signum() == 0) { 541 if (fac instanceof GenPolynomialRing) { 542 GenPolynomialRing pfac = (GenPolynomialRing) fac; 543 OrderedPairlist ppl = new OrderedPairlist<GenPolynomial<C>>(); 544 SolvableGroebnerBaseAbstract e1 = new SolvableGroebnerBasePseudoRecSeq<C>(pfac, ppl); 545 logger.warn("no parallel version available, returning sequential version"); 546 return e1; 547 //SolvableGroebnerBaseAbstract e2 = new SolvableGroebnerBasePseudoRecParallel<C>(th, pfac, ppl); 548 //return new SGBProxy<C>(e1, e2); 549 } 550 SolvableGroebnerBaseAbstract<C> e1 = new SolvableGroebnerBasePseudoSeq<C>(fac, pl); 551 logger.warn("no parallel version available, returning sequential version"); 552 return e1; 553 //SolvableGroebnerBaseAbstract<C> e2 = new SolvableGroebnerBasePseudoParallel<C>(th, fac, pl); 554 //return new SGBProxy<C>(e1, e2); 555 } 556 return getImplementation(fac, pl); 557 } 558 559 560 /** 561 * Determine suitable parallel/concurrent implementation of GB algorithms if 562 * possible. 563 * @param fac RingFactory<C>. 564 * @return GB proxy algorithm implementation. 565 */ 566 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 567 SolvableGroebnerBaseAbstract<GenPolynomial<C>> getProxy(GenPolynomialRing<C> fac) { 568 if (ComputerThreads.NO_THREADS) { 569 //return SGBFactory.<GenPolynomial<C>> getImplementation(fac); 570 return SGBFactory.getImplementation(fac); 571 } 572 logger.info("fac = " + fac.getClass().getName()); 573 //int th = (ComputerThreads.N_CPUS > 2 ? ComputerThreads.N_CPUS - 1 : 2); 574 OrderedPairlist<GenPolynomial<C>> ppl = new OrderedPairlist<GenPolynomial<C>>(); 575 SolvableGroebnerBaseAbstract<GenPolynomial<C>> e1 = new SolvableGroebnerBasePseudoRecSeq<C>(fac, ppl); 576 logger.warn("no parallel version available, returning sequential version"); 577 return e1; 578 //SolvableGroebnerBaseAbstract<GenPolynomial<C>> e2 = new SolvableGroebnerBasePseudoRecParallel<C>(th, fac, ppl); 579 //return new SGBProxy<GenPolynomial<C>>(e1, e2); 580 //return new SGBProxy(e1, e2); 581 } 582 583}