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