001/*
002 * $Id: PolyUtil.java 4130 2012-08-22 21:41:29Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.util.ArrayList;
009import java.util.List;
010import java.util.Map;
011import java.util.SortedMap;
012import java.util.TreeMap;
013
014import org.apache.log4j.Logger;
015
016import edu.jas.arith.BigComplex;
017import edu.jas.arith.BigDecimal;
018import edu.jas.arith.BigInteger;
019import edu.jas.arith.BigRational;
020import edu.jas.arith.ModInteger;
021import edu.jas.arith.ModIntegerRing;
022import edu.jas.arith.Modular;
023import edu.jas.arith.ModularRingFactory;
024import edu.jas.arith.Product;
025import edu.jas.arith.ProductRing;
026import edu.jas.arith.Rational;
027import edu.jas.structure.Element;
028import edu.jas.structure.GcdRingElem;
029import edu.jas.structure.RingElem;
030import edu.jas.structure.RingFactory;
031import edu.jas.structure.UnaryFunctor;
032import edu.jas.util.ListUtil;
033
034
035/**
036 * Polynomial utilities, for example conversion between different
037 * representations, evaluation and interpolation.
038 * @author Heinz Kredel
039 */
040
041public class PolyUtil {
042
043
044    private static final Logger logger = Logger.getLogger(PolyUtil.class);
045
046
047    private static boolean debug = logger.isDebugEnabled();
048
049
050    /**
051     * Recursive representation. Represent as polynomial in i variables with
052     * coefficients in n-i variables. Works for arbitrary term orders.
053     * @param <C> coefficient type.
054     * @param rfac recursive polynomial ring factory.
055     * @param A polynomial to be converted.
056     * @return Recursive represenations of this in the ring rfac.
057     */
058    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursive(
059                    GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<C> A) {
060
061        GenPolynomial<GenPolynomial<C>> B = rfac.getZERO().copy();
062        if (A.isZERO()) {
063            return B;
064        }
065        int i = rfac.nvar;
066        GenPolynomial<C> zero = rfac.getZEROCoefficient();
067        Map<ExpVector, GenPolynomial<C>> Bv = B.val; //getMap();
068        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
069            ExpVector e = y.getKey();
070            C a = y.getValue();
071            ExpVector f = e.contract(0, i);
072            ExpVector g = e.contract(i, e.length() - i);
073            GenPolynomial<C> p = Bv.get(f);
074            if (p == null) {
075                p = zero;
076            }
077            p = p.sum(a, g);
078            Bv.put(f, p);
079        }
080        return B;
081    }
082
083
084    /**
085     * Distribute a recursive polynomial to a generic polynomial. Works for
086     * arbitrary term orders.
087     * @param <C> coefficient type.
088     * @param dfac combined polynomial ring factory of coefficients and this.
089     * @param B polynomial to be converted.
090     * @return distributed polynomial.
091     */
092    public static <C extends RingElem<C>> GenPolynomial<C> distribute(GenPolynomialRing<C> dfac,
093                    GenPolynomial<GenPolynomial<C>> B) {
094        GenPolynomial<C> C = dfac.getZERO().copy();
095        if (B.isZERO()) {
096            return C;
097        }
098        Map<ExpVector, C> Cm = C.val; //getMap();
099        for (Map.Entry<ExpVector, GenPolynomial<C>> y : B.getMap().entrySet()) {
100            ExpVector e = y.getKey();
101            GenPolynomial<C> A = y.getValue();
102            for (Map.Entry<ExpVector, C> x : A.val.entrySet()) {
103                ExpVector f = x.getKey();
104                C b = x.getValue();
105                ExpVector g = e.combine(f);
106                assert (Cm.get(g) != null);
107                //if ( Cm.get(g) != null ) { // todo assert, done
108                //   throw new RuntimeException("PolyUtil debug error");
109                //}
110                Cm.put(g, b);
111            }
112        }
113        return C;
114    }
115
116
117    /**
118     * Recursive representation. Represent as polynomials in i variables with
119     * coefficients in n-i variables. Works for arbitrary term orders.
120     * @param <C> coefficient type.
121     * @param rfac recursive polynomial ring factory.
122     * @param L list of polynomials to be converted.
123     * @return Recursive represenations of the list in the ring rfac.
124     */
125    public static <C extends RingElem<C>> List<GenPolynomial<GenPolynomial<C>>> recursive(
126                    GenPolynomialRing<GenPolynomial<C>> rfac, List<GenPolynomial<C>> L) {
127        return ListUtil.<GenPolynomial<C>, GenPolynomial<GenPolynomial<C>>> map(L, new DistToRec<C>(rfac));
128    }
129
130
131    /**
132     * Distribute a recursive polynomial list to a generic polynomial list.
133     * Works for arbitrary term orders.
134     * @param <C> coefficient type.
135     * @param dfac combined polynomial ring factory of coefficients and this.
136     * @param L list of polynomials to be converted.
137     * @return distributed polynomial list.
138     */
139    public static <C extends RingElem<C>> List<GenPolynomial<C>> distribute(GenPolynomialRing<C> dfac,
140                    List<GenPolynomial<GenPolynomial<C>>> L) {
141        return ListUtil.<GenPolynomial<GenPolynomial<C>>, GenPolynomial<C>> map(L, new RecToDist<C>(dfac));
142    }
143
144
145    /**
146     * BigInteger from ModInteger coefficients, symmetric. Represent as
147     * polynomial with BigInteger coefficients by removing the modules and
148     * making coefficients symmetric to 0.
149     * @param fac result polynomial factory.
150     * @param A polynomial with ModInteger coefficients to be converted.
151     * @return polynomial with BigInteger coefficients.
152     */
153    public static <C extends RingElem<C> & Modular> GenPolynomial<BigInteger> integerFromModularCoefficients(
154                    GenPolynomialRing<BigInteger> fac, GenPolynomial<C> A) {
155        return PolyUtil.<C, BigInteger> map(fac, A, new ModSymToInt<C>());
156    }
157
158
159    /**
160     * BigInteger from ModInteger coefficients, symmetric. Represent as
161     * polynomial with BigInteger coefficients by removing the modules and
162     * making coefficients symmetric to 0.
163     * @param fac result polynomial factory.
164     * @param L list of polynomials with ModInteger coefficients to be
165     *            converted.
166     * @return list of polynomials with BigInteger coefficients.
167     */
168    public static <C extends RingElem<C> & Modular> List<GenPolynomial<BigInteger>> integerFromModularCoefficients(
169                    final GenPolynomialRing<BigInteger> fac, List<GenPolynomial<C>> L) {
170        return ListUtil.<GenPolynomial<C>, GenPolynomial<BigInteger>> map(L,
171                        new UnaryFunctor<GenPolynomial<C>, GenPolynomial<BigInteger>>() {
172
173
174                            public GenPolynomial<BigInteger> eval(GenPolynomial<C> c) {
175                                return PolyUtil.<C> integerFromModularCoefficients(fac, c);
176                            }
177                        });
178    }
179
180
181    /**
182     * BigInteger from ModInteger coefficients, positive. Represent as
183     * polynomial with BigInteger coefficients by removing the modules.
184     * @param fac result polynomial factory.
185     * @param A polynomial with ModInteger coefficients to be converted.
186     * @return polynomial with BigInteger coefficients.
187     */
188    public static <C extends RingElem<C> & Modular> GenPolynomial<BigInteger> integerFromModularCoefficientsPositive(
189                    GenPolynomialRing<BigInteger> fac, GenPolynomial<C> A) {
190        return PolyUtil.<C, BigInteger> map(fac, A, new ModToInt<C>());
191    }
192
193
194    /**
195     * BigInteger from BigRational coefficients. Represent as polynomial with
196     * BigInteger coefficients by multiplication with the lcm of the numerators
197     * of the BigRational coefficients.
198     * @param fac result polynomial factory.
199     * @param A polynomial with BigRational coefficients to be converted.
200     * @return polynomial with BigInteger coefficients.
201     */
202    public static GenPolynomial<BigInteger> integerFromRationalCoefficients(
203                    GenPolynomialRing<BigInteger> fac, GenPolynomial<BigRational> A) {
204        if (A == null || A.isZERO()) {
205            return fac.getZERO();
206        }
207        java.math.BigInteger c = null;
208        int s = 0;
209        // lcm of denominators
210        for (BigRational y : A.val.values()) {
211            java.math.BigInteger x = y.denominator();
212            // c = lcm(c,x)
213            if (c == null) {
214                c = x;
215                s = x.signum();
216            } else {
217                java.math.BigInteger d = c.gcd(x);
218                c = c.multiply(x.divide(d));
219            }
220        }
221        if (s < 0) {
222            c = c.negate();
223        }
224        return PolyUtil.<BigRational, BigInteger> map(fac, A, new RatToInt(c));
225    }
226
227
228    /**
229     * BigInteger from BigRational coefficients. Represent as polynomial with
230     * BigInteger coefficients by multiplication with the gcd of the numerators
231     * and the lcm of the denominators of the BigRational coefficients. <br
232     * />
233     * <b>Author:</b> Axel Kramer
234     * @param fac result polynomial factory.
235     * @param A polynomial with BigRational coefficients to be converted.
236     * @return Object[] with 3 entries: [0]->gcd [1]->lcm and [2]->polynomial
237     *         with BigInteger coefficients.
238     */
239    public static Object[] integerFromRationalCoefficientsFactor(GenPolynomialRing<BigInteger> fac,
240                    GenPolynomial<BigRational> A) {
241        Object[] result = new Object[3];
242        if (A == null || A.isZERO()) {
243            result[0] = java.math.BigInteger.ONE;
244            result[1] = java.math.BigInteger.ZERO;
245            result[2] = fac.getZERO();
246            return result;
247        }
248        java.math.BigInteger gcd = null;
249        java.math.BigInteger lcm = null;
250        int sLCM = 0;
251        int sGCD = 0;
252        // lcm of denominators
253        for (BigRational y : A.val.values()) {
254            java.math.BigInteger numerator = y.numerator();
255            java.math.BigInteger denominator = y.denominator();
256            // lcm = lcm(lcm,x)
257            if (lcm == null) {
258                lcm = denominator;
259                sLCM = denominator.signum();
260            } else {
261                java.math.BigInteger d = lcm.gcd(denominator);
262                lcm = lcm.multiply(denominator.divide(d));
263            }
264            // gcd = gcd(gcd,x)
265            if (gcd == null) {
266                gcd = numerator;
267                sGCD = numerator.signum();
268            } else {
269                gcd = gcd.gcd(numerator);
270            }
271        }
272        if (sLCM < 0) {
273            lcm = lcm.negate();
274        }
275        if (sGCD < 0) {
276            gcd = gcd.negate();
277        }
278        result[0] = gcd;
279        result[1] = lcm;
280        result[2] = PolyUtil.<BigRational, BigInteger> map(fac, A, new RatToIntFactor(gcd, lcm));
281        return result;
282    }
283
284
285    /**
286     * BigInteger from BigRational coefficients. Represent as list of
287     * polynomials with BigInteger coefficients by multiplication with the lcm
288     * of the numerators of the BigRational coefficients of each polynomial.
289     * @param fac result polynomial factory.
290     * @param L list of polynomials with BigRational coefficients to be
291     *            converted.
292     * @return polynomial list with BigInteger coefficients.
293     */
294    public static List<GenPolynomial<BigInteger>> integerFromRationalCoefficients(
295                    GenPolynomialRing<BigInteger> fac, List<GenPolynomial<BigRational>> L) {
296        return ListUtil.<GenPolynomial<BigRational>, GenPolynomial<BigInteger>> map(L, new RatToIntPoly(fac));
297    }
298
299
300    /**
301     * From BigInteger coefficients. Represent as polynomial with type C
302     * coefficients, e.g. ModInteger or BigRational.
303     * @param <C> coefficient type.
304     * @param fac result polynomial factory.
305     * @param A polynomial with BigInteger coefficients to be converted.
306     * @return polynomial with type C coefficients.
307     */
308    public static <C extends RingElem<C>> GenPolynomial<C> fromIntegerCoefficients(GenPolynomialRing<C> fac,
309                    GenPolynomial<BigInteger> A) {
310        return PolyUtil.<BigInteger, C> map(fac, A, new FromInteger<C>(fac.coFac));
311    }
312
313
314    /**
315     * From BigInteger coefficients. Represent as list of polynomials with type
316     * C coefficients, e.g. ModInteger or BigRational.
317     * @param <C> coefficient type.
318     * @param fac result polynomial factory.
319     * @param L list of polynomials with BigInteger coefficients to be
320     *            converted.
321     * @return list of polynomials with type C coefficients.
322     */
323    public static <C extends RingElem<C>> List<GenPolynomial<C>> fromIntegerCoefficients(
324                    GenPolynomialRing<C> fac, List<GenPolynomial<BigInteger>> L) {
325        return ListUtil.<GenPolynomial<BigInteger>, GenPolynomial<C>> map(L, new FromIntegerPoly<C>(fac));
326    }
327
328
329    /**
330     * Convert to decimal coefficients.
331     * @param fac result polynomial factory.
332     * @param A polynomial with Rational coefficients to be converted.
333     * @return polynomial with BigDecimal coefficients.
334     */
335    public static <C extends RingElem<C> & Rational> GenPolynomial<BigDecimal> decimalFromRational(
336                    GenPolynomialRing<BigDecimal> fac, GenPolynomial<C> A) {
337        return PolyUtil.<C, BigDecimal> map(fac, A, new RatToDec<C>());
338    }
339
340
341    /**
342     * Convert to complex decimal coefficients.
343     * @param fac result polynomial factory.
344     * @param A polynomial with complex Rational coefficients to be converted.
345     * @return polynomial with Complex BigDecimal coefficients.
346     */
347    public static <C extends RingElem<C> & Rational> GenPolynomial<Complex<BigDecimal>> complexDecimalFromRational(
348                    GenPolynomialRing<Complex<BigDecimal>> fac, GenPolynomial<Complex<C>> A) {
349        return PolyUtil.<Complex<C>, Complex<BigDecimal>> map(fac, A, new CompRatToDec<C>(fac.coFac));
350    }
351
352
353    /**
354     * Real part.
355     * @param fac result polynomial factory.
356     * @param A polynomial with BigComplex coefficients to be converted.
357     * @return polynomial with real part of the coefficients.
358     */
359    public static GenPolynomial<BigRational> realPart(GenPolynomialRing<BigRational> fac,
360                    GenPolynomial<BigComplex> A) {
361        return PolyUtil.<BigComplex, BigRational> map(fac, A, new RealPart());
362    }
363
364
365    /**
366     * Imaginary part.
367     * @param fac result polynomial factory.
368     * @param A polynomial with BigComplex coefficients to be converted.
369     * @return polynomial with imaginary part of coefficients.
370     */
371    public static GenPolynomial<BigRational> imaginaryPart(GenPolynomialRing<BigRational> fac,
372                    GenPolynomial<BigComplex> A) {
373        return PolyUtil.<BigComplex, BigRational> map(fac, A, new ImagPart());
374    }
375
376
377    /**
378     * Real part.
379     * @param fac result polynomial factory.
380     * @param A polynomial with BigComplex coefficients to be converted.
381     * @return polynomial with real part of the coefficients.
382     */
383    public static <C extends RingElem<C>> GenPolynomial<C> realPartFromComplex(GenPolynomialRing<C> fac,
384                    GenPolynomial<Complex<C>> A) {
385        return PolyUtil.<Complex<C>, C> map(fac, A, new RealPartComplex<C>());
386    }
387
388
389    /**
390     * Imaginary part.
391     * @param fac result polynomial factory.
392     * @param A polynomial with BigComplex coefficients to be converted.
393     * @return polynomial with imaginary part of coefficients.
394     */
395    public static <C extends RingElem<C>> GenPolynomial<C> imaginaryPartFromComplex(GenPolynomialRing<C> fac,
396                    GenPolynomial<Complex<C>> A) {
397        return PolyUtil.<Complex<C>, C> map(fac, A, new ImagPartComplex<C>());
398    }
399
400
401    /**
402     * Complex from real polynomial.
403     * @param fac result polynomial factory.
404     * @param A polynomial with C coefficients to be converted.
405     * @return polynomial with Complex<C> coefficients.
406     */
407    public static <C extends RingElem<C>> GenPolynomial<Complex<C>> toComplex(
408                    GenPolynomialRing<Complex<C>> fac, GenPolynomial<C> A) {
409        return PolyUtil.<C, Complex<C>> map(fac, A, new ToComplex<C>(fac.coFac));
410    }
411
412
413    /**
414     * Complex from rational coefficients.
415     * @param fac result polynomial factory.
416     * @param A polynomial with BigRational coefficients to be converted.
417     * @return polynomial with BigComplex coefficients.
418     */
419    public static GenPolynomial<BigComplex> complexFromRational(GenPolynomialRing<BigComplex> fac,
420                    GenPolynomial<BigRational> A) {
421        return PolyUtil.<BigRational, BigComplex> map(fac, A, new RatToCompl());
422    }
423
424
425    /**
426     * Complex from ring element coefficients.
427     * @param fac result polynomial factory.
428     * @param A polynomial with RingElem coefficients to be converted.
429     * @return polynomial with Complex coefficients.
430     */
431    public static <C extends GcdRingElem<C>> GenPolynomial<Complex<C>> complexFromAny(
432                    GenPolynomialRing<Complex<C>> fac, GenPolynomial<C> A) {
433        ComplexRing<C> cr = (ComplexRing<C>) fac.coFac;
434        return PolyUtil.<C, Complex<C>> map(fac, A, new AnyToComplex<C>(cr));
435    }
436
437
438    /**
439     * From AlgebraicNumber coefficients. Represent as polynomial with type
440     * GenPolynomial&lt;C&gt; coefficients, e.g. ModInteger or BigRational.
441     * @param rfac result polynomial factory.
442     * @param A polynomial with AlgebraicNumber coefficients to be converted.
443     * @return polynomial with type GenPolynomial&lt;C&gt; coefficients.
444     */
445    public static <C extends GcdRingElem<C>> GenPolynomial<GenPolynomial<C>> fromAlgebraicCoefficients(
446                    GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<AlgebraicNumber<C>> A) {
447        return PolyUtil.<AlgebraicNumber<C>, GenPolynomial<C>> map(rfac, A, new AlgToPoly<C>());
448    }
449
450
451    /**
452     * Convert to AlgebraicNumber coefficients. Represent as polynomial with
453     * AlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational.
454     * @param pfac result polynomial factory.
455     * @param A polynomial with C coefficients to be converted.
456     * @return polynomial with AlgebraicNumber&lt;C&gt; coefficients.
457     */
458    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToAlgebraicCoefficients(
459                    GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<C> A) {
460        AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac;
461        return PolyUtil.<C, AlgebraicNumber<C>> map(pfac, A, new CoeffToAlg<C>(afac));
462    }
463
464
465    /**
466     * Convert to recursive AlgebraicNumber coefficients. Represent as
467     * polynomial with recursive AlgebraicNumber<C> coefficients, C is e.g.
468     * ModInteger or BigRational.
469     * @param depth recursion depth of AlgebraicNumber coefficients.
470     * @param pfac result polynomial factory.
471     * @param A polynomial with C coefficients to be converted.
472     * @return polynomial with AlgebraicNumber&lt;C&gt; coefficients.
473     */
474    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToRecAlgebraicCoefficients(
475                    int depth, GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<C> A) {
476        AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac;
477        return PolyUtil.<C, AlgebraicNumber<C>> map(pfac, A, new CoeffToRecAlg<C>(depth, afac));
478    }
479
480
481    /**
482     * Convert to AlgebraicNumber coefficients. Represent as polynomial with
483     * AlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational.
484     * @param pfac result polynomial factory.
485     * @param A recursive polynomial with GenPolynomial&lt;BigInteger&gt;
486     *            coefficients to be converted.
487     * @return polynomial with AlgebraicNumber&lt;C&gt; coefficients.
488     */
489    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertRecursiveToAlgebraicCoefficients(
490                    GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<GenPolynomial<C>> A) {
491        AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac;
492        return PolyUtil.<GenPolynomial<C>, AlgebraicNumber<C>> map(pfac, A, new PolyToAlg<C>(afac));
493    }
494
495
496    /**
497     * Complex from algebraic coefficients.
498     * @param fac result polynomial factory.
499     * @param A polynomial with AlgebraicNumber coefficients Q(i) to be
500     *            converted.
501     * @return polynomial with Complex coefficients.
502     */
503    public static <C extends GcdRingElem<C>> GenPolynomial<Complex<C>> complexFromAlgebraic(
504                    GenPolynomialRing<Complex<C>> fac, GenPolynomial<AlgebraicNumber<C>> A) {
505        ComplexRing<C> cfac = (ComplexRing<C>) fac.coFac;
506        return PolyUtil.<AlgebraicNumber<C>, Complex<C>> map(fac, A, new AlgebToCompl<C>(cfac));
507    }
508
509
510    /**
511     * AlgebraicNumber from complex coefficients.
512     * @param fac result polynomial factory over Q(i).
513     * @param A polynomial with Complex coefficients to be converted.
514     * @return polynomial with AlgebraicNumber coefficients.
515     */
516    public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> algebraicFromComplex(
517                    GenPolynomialRing<AlgebraicNumber<C>> fac, GenPolynomial<Complex<C>> A) {
518        AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) fac.coFac;
519        return PolyUtil.<Complex<C>, AlgebraicNumber<C>> map(fac, A, new ComplToAlgeb<C>(afac));
520    }
521
522
523    /**
524     * ModInteger chinese remainder algorithm on coefficients.
525     * @param fac GenPolynomial&lt;ModInteger&gt; result factory with
526     *            A.coFac.modul*B.coFac.modul = C.coFac.modul.
527     * @param A GenPolynomial&lt;ModInteger&gt;.
528     * @param B other GenPolynomial&lt;ModInteger&gt;.
529     * @param mi inverse of A.coFac.modul in ring B.coFac.
530     * @return S = cra(A,B), with S mod A.coFac.modul == A and S mod
531     *         B.coFac.modul == B.
532     */
533    public static <C extends RingElem<C> & Modular> GenPolynomial<C> chineseRemainder(
534                    GenPolynomialRing<C> fac, GenPolynomial<C> A, C mi, GenPolynomial<C> B) {
535        ModularRingFactory<C> cfac = (ModularRingFactory<C>) fac.coFac; // get RingFactory
536        GenPolynomial<C> S = fac.getZERO().copy();
537        GenPolynomial<C> Ap = A.copy();
538        SortedMap<ExpVector, C> av = Ap.val; //getMap();
539        SortedMap<ExpVector, C> bv = B.getMap();
540        SortedMap<ExpVector, C> sv = S.val; //getMap();
541        C c = null;
542        for (Map.Entry<ExpVector, C> me : bv.entrySet()) {
543            ExpVector e = me.getKey();
544            C y = me.getValue(); //bv.get(e); // assert y != null
545            C x = av.get(e);
546            if (x != null) {
547                av.remove(e);
548                c = cfac.chineseRemainder(x, mi, y);
549                if (!c.isZERO()) { // 0 cannot happen
550                    sv.put(e, c);
551                }
552            } else {
553                //c = cfac.fromInteger( y.getVal() );
554                c = cfac.chineseRemainder(A.ring.coFac.getZERO(), mi, y);
555                if (!c.isZERO()) { // 0 cannot happen
556                    sv.put(e, c); // c != null
557                }
558            }
559        }
560        // assert bv is empty = done
561        for (Map.Entry<ExpVector, C> me : av.entrySet()) { // rest of av
562            ExpVector e = me.getKey();
563            C x = me.getValue(); // av.get(e); // assert x != null
564            //c = cfac.fromInteger( x.getVal() );
565            c = cfac.chineseRemainder(x, mi, B.ring.coFac.getZERO());
566            if (!c.isZERO()) { // 0 cannot happen
567                sv.put(e, c); // c != null
568            }
569        }
570        return S;
571    }
572
573
574    /**
575     * GenPolynomial monic, i.e. leadingBaseCoefficient == 1. If
576     * leadingBaseCoefficient is not invertible returns this unmodified.
577     * @param <C> coefficient type.
578     * @param p recursive GenPolynomial<GenPolynomial<C>>.
579     * @return monic(p).
580     */
581    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> monic(
582                    GenPolynomial<GenPolynomial<C>> p) {
583        if (p == null || p.isZERO()) {
584            return p;
585        }
586        C lc = p.leadingBaseCoefficient().leadingBaseCoefficient();
587        if (!lc.isUnit()) {
588            return p;
589        }
590        C lm = lc.inverse();
591        GenPolynomial<C> L = p.ring.coFac.getONE();
592        L = L.multiply(lm);
593        return p.multiply(L);
594    }
595
596
597    /**
598     * Polynomial list monic.
599     * @param <C> coefficient type.
600     * @param L list of polynomials with field coefficients.
601     * @return list of polynomials with leading coefficient 1.
602     */
603    public static <C extends RingElem<C>> List<GenPolynomial<C>> monic(List<GenPolynomial<C>> L) {
604        return ListUtil.<GenPolynomial<C>, GenPolynomial<C>> map(L,
605                        new UnaryFunctor<GenPolynomial<C>, GenPolynomial<C>>() {
606
607
608                            public GenPolynomial<C> eval(GenPolynomial<C> c) {
609                                if (c == null) {
610                                    return null;
611                                }
612                                return c.monic();
613                            }
614                        });
615    }
616
617
618    /**
619     * Recursive polynomial list monic.
620     * @param <C> coefficient type.
621     * @param L list of recursive polynomials with field coefficients.
622     * @return list of polynomials with leading base coefficient 1.
623     */
624    public static <C extends RingElem<C>> List<GenPolynomial<GenPolynomial<C>>> monicRec(List<GenPolynomial<GenPolynomial<C>>> L) {
625        return ListUtil.<GenPolynomial<GenPolynomial<C>>, GenPolynomial<GenPolynomial<C>>> map(L,
626                        new UnaryFunctor<GenPolynomial<GenPolynomial<C>>, GenPolynomial<GenPolynomial<C>>>() {
627
628
629                            public GenPolynomial<GenPolynomial<C>> eval(GenPolynomial<GenPolynomial<C>> c) {
630                                if (c == null) {
631                                    return null;
632                                }
633                                return PolyUtil.<C> monic(c);
634                            }
635                        });
636    }
637
638
639    /**
640     * Polynomial list leading exponent vectors.
641     * @param <C> coefficient type.
642     * @param L list of polynomials.
643     * @return list of leading exponent vectors.
644     */
645    public static <C extends RingElem<C>> List<ExpVector> leadingExpVector(List<GenPolynomial<C>> L) {
646        return ListUtil.<GenPolynomial<C>, ExpVector> map(L, new UnaryFunctor<GenPolynomial<C>, ExpVector>() {
647
648
649            public ExpVector eval(GenPolynomial<C> c) {
650                if (c == null) {
651                    return null;
652                }
653                return c.leadingExpVector();
654            }
655        });
656    }
657
658
659    /**
660     * Extend coefficient variables. Extend all coefficient ExpVectors by i
661     * elements and multiply by x_j^k.
662     * @param pfac extended polynomial ring factory (by i variables in the
663     *            coefficients).
664     * @param j index of variable to be used for multiplication.
665     * @param k exponent for x_j.
666     * @return extended polynomial.
667     */
668    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> extendCoefficients(
669                    GenPolynomialRing<GenPolynomial<C>> pfac, GenPolynomial<GenPolynomial<C>> A, int j, long k) {
670        GenPolynomial<GenPolynomial<C>> Cp = pfac.getZERO().copy();
671        if (A.isZERO()) {
672            return Cp;
673        }
674        GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac;
675        //GenPolynomialRing<C> acfac = (GenPolynomialRing<C>) A.ring.coFac;
676        //int i = cfac.nvar - acfac.nvar;
677        Map<ExpVector, GenPolynomial<C>> CC = Cp.val; //getMap();
678        for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.val.entrySet()) {
679            ExpVector e = y.getKey();
680            GenPolynomial<C> a = y.getValue();
681            GenPolynomial<C> f = a.extend(cfac, j, k);
682            CC.put(e, f);
683        }
684        return Cp;
685    }
686
687
688    /**
689     * To recursive representation. Represent as polynomial in i+r variables
690     * with coefficients in i variables. Works for arbitrary term orders.
691     * @param <C> coefficient type.
692     * @param rfac recursive polynomial ring factory.
693     * @param A polynomial to be converted.
694     * @return Recursive represenations of this in the ring rfac.
695     */
696    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> toRecursive(
697                    GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<C> A) {
698
699        GenPolynomial<GenPolynomial<C>> B = rfac.getZERO().copy();
700        if (A.isZERO()) {
701            return B;
702        }
703        //int i = rfac.nvar;
704        //GenPolynomial<C> zero = rfac.getZEROCoefficient();
705        GenPolynomial<C> one = rfac.getONECoefficient();
706        Map<ExpVector, GenPolynomial<C>> Bv = B.val; //getMap();
707        for (Monomial<C> m : A) {
708            ExpVector e = m.e;
709            C a = m.c;
710            GenPolynomial<C> p = one.multiply(a);
711            Bv.put(e, p);
712        }
713        return B;
714    }
715
716
717    /**
718     * GenPolynomial coefficient wise remainder.
719     * @param <C> coefficient type.
720     * @param P GenPolynomial.
721     * @param s nonzero coefficient.
722     * @return coefficient wise remainder.
723     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
724     */
725    public static <C extends RingElem<C>> GenPolynomial<C> baseRemainderPoly(GenPolynomial<C> P, C s) {
726        if (s == null || s.isZERO()) {
727            throw new ArithmeticException(P + " division by zero " + s);
728        }
729        GenPolynomial<C> h = P.ring.getZERO().copy();
730        Map<ExpVector, C> hm = h.val; //getMap();
731        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
732            ExpVector f = m.getKey();
733            C a = m.getValue();
734            C x = a.remainder(s);
735            hm.put(f, x);
736        }
737        return h;
738    }
739
740
741    /**
742     * GenPolynomial sparse pseudo remainder. For univariate polynomials.
743     * @param <C> coefficient type.
744     * @param P GenPolynomial.
745     * @param S nonzero GenPolynomial.
746     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
747     *         m' &le; deg(P)-deg(S)
748     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
749     * @deprecated Use
750     *             {@link #baseSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)}
751     *             instead
752     */
753    @Deprecated
754    public static <C extends RingElem<C>> GenPolynomial<C> basePseudoRemainder(GenPolynomial<C> P,
755                    GenPolynomial<C> S) {
756        return baseSparsePseudoRemainder(P, S);
757    }
758
759
760    /**
761     * GenPolynomial sparse pseudo remainder. For univariate polynomials.
762     * @param <C> coefficient type.
763     * @param P GenPolynomial.
764     * @param S nonzero GenPolynomial.
765     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
766     *         m' &le; deg(P)-deg(S)
767     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
768     */
769    public static <C extends RingElem<C>> GenPolynomial<C> baseSparsePseudoRemainder(GenPolynomial<C> P,
770                    GenPolynomial<C> S) {
771        if (S == null || S.isZERO()) {
772            throw new ArithmeticException(P.toString() + " division by zero " + S);
773        }
774        if (P.isZERO()) {
775            return P;
776        }
777        if (S.isONE()) {
778            return P.ring.getZERO();
779        }
780        C c = S.leadingBaseCoefficient();
781        ExpVector e = S.leadingExpVector();
782        GenPolynomial<C> h;
783        GenPolynomial<C> r = P;
784        while (!r.isZERO()) {
785            ExpVector f = r.leadingExpVector();
786            if (f.multipleOf(e)) {
787                C a = r.leadingBaseCoefficient();
788                f = f.subtract(e);
789                C x = a.remainder(c);
790                if (x.isZERO()) {
791                    C y = a.divide(c);
792                    h = S.multiply(y, f); // coeff a
793                } else {
794                    r = r.multiply(c); // coeff ac
795                    h = S.multiply(a, f); // coeff ac
796                }
797                r = r.subtract(h);
798            } else {
799                break;
800            }
801        }
802        return r;
803    }
804
805
806    /**
807     * GenPolynomial dense pseudo remainder. For univariate polynomials.
808     * @param P GenPolynomial.
809     * @param S nonzero GenPolynomial.
810     * @return remainder with ldcf(S)<sup>m</sup> P = quotient * S + remainder.
811     *         m == deg(P)-deg(S)
812     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
813     */
814    public static <C extends RingElem<C>> GenPolynomial<C> baseDensePseudoRemainder(GenPolynomial<C> P,
815                    GenPolynomial<C> S) {
816        if (S == null || S.isZERO()) {
817            throw new ArithmeticException(P + " division by zero " + S);
818        }
819        if (P.isZERO()) {
820            return P;
821        }
822        if (S.degree() <= 0) {
823            return P.ring.getZERO();
824        }
825        long m = P.degree(0);
826        long n = S.degree(0);
827        C c = S.leadingBaseCoefficient();
828        ExpVector e = S.leadingExpVector();
829        GenPolynomial<C> h;
830        GenPolynomial<C> r = P;
831        for (long i = m; i >= n; i--) {
832            if (r.isZERO()) {
833                return r;
834            }
835            long k = r.degree(0);
836            if (i == k) {
837                ExpVector f = r.leadingExpVector();
838                C a = r.leadingBaseCoefficient();
839                f = f.subtract(e); // EVDIF( f, e );
840                //System.out.println("red div = " + f);
841                r = r.multiply(c); // coeff ac
842                h = S.multiply(a, f); // coeff ac
843                r = r.subtract(h);
844            } else {
845                r = r.multiply(c);
846            }
847        }
848        return r;
849    }
850
851
852    /**
853     * GenPolynomial dense pseudo quotient. For univariate polynomials.
854     * @param P GenPolynomial.
855     * @param S nonzero GenPolynomial.
856     * @return quotient with ldcf(S)<sup>m</sup> P = quotient * S + remainder. m
857     *         == deg(P)-deg(S)
858     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
859     */
860    public static <C extends RingElem<C>> GenPolynomial<C> baseDensePseudoQuotient(GenPolynomial<C> P,
861                    GenPolynomial<C> S) {
862        if (S == null || S.isZERO()) {
863            throw new ArithmeticException(P + " division by zero " + S);
864        }
865        if (P.isZERO()) {
866            return P;
867        }
868        //if (S.degree() <= 0) {
869        //    return l^n P; //P.ring.getZERO();
870        //}
871        long m = P.degree(0);
872        long n = S.degree(0);
873        C c = S.leadingBaseCoefficient();
874        ExpVector e = S.leadingExpVector();
875        GenPolynomial<C> q = P.ring.getZERO();
876        GenPolynomial<C> h;
877        GenPolynomial<C> r = P;
878        for (long i = m; i >= n; i--) {
879            if (r.isZERO()) {
880                return q;
881            }
882            long k = r.degree(0);
883            if (i == k) {
884                ExpVector f = r.leadingExpVector();
885                C a = r.leadingBaseCoefficient();
886                f = f.subtract(e); // EVDIF( f, e );
887                //System.out.println("red div = " + f);
888                r = r.multiply(c); // coeff ac
889                h = S.multiply(a, f); // coeff ac
890                r = r.subtract(h);
891                q = q.multiply(c);
892                q = q.sum(a, f);
893            } else {
894                q = q.multiply(c);
895                r = r.multiply(c);
896            }
897        }
898        return q;
899    }
900
901
902    /**
903     * GenPolynomial sparse pseudo divide. For univariate polynomials or exact
904     * division.
905     * @param <C> coefficient type.
906     * @param P GenPolynomial.
907     * @param S nonzero GenPolynomial.
908     * @return quotient with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
909     *         m' &le; deg(P)-deg(S)
910     * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial).
911     */
912    public static <C extends RingElem<C>> GenPolynomial<C> basePseudoDivide(GenPolynomial<C> P,
913                    GenPolynomial<C> S) {
914        if (S == null || S.isZERO()) {
915            throw new ArithmeticException(P.toString() + " division by zero " + S);
916        }
917        //if (S.ring.nvar != 1) {
918            // ok if exact division
919            // throw new RuntimeException(this.getClass().getName()
920            //                            + " univariate polynomials only");
921        //}
922        if (P.isZERO() || S.isONE()) {
923            return P;
924        }
925        C c = S.leadingBaseCoefficient();
926        ExpVector e = S.leadingExpVector();
927        GenPolynomial<C> h;
928        GenPolynomial<C> r = P;
929        GenPolynomial<C> q = S.ring.getZERO().copy();
930
931        while (!r.isZERO()) {
932            ExpVector f = r.leadingExpVector();
933            if (f.multipleOf(e)) {
934                C a = r.leadingBaseCoefficient();
935                f = f.subtract(e);
936                C x = a.remainder(c);
937                if (x.isZERO()) {
938                    C y = a.divide(c);
939                    q = q.sum(y, f);
940                    h = S.multiply(y, f); // coeff a
941                } else {
942                    q = q.multiply(c);
943                    q = q.sum(a, f);
944                    r = r.multiply(c); // coeff ac
945                    h = S.multiply(a, f); // coeff ac
946                }
947                r = r.subtract(h);
948            } else {
949                break;
950            }
951        }
952        return q;
953    }
954
955
956    /**
957     * GenPolynomial sparse pseudo quotient and remainder. For univariate
958     * polynomials or exact division.
959     * @param <C> coefficient type.
960     * @param P GenPolynomial.
961     * @param S nonzero GenPolynomial.
962     * @return [ quotient, remainder ] with ldcf(S)<sup>m'</sup> P = quotient *
963     *         S + remainder. m' &le; deg(P)-deg(S)
964     * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial).
965     */
966    @SuppressWarnings("unchecked")
967    public static <C extends RingElem<C>> GenPolynomial<C>[] basePseudoQuotientRemainder(GenPolynomial<C> P,
968                    GenPolynomial<C> S) {
969        if (S == null || S.isZERO()) {
970            throw new ArithmeticException(P.toString() + " division by zero " + S);
971        }
972        //if (S.ring.nvar != 1) {
973            // ok if exact division
974            // throw new RuntimeException(this.getClass().getName()
975            //                            + " univariate polynomials only");
976        //}
977        GenPolynomial<C>[] ret = new GenPolynomial[2];
978        ret[0] = null;
979        ret[1] = null;
980        if (P.isZERO() || S.isONE()) {
981            ret[0] = P;
982            ret[1] = S.ring.getZERO();
983            return ret;
984        }
985        C c = S.leadingBaseCoefficient();
986        ExpVector e = S.leadingExpVector();
987        GenPolynomial<C> h;
988        GenPolynomial<C> r = P;
989        GenPolynomial<C> q = S.ring.getZERO().copy();
990
991        while (!r.isZERO()) {
992            ExpVector f = r.leadingExpVector();
993            if (f.multipleOf(e)) {
994                C a = r.leadingBaseCoefficient();
995                f = f.subtract(e);
996                C x = a.remainder(c);
997                if (x.isZERO()) {
998                    C y = a.divide(c);
999                    q = q.sum(y, f);
1000                    h = S.multiply(y, f); // coeff a
1001                } else {
1002                    q = q.multiply(c);
1003                    q = q.sum(a, f);
1004                    r = r.multiply(c); // coeff ac
1005                    h = S.multiply(a, f); // coeff ac
1006                }
1007                r = r.subtract(h);
1008            } else {
1009                break;
1010            }
1011        }
1012        //GenPolynomial<C> rhs = q.multiply(S).sum(r);
1013        //GenPolynomial<C> lhs = P;
1014        ret[0] = q;
1015        ret[1] = r;
1016        return ret;
1017    }
1018
1019
1020    /**
1021     * Is GenPolynomial pseudo quotient and remainder. For univariate
1022     * polynomials.
1023     * @param <C> coefficient type.
1024     * @param P base GenPolynomial.
1025     * @param S nonzero base GenPolynomial.
1026     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1027     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1028     *      <b>Note:</b> not always meaningful and working
1029     */
1030    public static <C extends RingElem<C>> boolean isBasePseudoQuotientRemainder(GenPolynomial<C> P,
1031                    GenPolynomial<C> S, GenPolynomial<C> q, GenPolynomial<C> r) {
1032        GenPolynomial<C> rhs = q.multiply(S).sum(r);
1033        //System.out.println("rhs,1 = " + rhs);
1034        GenPolynomial<C> lhs = P;
1035        C ldcf = S.leadingBaseCoefficient();
1036        long d = P.degree(0) - S.degree(0) + 1;
1037        d = (d > 0 ? d : -d + 2);
1038        for (long i = 0; i <= d; i++) {
1039            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1040            if (lhs.equals(rhs)) {
1041                //System.out.println("lhs,1 = " + lhs);
1042                return true;
1043            }
1044            lhs = lhs.multiply(ldcf);
1045        }
1046        GenPolynomial<C> Pp = P;
1047        rhs = q.multiply(S);
1048        //System.out.println("rhs,2 = " + rhs);
1049        for (long i = 0; i <= d; i++) {
1050            lhs = Pp.subtract(r);
1051            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1052            if (lhs.equals(rhs)) {
1053                //System.out.println("lhs,2 = " + lhs);
1054                return true;
1055            }
1056            Pp = Pp.multiply(ldcf);
1057        }
1058        return false;
1059    }
1060
1061
1062    /**
1063     * GenPolynomial divide. For recursive polynomials. Division by coefficient
1064     * ring element.
1065     * @param <C> coefficient type.
1066     * @param P recursive GenPolynomial.
1067     * @param s GenPolynomial.
1068     * @return this/s.
1069     */
1070    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDivide(
1071                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
1072        if (s == null || s.isZERO()) {
1073            throw new ArithmeticException("division by zero " + P + ", " + s);
1074        }
1075        if (P.isZERO()) {
1076            return P;
1077        }
1078        if (s.isONE()) {
1079            return P;
1080        }
1081        GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1082        SortedMap<ExpVector, GenPolynomial<C>> pv = p.val; //getMap();
1083        for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
1084            GenPolynomial<C> c1 = m1.getValue();
1085            ExpVector e1 = m1.getKey();
1086            GenPolynomial<C> c = PolyUtil.<C> basePseudoDivide(c1, s);
1087            if (!c.isZERO()) {
1088                pv.put(e1, c); // or m1.setValue( c )
1089            } else {
1090                System.out.println("pu, c1 = " + c1);
1091                System.out.println("pu, s  = " + s);
1092                System.out.println("pu, c  = " + c);
1093                throw new RuntimeException("something is wrong");
1094            }
1095        }
1096        return p;
1097    }
1098
1099
1100    /**
1101     * GenPolynomial base divide. For recursive polynomials. Division by
1102     * coefficient ring element.
1103     * @param <C> coefficient type.
1104     * @param P recursive GenPolynomial.
1105     * @param s coefficient.
1106     * @return this/s.
1107     */
1108    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> baseRecursiveDivide(
1109                    GenPolynomial<GenPolynomial<C>> P, C s) {
1110        if (s == null || s.isZERO()) {
1111            throw new ArithmeticException("division by zero " + P + ", " + s);
1112        }
1113        if (P.isZERO()) {
1114            return P;
1115        }
1116        if (s.isONE()) {
1117            return P;
1118        }
1119        GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1120        SortedMap<ExpVector, GenPolynomial<C>> pv = p.val; //getMap();
1121        for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
1122            GenPolynomial<C> c1 = m1.getValue();
1123            ExpVector e1 = m1.getKey();
1124            GenPolynomial<C> c = PolyUtil.<C> coefficientBasePseudoDivide(c1, s);
1125            if (!c.isZERO()) {
1126                pv.put(e1, c); // or m1.setValue( c )
1127            } else {
1128                System.out.println("pu, c1 = " + c1);
1129                System.out.println("pu, s  = " + s);
1130                System.out.println("pu, c  = " + c);
1131                throw new RuntimeException("something is wrong");
1132            }
1133        }
1134        return p;
1135    }
1136
1137
1138    /**
1139     * GenPolynomial sparse pseudo remainder. For recursive polynomials.
1140     * @param <C> coefficient type.
1141     * @param P recursive GenPolynomial.
1142     * @param S nonzero recursive GenPolynomial.
1143     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1144     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1145     * @deprecated Use
1146     *             {@link #recursiveSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)}
1147     *             instead
1148     */
1149    @Deprecated
1150    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursivePseudoRemainder(
1151                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1152        return recursiveSparsePseudoRemainder(P, S);
1153    }
1154
1155
1156    /**
1157     * GenPolynomial sparse pseudo remainder. For recursive polynomials.
1158     * @param <C> coefficient type.
1159     * @param P recursive GenPolynomial.
1160     * @param S nonzero recursive GenPolynomial.
1161     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1162     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1163     */
1164    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveSparsePseudoRemainder(
1165                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1166        if (S == null || S.isZERO()) {
1167            throw new ArithmeticException(P + " division by zero " + S);
1168        }
1169        if (P == null || P.isZERO()) {
1170            return P;
1171        }
1172        if (S.isONE()) {
1173            return P.ring.getZERO();
1174        }
1175        GenPolynomial<C> c = S.leadingBaseCoefficient();
1176        ExpVector e = S.leadingExpVector();
1177        GenPolynomial<GenPolynomial<C>> h;
1178        GenPolynomial<GenPolynomial<C>> r = P;
1179        while (!r.isZERO()) {
1180            ExpVector f = r.leadingExpVector();
1181            if (f.multipleOf(e)) {
1182                GenPolynomial<C> a = r.leadingBaseCoefficient();
1183                f = f.subtract(e);
1184                GenPolynomial<C> x = c; //test basePseudoRemainder(a,c);
1185                if (x.isZERO()) {
1186                    GenPolynomial<C> y = PolyUtil.<C> basePseudoDivide(a, c);
1187                    h = S.multiply(y, f); // coeff a
1188                } else {
1189                    r = r.multiply(c); // coeff ac
1190                    h = S.multiply(a, f); // coeff ac
1191                }
1192                r = r.subtract(h);
1193            } else {
1194                break;
1195            }
1196        }
1197        return r;
1198    }
1199
1200
1201    /**
1202     * GenPolynomial dense pseudo remainder. For recursive polynomials.
1203     * @param P recursive GenPolynomial.
1204     * @param S nonzero recursive GenPolynomial.
1205     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1206     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1207     */
1208    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDensePseudoRemainder(
1209                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1210        if (S == null || S.isZERO()) {
1211            throw new ArithmeticException(P + " division by zero " + S);
1212        }
1213        if (P == null || P.isZERO()) {
1214            return P;
1215        }
1216        if (S.degree() <= 0) {
1217            return P.ring.getZERO();
1218        }
1219        long m = P.degree(0);
1220        long n = S.degree(0);
1221        GenPolynomial<C> c = S.leadingBaseCoefficient();
1222        ExpVector e = S.leadingExpVector();
1223        GenPolynomial<GenPolynomial<C>> h;
1224        GenPolynomial<GenPolynomial<C>> r = P;
1225        for (long i = m; i >= n; i--) {
1226            if (r.isZERO()) {
1227                return r;
1228            }
1229            long k = r.degree(0);
1230            if (i == k) {
1231                ExpVector f = r.leadingExpVector();
1232                GenPolynomial<C> a = r.leadingBaseCoefficient();
1233                f = f.subtract(e); //EVDIF( f, e );
1234                //System.out.println("red div = " + f);
1235                r = r.multiply(c); // coeff ac
1236                h = S.multiply(a, f); // coeff ac
1237                r = r.subtract(h);
1238            } else {
1239                r = r.multiply(c);
1240            }
1241        }
1242        return r;
1243    }
1244
1245
1246    /**
1247     * GenPolynomial recursive pseudo divide. For recursive polynomials.
1248     * @param <C> coefficient type.
1249     * @param P recursive GenPolynomial.
1250     * @param S nonzero recursive GenPolynomial.
1251     * @return quotient with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1252     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1253     */
1254    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursivePseudoDivide(
1255                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1256        if (S == null || S.isZERO()) {
1257            throw new ArithmeticException(P + " division by zero " + S);
1258        }
1259        //if (S.ring.nvar != 1) {
1260            // ok if exact division
1261            // throw new RuntimeException(this.getClass().getName()
1262            //                            + " univariate polynomials only");
1263        //}
1264        if (P == null || P.isZERO()) {
1265            return P;
1266        }
1267        if (S.isONE()) {
1268            return P;
1269        }
1270        GenPolynomial<C> c = S.leadingBaseCoefficient();
1271        ExpVector e = S.leadingExpVector();
1272        GenPolynomial<GenPolynomial<C>> h;
1273        GenPolynomial<GenPolynomial<C>> r = P;
1274        GenPolynomial<GenPolynomial<C>> q = S.ring.getZERO().copy();
1275        while (!r.isZERO()) {
1276            ExpVector f = r.leadingExpVector();
1277            if (f.multipleOf(e)) {
1278                GenPolynomial<C> a = r.leadingBaseCoefficient();
1279                f = f.subtract(e);
1280                GenPolynomial<C> x = PolyUtil.<C> baseSparsePseudoRemainder(a, c);
1281                if (x.isZERO() && !c.isConstant()) {
1282                    GenPolynomial<C> y = PolyUtil.<C> basePseudoDivide(a, c);
1283                    q = q.sum(y, f);
1284                    h = S.multiply(y, f); // coeff a
1285                } else {
1286                    q = q.multiply(c);
1287                    q = q.sum(a, f);
1288                    r = r.multiply(c); // coeff ac
1289                    h = S.multiply(a, f); // coeff ac
1290                }
1291                r = r.subtract(h);
1292            } else {
1293                break;
1294            }
1295        }
1296        return q;
1297    }
1298
1299
1300    /**
1301     * Is GenPolynomial pseudo quotient and remainder. For recursive
1302     * polynomials.
1303     * @param <C> coefficient type.
1304     * @param P recursive GenPolynomial.
1305     * @param S nonzero recursive GenPolynomial.
1306     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1307     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1308     *      <b>Note:</b> not always meaningful and working
1309     */
1310    public static <C extends RingElem<C>> boolean isRecursivePseudoQuotientRemainder(
1311                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S,
1312                    GenPolynomial<GenPolynomial<C>> q, GenPolynomial<GenPolynomial<C>> r) {
1313        GenPolynomial<GenPolynomial<C>> rhs = q.multiply(S).sum(r);
1314        GenPolynomial<GenPolynomial<C>> lhs = P;
1315        GenPolynomial<C> ldcf = S.leadingBaseCoefficient();
1316        long d = P.degree(0) - S.degree(0) + 1;
1317        d = (d > 0 ? d : -d + 2);
1318        for (long i = 0; i <= d; i++) {
1319            //System.out.println("lhs = " + lhs);
1320            //System.out.println("rhs = " + rhs);
1321            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1322            if (lhs.equals(rhs)) {
1323                return true;
1324            }
1325            lhs = lhs.multiply(ldcf);
1326        }
1327        GenPolynomial<GenPolynomial<C>> Pp = P;
1328        rhs = q.multiply(S);
1329        //System.out.println("rhs,2 = " + rhs);
1330        for (long i = 0; i <= d; i++) {
1331            lhs = Pp.subtract(r);
1332            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1333            if (lhs.equals(rhs)) {
1334                //System.out.println("lhs,2 = " + lhs);
1335                return true;
1336            }
1337            Pp = Pp.multiply(ldcf);
1338        }
1339        return false;
1340    }
1341
1342
1343    /**
1344     * GenPolynomial pseudo divide. For recursive polynomials.
1345     * @param <C> coefficient type.
1346     * @param P recursive GenPolynomial.
1347     * @param s nonzero GenPolynomial.
1348     * @return quotient with ldcf(s)<sup>m</sup> P = quotient * s + remainder.
1349     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1350     */
1351    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> coefficientPseudoDivide(
1352                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
1353        if (s == null || s.isZERO()) {
1354            throw new ArithmeticException(P + " division by zero " + s);
1355        }
1356        if (P.isZERO()) {
1357            return P;
1358        }
1359        GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1360        SortedMap<ExpVector, GenPolynomial<C>> pv = p.val;
1361        for (Map.Entry<ExpVector, GenPolynomial<C>> m : P.getMap().entrySet()) {
1362            ExpVector e = m.getKey();
1363            GenPolynomial<C> c1 = m.getValue();
1364            GenPolynomial<C> c = basePseudoDivide(c1, s);
1365            if (debug) {
1366                GenPolynomial<C> x = c1.remainder(s);
1367                if (!x.isZERO()) {
1368                    logger.info("divide x = " + x);
1369                    throw new ArithmeticException(" no exact division: " + c1 + "/" + s);
1370                }
1371            }
1372            if (c.isZERO()) {
1373                System.out.println(" no exact division: " + c1 + "/" + s);
1374                //throw new ArithmeticException(" no exact division: " + c1 + "/" + s);
1375            } else {
1376                pv.put(e, c); // or m1.setValue( c )
1377            }
1378        }
1379        return p;
1380    }
1381
1382
1383    /**
1384     * GenPolynomial pseudo divide. For polynomials.
1385     * @param <C> coefficient type.
1386     * @param P GenPolynomial.
1387     * @param s nonzero coefficient.
1388     * @return quotient with ldcf(s)<sup>m</sup> P = quotient * s + remainder.
1389     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1390     */
1391    public static <C extends RingElem<C>> GenPolynomial<C> coefficientBasePseudoDivide(GenPolynomial<C> P, C s) {
1392        if (s == null || s.isZERO()) {
1393            throw new ArithmeticException(P + " division by zero " + s);
1394        }
1395        if (P.isZERO()) {
1396            return P;
1397        }
1398        GenPolynomial<C> p = P.ring.getZERO().copy();
1399        SortedMap<ExpVector, C> pv = p.val;
1400        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1401            ExpVector e = m.getKey();
1402            C c1 = m.getValue();
1403            C c = c1.divide(s);
1404            if (debug) {
1405                C x = c1.remainder(s);
1406                if (!x.isZERO()) {
1407                    logger.info("divide x = " + x);
1408                    throw new ArithmeticException(" no exact division: " + c1 + "/" + s);
1409                }
1410            }
1411            if (c.isZERO()) {
1412                System.out.println(" no exact division: " + c1 + "/" + s);
1413                //throw new ArithmeticException(" no exact division: " + c1 + "/" + s);
1414            } else {
1415                pv.put(e, c); // or m1.setValue( c )
1416            }
1417        }
1418        return p;
1419    }
1420
1421
1422    /**
1423     * GenPolynomial polynomial derivative main variable.
1424     * @param <C> coefficient type.
1425     * @param P GenPolynomial.
1426     * @return deriviative(P).
1427     */
1428    public static <C extends RingElem<C>> GenPolynomial<C> baseDeriviative(GenPolynomial<C> P) {
1429        if (P == null || P.isZERO()) {
1430            return P;
1431        }
1432        GenPolynomialRing<C> pfac = P.ring;
1433        if (pfac.nvar > 1) {
1434            // baseContent not possible by return type
1435            throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
1436        }
1437        RingFactory<C> rf = pfac.coFac;
1438        GenPolynomial<C> d = pfac.getZERO().copy();
1439        Map<ExpVector, C> dm = d.val; //getMap();
1440        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1441            ExpVector f = m.getKey();
1442            long fl = f.getVal(0);
1443            if (fl > 0) {
1444                C cf = rf.fromInteger(fl);
1445                C a = m.getValue();
1446                C x = a.multiply(cf);
1447                if (x != null && !x.isZERO()) {
1448                    ExpVector e = ExpVector.create(1, 0, fl - 1L);
1449                    dm.put(e, x);
1450                }
1451            }
1452        }
1453        return d;
1454    }
1455
1456
1457    /**
1458     * GenPolynomial polynomial partial derivative variable r.
1459     * @param <C> coefficient type.
1460     * @param P GenPolynomial.
1461     * @param r variable for partial deriviate.
1462     * @return deriviative(P,r).
1463     */
1464    public static <C extends RingElem<C>> GenPolynomial<C> baseDeriviative(GenPolynomial<C> P, int r) {
1465        if (P == null || P.isZERO()) {
1466            return P;
1467        }
1468        GenPolynomialRing<C> pfac = P.ring;
1469        if (r < 0 || pfac.nvar <= r) {
1470            throw new IllegalArgumentException(P.getClass().getName() + " deriviative variable out of bound "
1471                            + r);
1472        }
1473        int rp = pfac.nvar - 1 - r;
1474        RingFactory<C> rf = pfac.coFac;
1475        GenPolynomial<C> d = pfac.getZERO().copy();
1476        Map<ExpVector, C> dm = d.val; //getMap();
1477        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1478            ExpVector f = m.getKey();
1479            long fl = f.getVal(rp);
1480            if (fl > 0) {
1481                C cf = rf.fromInteger(fl);
1482                C a = m.getValue();
1483                C x = a.multiply(cf);
1484                if (x != null && !x.isZERO()) {
1485                    ExpVector e = f.subst(rp, fl - 1L);
1486                    dm.put(e, x);
1487                }
1488            }
1489        }
1490        return d;
1491    }
1492
1493
1494    /**
1495     * GenPolynomial polynomial integral main variable.
1496     * @param <C> coefficient type.
1497     * @param P GenPolynomial.
1498     * @return integral(P).
1499     */
1500    public static <C extends RingElem<C>> GenPolynomial<C> baseIntegral(GenPolynomial<C> P) {
1501        if (P == null || P.isZERO()) {
1502            return P;
1503        }
1504        GenPolynomialRing<C> pfac = P.ring;
1505        if (pfac.nvar > 1) {
1506            // baseContent not possible by return type
1507            throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
1508        }
1509        RingFactory<C> rf = pfac.coFac;
1510        GenPolynomial<C> d = pfac.getZERO().copy();
1511        Map<ExpVector, C> dm = d.val; //getMap();
1512        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1513            ExpVector f = m.getKey();
1514            long fl = f.getVal(0);
1515            fl++;
1516            C cf = rf.fromInteger(fl);
1517            C a = m.getValue();
1518            C x = a.divide(cf);
1519            if (x != null && !x.isZERO()) {
1520                ExpVector e = ExpVector.create(1, 0, fl);
1521                dm.put(e, x);
1522            }
1523        }
1524        return d;
1525    }
1526
1527
1528    /**
1529     * GenPolynomial recursive polynomial derivative main variable.
1530     * @param <C> coefficient type.
1531     * @param P recursive GenPolynomial.
1532     * @return deriviative(P).
1533     */
1534    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDeriviative(
1535                    GenPolynomial<GenPolynomial<C>> P) {
1536        if (P == null || P.isZERO()) {
1537            return P;
1538        }
1539        GenPolynomialRing<GenPolynomial<C>> pfac = P.ring;
1540        if (pfac.nvar > 1) {
1541            // baseContent not possible by return type
1542            throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
1543        }
1544        GenPolynomialRing<C> pr = (GenPolynomialRing<C>) pfac.coFac;
1545        RingFactory<C> rf = pr.coFac;
1546        GenPolynomial<GenPolynomial<C>> d = pfac.getZERO().copy();
1547        Map<ExpVector, GenPolynomial<C>> dm = d.val; //getMap();
1548        for (Map.Entry<ExpVector, GenPolynomial<C>> m : P.getMap().entrySet()) {
1549            ExpVector f = m.getKey();
1550            long fl = f.getVal(0);
1551            if (fl > 0) {
1552                C cf = rf.fromInteger(fl);
1553                GenPolynomial<C> a = m.getValue();
1554                GenPolynomial<C> x = a.multiply(cf);
1555                if (x != null && !x.isZERO()) {
1556                    ExpVector e = ExpVector.create(1, 0, fl - 1L);
1557                    dm.put(e, x);
1558                }
1559            }
1560        }
1561        return d;
1562    }
1563
1564
1565    /**
1566     * Factor coefficient bound. See SACIPOL.IPFCB: the product of all maxNorms
1567     * of potential factors is less than or equal to 2**b times the maxNorm of
1568     * A.
1569     * @param e degree vector of a GenPolynomial A.
1570     * @return 2**b.
1571     */
1572    public static BigInteger factorBound(ExpVector e) {
1573        int n = 0;
1574        java.math.BigInteger p = java.math.BigInteger.ONE;
1575        java.math.BigInteger v;
1576        if (e == null || e.isZERO()) {
1577            return BigInteger.ONE;
1578        }
1579        for (int i = 0; i < e.length(); i++) {
1580            if (e.getVal(i) > 0) {
1581                n += (2 * e.getVal(i) - 1);
1582                v = new java.math.BigInteger("" + (e.getVal(i) - 1));
1583                p = p.multiply(v);
1584            }
1585        }
1586        n += (p.bitCount() + 1); // log2(p)
1587        n /= 2;
1588        v = new java.math.BigInteger("" + 2);
1589        v = v.shiftLeft(n);
1590        BigInteger N = new BigInteger(v);
1591        return N;
1592    }
1593
1594
1595    /**
1596     * Evaluate at main variable.
1597     * @param <C> coefficient type.
1598     * @param cfac coefficent polynomial ring factory.
1599     * @param A recursive polynomial to be evaluated.
1600     * @param a value to evaluate at.
1601     * @return A( x_1, ..., x_{n-1}, a ).
1602     */
1603    public static <C extends RingElem<C>> GenPolynomial<C> evaluateMainRecursive(GenPolynomialRing<C> cfac,
1604                    GenPolynomial<GenPolynomial<C>> A, C a) {
1605        if (A == null || A.isZERO()) {
1606            return cfac.getZERO();
1607        }
1608        if (A.ring.nvar != 1) { // todo assert
1609            throw new IllegalArgumentException("evaluateMain no univariate polynomial");
1610        }
1611        if (a == null || a.isZERO()) {
1612            return A.trailingBaseCoefficient();
1613        }
1614        // assert descending exponents, i.e. compatible term order
1615        Map<ExpVector, GenPolynomial<C>> val = A.getMap();
1616        GenPolynomial<C> B = null;
1617        long el1 = -1; // undefined
1618        long el2 = -1;
1619        for (Map.Entry<ExpVector, GenPolynomial<C>> me : val.entrySet()) {
1620            ExpVector e = me.getKey();
1621            el2 = e.getVal(0);
1622            if (B == null /*el1 < 0*/) { // first turn
1623                B = me.getValue(); //val.get(e);
1624            } else {
1625                for (long i = el2; i < el1; i++) {
1626                    B = B.multiply(a);
1627                }
1628                B = B.sum(me.getValue()); //val.get(e));
1629            }
1630            el1 = el2;
1631        }
1632        for (long i = 0; i < el2; i++) {
1633            B = B.multiply(a);
1634        }
1635        return B;
1636    }
1637
1638
1639    /**
1640     * Evaluate at main variable.
1641     * @param <C> coefficient type.
1642     * @param cfac coefficent polynomial ring factory.
1643     * @param A distributed polynomial to be evaluated.
1644     * @param a value to evaluate at.
1645     * @return A( x_1, ..., x_{n-1}, a ).
1646     */
1647    public static <C extends RingElem<C>> GenPolynomial<C> evaluateMain(GenPolynomialRing<C> cfac,
1648                    GenPolynomial<C> A, C a) {
1649        if (A == null || A.isZERO()) {
1650            return cfac.getZERO();
1651        }
1652        GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(cfac, 1);
1653        if (rfac.nvar + cfac.nvar != A.ring.nvar) {
1654            throw new IllegalArgumentException("evaluateMain number of variabes mismatch");
1655        }
1656        GenPolynomial<GenPolynomial<C>> Ap = recursive(rfac, A);
1657        return PolyUtil.<C> evaluateMainRecursive(cfac, Ap, a);
1658    }
1659
1660
1661    /**
1662     * Evaluate at main variable.
1663     * @param <C> coefficient type.
1664     * @param cfac coefficent ring factory.
1665     * @param L list of univariate polynomials to be evaluated.
1666     * @param a value to evaluate at.
1667     * @return list( A( x_1, ..., x_{n-1}, a ) ) for A in L.
1668     */
1669    public static <C extends RingElem<C>> List<GenPolynomial<C>> evaluateMain(GenPolynomialRing<C> cfac,
1670                    List<GenPolynomial<C>> L, C a) {
1671        return ListUtil.<GenPolynomial<C>, GenPolynomial<C>> map(L, new EvalMainPol<C>(cfac, a));
1672    }
1673
1674
1675    /**
1676     * Evaluate at main variable.
1677     * @param <C> coefficient type.
1678     * @param cfac coefficent ring factory.
1679     * @param A univariate polynomial to be evaluated.
1680     * @param a value to evaluate at.
1681     * @return A( a ).
1682     */
1683    public static <C extends RingElem<C>> C evaluateMain(RingFactory<C> cfac, GenPolynomial<C> A, C a) {
1684        if (A == null || A.isZERO()) {
1685            return cfac.getZERO();
1686        }
1687        if (A.ring.nvar != 1) { // todo assert
1688            throw new IllegalArgumentException("evaluateMain no univariate polynomial");
1689        }
1690        if (a == null || a.isZERO()) {
1691            return A.trailingBaseCoefficient();
1692        }
1693        // assert decreasing exponents, i.e. compatible term order
1694        Map<ExpVector, C> val = A.getMap();
1695        C B = null;
1696        long el1 = -1; // undefined
1697        long el2 = -1;
1698        for (Map.Entry<ExpVector, C> me : val.entrySet()) {
1699            ExpVector e = me.getKey();
1700            el2 = e.getVal(0);
1701            if (B == null /*el1 < 0*/) { // first turn
1702                B = me.getValue(); // val.get(e);
1703            } else {
1704                for (long i = el2; i < el1; i++) {
1705                    B = B.multiply(a);
1706                }
1707                B = B.sum(me.getValue()); //val.get(e));
1708            }
1709            el1 = el2;
1710        }
1711        for (long i = 0; i < el2; i++) {
1712            B = B.multiply(a);
1713        }
1714        return B;
1715    }
1716
1717
1718    /**
1719     * Evaluate at main variable.
1720     * @param <C> coefficient type.
1721     * @param cfac coefficent ring factory.
1722     * @param L list of univariate polynomial to be evaluated.
1723     * @param a value to evaluate at.
1724     * @return list( A( a ) ) for A in L.
1725     */
1726    public static <C extends RingElem<C>> List<C> evaluateMain(RingFactory<C> cfac, List<GenPolynomial<C>> L,
1727                    C a) {
1728        return ListUtil.<GenPolynomial<C>, C> map(L, new EvalMain<C>(cfac, a));
1729    }
1730
1731
1732    /**
1733     * Evaluate at k-th variable.
1734     * @param <C> coefficient type.
1735     * @param cfac coefficient polynomial ring in k variables C[x_1, ..., x_k]
1736     *            factory.
1737     * @param rfac coefficient polynomial ring C[x_1, ..., x_{k-1}] [x_k]
1738     *            factory, a recursive polynomial ring in 1 variable with
1739     *            coefficients in k-1 variables.
1740     * @param nfac polynomial ring in n-1 varaibles C[x_1, ..., x_{k-1}]
1741     *            [x_{k+1}, ..., x_n] factory, a recursive polynomial ring in
1742     *            n-k+1 variables with coefficients in k-1 variables.
1743     * @param dfac polynomial ring in n-1 variables. C[x_1, ..., x_{k-1},
1744     *            x_{k+1}, ..., x_n] factory.
1745     * @param A polynomial to be evaluated.
1746     * @param a value to evaluate at.
1747     * @return A( x_1, ..., x_{k-1}, a, x_{k+1}, ..., x_n).
1748     */
1749    public static <C extends RingElem<C>> GenPolynomial<C> evaluate(GenPolynomialRing<C> cfac,
1750                    GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomialRing<GenPolynomial<C>> nfac,
1751                    GenPolynomialRing<C> dfac, GenPolynomial<C> A, C a) {
1752        if (rfac.nvar != 1) { // todo assert
1753            throw new IllegalArgumentException("evaluate coefficient ring not univariate");
1754        }
1755        if (A == null || A.isZERO()) {
1756            return cfac.getZERO();
1757        }
1758        Map<ExpVector, GenPolynomial<C>> Ap = A.contract(cfac);
1759        GenPolynomialRing<C> rcf = (GenPolynomialRing<C>) rfac.coFac;
1760        GenPolynomial<GenPolynomial<C>> Ev = nfac.getZERO().copy();
1761        Map<ExpVector, GenPolynomial<C>> Evm = Ev.val; //getMap();
1762        for (Map.Entry<ExpVector, GenPolynomial<C>> m : Ap.entrySet()) {
1763            ExpVector e = m.getKey();
1764            GenPolynomial<C> b = m.getValue();
1765            GenPolynomial<GenPolynomial<C>> c = recursive(rfac, b);
1766            GenPolynomial<C> d = evaluateMainRecursive(rcf, c, a);
1767            if (d != null && !d.isZERO()) {
1768                Evm.put(e, d);
1769            }
1770        }
1771        GenPolynomial<C> B = distribute(dfac, Ev);
1772        return B;
1773    }
1774
1775
1776    /**
1777     * Evaluate at first (lowest) variable.
1778     * @param <C> coefficient type.
1779     * @param cfac coefficient polynomial ring in first variable C[x_1] factory.
1780     * @param dfac polynomial ring in n-1 variables. C[x_2, ..., x_n] factory.
1781     * @param A polynomial to be evaluated.
1782     * @param a value to evaluate at.
1783     * @return A( a, x_2, ..., x_n).
1784     */
1785    public static <C extends RingElem<C>> GenPolynomial<C> evaluateFirst(GenPolynomialRing<C> cfac,
1786                    GenPolynomialRing<C> dfac, GenPolynomial<C> A, C a) {
1787        if (A == null || A.isZERO()) {
1788            return dfac.getZERO();
1789        }
1790        Map<ExpVector, GenPolynomial<C>> Ap = A.contract(cfac);
1791        //RingFactory<C> rcf = cfac.coFac; // == dfac.coFac
1792
1793        GenPolynomial<C> B = dfac.getZERO().copy();
1794        Map<ExpVector, C> Bm = B.val; //getMap();
1795
1796        for (Map.Entry<ExpVector, GenPolynomial<C>> m : Ap.entrySet()) {
1797            ExpVector e = m.getKey();
1798            GenPolynomial<C> b = m.getValue();
1799            C d = evaluateMain(cfac.coFac, b, a);
1800            if (d != null && !d.isZERO()) {
1801                Bm.put(e, d);
1802            }
1803        }
1804        return B;
1805    }
1806
1807
1808    /**
1809     * Evaluate at first (lowest) variable.
1810     * @param <C> coefficient type. Could also be called evaluateFirst(), but
1811     *            type erasure of A parameter does not allow same name.
1812     * @param cfac coefficient polynomial ring in first variable C[x_1] factory.
1813     * @param dfac polynomial ring in n-1 variables. C[x_2, ..., x_n] factory.
1814     * @param A recursive polynomial to be evaluated.
1815     * @param a value to evaluate at.
1816     * @return A( a, x_2, ..., x_n).
1817     */
1818    public static <C extends RingElem<C>> GenPolynomial<C> evaluateFirstRec(GenPolynomialRing<C> cfac,
1819                    GenPolynomialRing<C> dfac, GenPolynomial<GenPolynomial<C>> A, C a) {
1820        if (A == null || A.isZERO()) {
1821            return dfac.getZERO();
1822        }
1823        Map<ExpVector, GenPolynomial<C>> Ap = A.getMap();
1824        GenPolynomial<C> B = dfac.getZERO().copy();
1825        Map<ExpVector, C> Bm = B.val; //getMap();
1826        for (Map.Entry<ExpVector, GenPolynomial<C>> m : Ap.entrySet()) {
1827            ExpVector e = m.getKey();
1828            GenPolynomial<C> b = m.getValue();
1829            C d = evaluateMain(cfac.coFac, b, a);
1830            if (d != null && !d.isZERO()) {
1831                Bm.put(e, d);
1832            }
1833        }
1834        return B;
1835    }
1836
1837
1838    /**
1839     * Evaluate all variables.
1840     * @param <C> coefficient type.
1841     * @param cfac coefficient ring factory.
1842     * @param dfac polynomial ring in n variables. C[x_1, x_2, ..., x_n]
1843     *            factory.
1844     * @param A polynomial to be evaluated.
1845     * @param a = ( a_1, a_2, ..., a_n) a tuple of values to evaluate at.
1846     * @return A( a_1, a_2, ..., a_n).
1847     */
1848    public static <C extends RingElem<C>> C evaluateAll(RingFactory<C> cfac, GenPolynomialRing<C> dfac,
1849                    GenPolynomial<C> A, List<C> a) {
1850        if (A == null || A.isZERO()) {
1851            return cfac.getZERO();
1852        }
1853        if (a == null || a.size() != dfac.nvar) {
1854            throw new IllegalArgumentException("evaluate tuple size not equal to number of variables");
1855        }
1856        if (dfac.nvar == 0) {
1857            return A.trailingBaseCoefficient();
1858        }
1859        if (dfac.nvar == 1) {
1860            return evaluateMain(cfac, A, a.get(0));
1861        }
1862        C b = cfac.getZERO();
1863        GenPolynomial<C> Ap = A;
1864        for (int k = 0; k < dfac.nvar - 1; k++) {
1865            C ap = a.get(k);
1866            GenPolynomialRing<C> c1fac = new GenPolynomialRing<C>(cfac, 1);
1867            GenPolynomialRing<C> cnfac = new GenPolynomialRing<C>(cfac, dfac.nvar - 1 - k);
1868            GenPolynomial<C> Bp = evaluateFirst(c1fac, cnfac, Ap, ap);
1869            if (Bp.isZERO()) {
1870                return b;
1871            }
1872            Ap = Bp;
1873            //System.out.println("Ap = " + Ap);
1874        }
1875        C ap = a.get(dfac.nvar - 1);
1876        b = evaluateMain(cfac, Ap, ap);
1877        return b;
1878    }
1879
1880
1881    /**
1882     * Substitute main variable.
1883     * @param A univariate polynomial.
1884     * @param s polynomial for substitution.
1885     * @return polynomial A(x <- s).
1886     */
1887    public static <C extends RingElem<C>> GenPolynomial<C> substituteMain(GenPolynomial<C> A,
1888                    GenPolynomial<C> s) {
1889        return substituteUnivariate(A, s);
1890    }
1891
1892
1893    /**
1894     * Substitute univariate polynomial.
1895     * @param f univariate polynomial.
1896     * @param t polynomial for substitution.
1897     * @return polynomial A(x <- t).
1898     */
1899    public static <C extends RingElem<C>> GenPolynomial<C> substituteUnivariate(GenPolynomial<C> f,
1900                    GenPolynomial<C> t) {
1901        if (f == null || t == null) {
1902            return null;
1903        }
1904        GenPolynomialRing<C> fac = f.ring;
1905        if (fac.nvar > 1) {
1906            throw new IllegalArgumentException("only for univariate polynomial f");
1907        }
1908        if (f.isZERO() || f.isConstant()) {
1909            return f;
1910        }
1911        if (t.ring.nvar > 1) {
1912            fac = t.ring;
1913        }
1914        // assert decending exponents, i.e. compatible term order
1915        Map<ExpVector, C> val = f.getMap();
1916        GenPolynomial<C> s = null;
1917        long el1 = -1; // undefined
1918        long el2 = -1;
1919        for (Map.Entry<ExpVector, C> me : val.entrySet()) {
1920            ExpVector e = me.getKey();
1921            el2 = e.getVal(0);
1922            if (s == null /*el1 < 0*/) { // first turn
1923                s = fac.getZERO().sum(me.getValue()); //val.get(e));
1924            } else {
1925                for (long i = el2; i < el1; i++) {
1926                    s = s.multiply(t);
1927                }
1928                s = s.sum(me.getValue()); //val.get(e));
1929            }
1930            el1 = el2;
1931        }
1932        for (long i = 0; i < el2; i++) {
1933            s = s.multiply(t);
1934        }
1935        //System.out.println("s = " + s);
1936        return s;
1937    }
1938
1939
1940    /**
1941     * Taylor series for polynomial.
1942     * @param f univariate polynomial.
1943     * @param a expansion point.
1944     * @return Taylor series (a polynomial) of f at a.
1945     */
1946    public static <C extends RingElem<C>> GenPolynomial<C> seriesOfTaylor(GenPolynomial<C> f, C a) {
1947        if (f == null) {
1948            return null;
1949        }
1950        GenPolynomialRing<C> fac = f.ring;
1951        if (fac.nvar > 1) {
1952            throw new IllegalArgumentException("only for univariate polynomials");
1953        }
1954        if (f.isZERO() || f.isConstant()) {
1955            return f;
1956        }
1957        GenPolynomial<C> s = fac.getZERO();
1958        C fa = PolyUtil.<C> evaluateMain(fac.coFac, f, a);
1959        s = s.sum(fa);
1960        long n = 1;
1961        long i = 0;
1962        GenPolynomial<C> g = PolyUtil.<C> baseDeriviative(f);
1963        //GenPolynomial<C> p = fac.getONE();
1964        while (!g.isZERO()) {
1965            i++;
1966            n *= i;
1967            fa = PolyUtil.<C> evaluateMain(fac.coFac, g, a);
1968            GenPolynomial<C> q = fac.univariate(0, i); //p;
1969            q = q.multiply(fa);
1970            q = q.divide(fac.fromInteger(n));
1971            s = s.sum(q);
1972            g = PolyUtil.<C> baseDeriviative(g);
1973        }
1974        //System.out.println("s = " + s);
1975        return s;
1976    }
1977
1978
1979    /**
1980     * ModInteger interpolate on first variable.
1981     * @param <C> coefficient type.
1982     * @param fac GenPolynomial<C> result factory.
1983     * @param A GenPolynomial.
1984     * @param M GenPolynomial interpolation modul of A.
1985     * @param mi inverse of M(am) in ring fac.coFac.
1986     * @param B evaluation of other GenPolynomial.
1987     * @param am evaluation point (interpolation modul) of B, i.e. P(am) = B.
1988     * @return S, with S mod M == A and S(am) == B.
1989     */
1990    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> interpolate(
1991                    GenPolynomialRing<GenPolynomial<C>> fac, GenPolynomial<GenPolynomial<C>> A,
1992                    GenPolynomial<C> M, C mi, GenPolynomial<C> B, C am) {
1993        GenPolynomial<GenPolynomial<C>> S = fac.getZERO().copy();
1994        GenPolynomial<GenPolynomial<C>> Ap = A.copy();
1995        SortedMap<ExpVector, GenPolynomial<C>> av = Ap.val; //getMap();
1996        SortedMap<ExpVector, C> bv = B.getMap();
1997        SortedMap<ExpVector, GenPolynomial<C>> sv = S.val; //getMap();
1998        GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) fac.coFac;
1999        RingFactory<C> bfac = cfac.coFac;
2000        GenPolynomial<C> c = null;
2001        for (Map.Entry<ExpVector, C> me : bv.entrySet()) {
2002            ExpVector e = me.getKey();
2003            C y = me.getValue(); //bv.get(e); // assert y != null
2004            GenPolynomial<C> x = av.get(e);
2005            if (x != null) {
2006                av.remove(e);
2007                c = PolyUtil.<C> interpolate(cfac, x, M, mi, y, am);
2008                if (!c.isZERO()) { // 0 cannot happen
2009                    sv.put(e, c);
2010                }
2011            } else {
2012                c = PolyUtil.<C> interpolate(cfac, cfac.getZERO(), M, mi, y, am);
2013                if (!c.isZERO()) { // 0 cannot happen
2014                    sv.put(e, c); // c != null
2015                }
2016            }
2017        }
2018        // assert bv is empty = done
2019        for (Map.Entry<ExpVector, GenPolynomial<C>> me : av.entrySet()) { // rest of av
2020            ExpVector e = me.getKey();
2021            GenPolynomial<C> x = me.getValue(); //av.get(e); // assert x != null
2022            c = PolyUtil.<C> interpolate(cfac, x, M, mi, bfac.getZERO(), am);
2023            if (!c.isZERO()) { // 0 cannot happen
2024                sv.put(e, c); // c != null
2025            }
2026        }
2027        return S;
2028    }
2029
2030
2031    /**
2032     * Univariate polynomial interpolation.
2033     * @param <C> coefficient type.
2034     * @param fac GenPolynomial<C> result factory.
2035     * @param A GenPolynomial.
2036     * @param M GenPolynomial interpolation modul of A.
2037     * @param mi inverse of M(am) in ring fac.coFac.
2038     * @param a evaluation of other GenPolynomial.
2039     * @param am evaluation point (interpolation modul) of a, i.e. P(am) = a.
2040     * @return S, with S mod M == A and S(am) == a.
2041     */
2042    public static <C extends RingElem<C>> GenPolynomial<C> interpolate(GenPolynomialRing<C> fac,
2043                    GenPolynomial<C> A, GenPolynomial<C> M, C mi, C a, C am) {
2044        GenPolynomial<C> s;
2045        C b = PolyUtil.<C> evaluateMain(fac.coFac, A, am);
2046        // A mod a.modul
2047        C d = a.subtract(b); // a-A mod a.modul
2048        if (d.isZERO()) {
2049            return A;
2050        }
2051        b = d.multiply(mi); // b = (a-A)*mi mod a.modul
2052        // (M*b)+A mod M = A mod M = 
2053        // (M*mi*(a-A)+A) mod a.modul = a mod a.modul
2054        s = M.multiply(b);
2055        s = s.sum(A);
2056        return s;
2057    }
2058
2059
2060    /**
2061     * Recursive GenPolynomial switch varaible blocks.
2062     * @param <C> coefficient type.
2063     * @param P recursive GenPolynomial in R[X,Y].
2064     * @return this in R[Y,X].
2065     */
2066    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> switchVariables(
2067                    GenPolynomial<GenPolynomial<C>> P) {
2068        if (P == null) {
2069            throw new IllegalArgumentException("P == null");
2070        }
2071        GenPolynomialRing<GenPolynomial<C>> rfac1 = P.ring;
2072        GenPolynomialRing<C> cfac1 = (GenPolynomialRing<C>) rfac1.coFac;
2073        GenPolynomialRing<C> cfac2 = new GenPolynomialRing<C>(cfac1.coFac, rfac1);
2074        GenPolynomial<C> zero = cfac2.getZERO();
2075        GenPolynomialRing<GenPolynomial<C>> rfac2 = new GenPolynomialRing<GenPolynomial<C>>(cfac2, cfac1);
2076        GenPolynomial<GenPolynomial<C>> B = rfac2.getZERO().copy();
2077        if (P.isZERO()) {
2078            return B;
2079        }
2080        for (Monomial<GenPolynomial<C>> mr : P) {
2081            GenPolynomial<C> cr = mr.c;
2082            for (Monomial<C> mc : cr) {
2083                GenPolynomial<C> c = zero.sum(mc.c, mr.e);
2084                B = B.sum(c, mc.e);
2085            }
2086        }
2087        return B;
2088    }
2089
2090
2091    /**
2092     * Maximal degree of leading terms of a polynomial list.
2093     * @return maximum degree of the leading terms of a polynomial list.
2094     */
2095    public static <C extends RingElem<C>> long totalDegreeLeadingTerm(List<GenPolynomial<C>> P) {
2096        long degree = 0;
2097        for (GenPolynomial<C> g : P) {
2098            long total = g.leadingExpVector().totalDeg();
2099            if (degree < total) {
2100                degree = total;
2101            }
2102        }
2103        return degree;
2104    }
2105
2106
2107    /**
2108     * Maximal degree of polynomial list.
2109     * @return maximum degree of the polynomial list.
2110     */
2111    public static <C extends RingElem<C>> long totalDegree(List<GenPolynomial<C>> P) {
2112        long degree = 0;
2113        for (GenPolynomial<C> g : P) {
2114            long total = g.degree();
2115            if (degree < total) {
2116                degree = total;
2117            }
2118        }
2119        return degree;
2120    }
2121
2122
2123    /**
2124     * Maximal degree in the coefficient polynomials.
2125     * @param <C> coefficient type.
2126     * @return maximal degree in the coefficients.
2127     */
2128    public static <C extends RingElem<C>> long coeffMaxDegree(GenPolynomial<GenPolynomial<C>> A) {
2129        if (A.isZERO()) {
2130            return 0; // 0 or -1 ?;
2131        }
2132        long deg = 0;
2133        for (GenPolynomial<C> a : A.getMap().values()) {
2134            long d = a.degree();
2135            if (d > deg) {
2136                deg = d;
2137            }
2138        }
2139        return deg;
2140    }
2141
2142
2143    /**
2144     * Map a unary function to the coefficients.
2145     * @param ring result polynomial ring factory.
2146     * @param p polynomial.
2147     * @param f evaluation functor.
2148     * @return new polynomial with coefficients f(p(e)).
2149     */
2150    public static <C extends RingElem<C>, D extends RingElem<D>> GenPolynomial<D> map(
2151                    GenPolynomialRing<D> ring, GenPolynomial<C> p, UnaryFunctor<C, D> f) {
2152        GenPolynomial<D> n = ring.getZERO().copy();
2153        SortedMap<ExpVector, D> nv = n.val;
2154        for (Monomial<C> m : p) {
2155            D c = f.eval(m.c);
2156            if (c != null && !c.isZERO()) {
2157                nv.put(m.e, c);
2158            }
2159        }
2160        return n;
2161    }
2162
2163
2164    /**
2165     * Product representation.
2166     * @param <C> coefficient type.
2167     * @param pfac polynomial ring factory.
2168     * @param L list of polynomials to be represented.
2169     * @return Product represenation of L in the polynomial ring pfac.
2170     */
2171    public static <C extends GcdRingElem<C>> List<GenPolynomial<Product<C>>> toProductGen(
2172                    GenPolynomialRing<Product<C>> pfac, List<GenPolynomial<C>> L) {
2173
2174        List<GenPolynomial<Product<C>>> list = new ArrayList<GenPolynomial<Product<C>>>();
2175        if (L == null || L.size() == 0) {
2176            return list;
2177        }
2178        for (GenPolynomial<C> a : L) {
2179            GenPolynomial<Product<C>> b = toProductGen(pfac, a);
2180            list.add(b);
2181        }
2182        return list;
2183    }
2184
2185
2186    /**
2187     * Product representation.
2188     * @param <C> coefficient type.
2189     * @param pfac polynomial ring factory.
2190     * @param A polynomial to be represented.
2191     * @return Product represenation of A in the polynomial ring pfac.
2192     */
2193    public static <C extends GcdRingElem<C>> GenPolynomial<Product<C>> toProductGen(
2194                    GenPolynomialRing<Product<C>> pfac, GenPolynomial<C> A) {
2195
2196        GenPolynomial<Product<C>> P = pfac.getZERO().copy();
2197        if (A == null || A.isZERO()) {
2198            return P;
2199        }
2200        RingFactory<Product<C>> rpfac = pfac.coFac;
2201        ProductRing<C> rfac = (ProductRing<C>) rpfac;
2202        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
2203            ExpVector e = y.getKey();
2204            C a = y.getValue();
2205            Product<C> p = toProductGen(rfac, a);
2206            if (!p.isZERO()) {
2207                P.doPutToMap(e, p);
2208            }
2209        }
2210        return P;
2211    }
2212
2213
2214    /**
2215     * Product representation.
2216     * @param <C> coefficient type.
2217     * @param pfac product ring factory.
2218     * @param c coefficient to be represented.
2219     * @return Product represenation of c in the ring pfac.
2220     */
2221    public static <C extends GcdRingElem<C>> Product<C> toProductGen(ProductRing<C> pfac, C c) {
2222
2223        SortedMap<Integer, C> elem = new TreeMap<Integer, C>();
2224        for (int i = 0; i < pfac.length(); i++) {
2225            RingFactory<C> rfac = pfac.getFactory(i);
2226            C u = rfac.copy(c);
2227            if (u != null && !u.isZERO()) {
2228                elem.put(i, u);
2229            }
2230        }
2231        return new Product<C>(pfac, elem);
2232    }
2233
2234
2235    /**
2236     * Product representation.
2237     * @param <C> coefficient type.
2238     * @param pfac product polynomial ring factory.
2239     * @param c coefficient to be used.
2240     * @param e exponent vector.
2241     * @return Product represenation of c X^e in the ring pfac.
2242     */
2243    public static <C extends RingElem<C>> Product<GenPolynomial<C>> toProduct(
2244                    ProductRing<GenPolynomial<C>> pfac, C c, ExpVector e) {
2245        SortedMap<Integer, GenPolynomial<C>> elem = new TreeMap<Integer, GenPolynomial<C>>();
2246        for (int i = 0; i < e.length(); i++) {
2247            RingFactory<GenPolynomial<C>> rfac = pfac.getFactory(i);
2248            GenPolynomialRing<C> fac = (GenPolynomialRing<C>) rfac;
2249            //GenPolynomialRing<C> cfac = fac.ring;
2250            long a = e.getVal(i);
2251            GenPolynomial<C> u;
2252            if (a == 0) {
2253                u = fac.getONE();
2254            } else {
2255                u = fac.univariate(0, a);
2256            }
2257            u = u.multiply(c);
2258            elem.put(i, u);
2259        }
2260        return new Product<GenPolynomial<C>>(pfac, elem);
2261    }
2262
2263
2264    /**
2265     * Product representation.
2266     * @param <C> coefficient type.
2267     * @param pfac product polynomial ring factory.
2268     * @param A polynomial.
2269     * @return Product represenation of the terms of A in the ring pfac.
2270     */
2271    public static <C extends RingElem<C>> Product<GenPolynomial<C>> toProduct(
2272                    ProductRing<GenPolynomial<C>> pfac, GenPolynomial<C> A) {
2273        Product<GenPolynomial<C>> P = pfac.getZERO();
2274        if (A == null || A.isZERO()) {
2275            return P;
2276        }
2277        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
2278            ExpVector e = y.getKey();
2279            C a = y.getValue();
2280            Product<GenPolynomial<C>> p = toProduct(pfac, a, e);
2281            P = P.sum(p);
2282        }
2283        return P;
2284    }
2285
2286
2287    /**
2288     * Product representation.
2289     * @param pfac product ring factory.
2290     * @param c coefficient to be represented.
2291     * @return Product represenation of c in the ring pfac.
2292     */
2293    public static Product<ModInteger> toProduct(ProductRing<ModInteger> pfac, BigInteger c) {
2294
2295        SortedMap<Integer, ModInteger> elem = new TreeMap<Integer, ModInteger>();
2296        for (int i = 0; i < pfac.length(); i++) {
2297            RingFactory<ModInteger> rfac = pfac.getFactory(i);
2298            ModIntegerRing fac = (ModIntegerRing) rfac;
2299            ModInteger u = fac.fromInteger(c.getVal());
2300            if (!u.isZERO()) {
2301                elem.put(i, u);
2302            }
2303        }
2304        return new Product<ModInteger>(pfac, elem);
2305    }
2306
2307
2308    /**
2309     * Product representation.
2310     * @param pfac polynomial ring factory.
2311     * @param A polynomial to be represented.
2312     * @return Product represenation of A in the polynomial ring pfac.
2313     */
2314    public static GenPolynomial<Product<ModInteger>> toProduct(GenPolynomialRing<Product<ModInteger>> pfac,
2315                    GenPolynomial<BigInteger> A) {
2316
2317        GenPolynomial<Product<ModInteger>> P = pfac.getZERO().copy();
2318        if (A == null || A.isZERO()) {
2319            return P;
2320        }
2321        RingFactory<Product<ModInteger>> rpfac = pfac.coFac;
2322        ProductRing<ModInteger> fac = (ProductRing<ModInteger>) rpfac;
2323        for (Map.Entry<ExpVector, BigInteger> y : A.getMap().entrySet()) {
2324            ExpVector e = y.getKey();
2325            BigInteger a = y.getValue();
2326            Product<ModInteger> p = toProduct(fac, a);
2327            if (!p.isZERO()) {
2328                P.doPutToMap(e, p);
2329            }
2330        }
2331        return P;
2332    }
2333
2334
2335    /**
2336     * Product representation.
2337     * @param pfac polynomial ring factory.
2338     * @param L list of polynomials to be represented.
2339     * @return Product represenation of L in the polynomial ring pfac.
2340     */
2341    public static List<GenPolynomial<Product<ModInteger>>> toProduct(
2342                    GenPolynomialRing<Product<ModInteger>> pfac, List<GenPolynomial<BigInteger>> L) {
2343
2344        List<GenPolynomial<Product<ModInteger>>> list = new ArrayList<GenPolynomial<Product<ModInteger>>>();
2345        if (L == null || L.size() == 0) {
2346            return list;
2347        }
2348        for (GenPolynomial<BigInteger> a : L) {
2349            GenPolynomial<Product<ModInteger>> b = toProduct(pfac, a);
2350            list.add(b);
2351        }
2352        return list;
2353    }
2354
2355
2356    /**
2357     * Remove all upper variables which do not occur in polynomial.
2358     * @param p polynomial.
2359     * @return polynomial with removed variables
2360     */
2361    public static <C extends RingElem<C>> GenPolynomial<C> removeUnusedUpperVariables(GenPolynomial<C> p) {
2362        GenPolynomialRing<C> fac = p.ring;
2363        if (fac.nvar <= 1) { // univariate
2364            return p;
2365        }
2366        int[] dep = p.degreeVector().dependencyOnVariables();
2367        if (fac.nvar == dep.length) { // all variables appear
2368            return p;
2369        }
2370        if (dep.length == 0) { // no variables
2371            GenPolynomialRing<C> fac0 = new GenPolynomialRing<C>(fac.coFac, 0);
2372            GenPolynomial<C> p0 = new GenPolynomial<C>(fac0, p.leadingBaseCoefficient());
2373            return p0;
2374        }
2375        int l = dep[0]; // higher variable
2376        int r = dep[dep.length - 1]; // lower variable
2377        if (l == 0 /*|| l == fac.nvar-1*/) { // upper variable appears
2378            return p;
2379        }
2380        int n = l;
2381        GenPolynomialRing<C> facr = fac.contract(n);
2382        Map<ExpVector, GenPolynomial<C>> mpr = p.contract(facr);
2383        if (mpr.size() != 1) {
2384            System.out.println("upper ex, l = " + l + ", r = " + r + ", p = " + p + ", fac = "
2385                            + fac.toScript());
2386            throw new RuntimeException("this should not happen " + mpr);
2387        }
2388        GenPolynomial<C> pr = mpr.values().iterator().next();
2389        n = fac.nvar - 1 - r;
2390        if (n == 0) {
2391            return pr;
2392        } // else case not implemented
2393        return pr;
2394    }
2395
2396
2397    /**
2398     * Remove all lower variables which do not occur in polynomial.
2399     * @param p polynomial.
2400     * @return polynomial with removed variables
2401     */
2402    public static <C extends RingElem<C>> GenPolynomial<C> removeUnusedLowerVariables(GenPolynomial<C> p) {
2403        GenPolynomialRing<C> fac = p.ring;
2404        if (fac.nvar <= 1) { // univariate
2405            return p;
2406        }
2407        int[] dep = p.degreeVector().dependencyOnVariables();
2408        if (fac.nvar == dep.length) { // all variables appear
2409            return p;
2410        }
2411        if (dep.length == 0) { // no variables
2412            GenPolynomialRing<C> fac0 = new GenPolynomialRing<C>(fac.coFac, 0);
2413            GenPolynomial<C> p0 = new GenPolynomial<C>(fac0, p.leadingBaseCoefficient());
2414            return p0;
2415        }
2416        int l = dep[0]; // higher variable
2417        int r = dep[dep.length - 1]; // lower variable
2418        if (r == fac.nvar - 1) { // lower variable appears
2419            return p;
2420        }
2421        int n = r + 1;
2422        GenPolynomialRing<GenPolynomial<C>> rfac = fac.recursive(n);
2423        GenPolynomial<GenPolynomial<C>> mpr = recursive(rfac, p);
2424        if (mpr.length() != p.length()) {
2425            System.out.println("lower ex, l = " + l + ", r = " + r + ", p = " + p + ", fac = "
2426                            + fac.toScript());
2427            throw new RuntimeException("this should not happen " + mpr);
2428        }
2429        RingFactory<C> cf = fac.coFac;
2430        GenPolynomialRing<C> facl = new GenPolynomialRing<C>(cf, rfac);
2431        GenPolynomial<C> pr = facl.getZERO().copy();
2432        for (Monomial<GenPolynomial<C>> m : mpr) {
2433            ExpVector e = m.e;
2434            GenPolynomial<C> a = m.c;
2435            if (!a.isConstant()) {
2436                throw new RuntimeException("this can not happen " + a);
2437            }
2438            C c = a.leadingBaseCoefficient();
2439            pr.doPutToMap(e, c);
2440        }
2441        return pr;
2442    }
2443
2444
2445    /**
2446     * Remove upper block of middle variables which do not occur in polynomial.
2447     * @param p polynomial.
2448     * @return polynomial with removed variables
2449     */
2450    public static <C extends RingElem<C>> GenPolynomial<C> removeUnusedMiddleVariables(GenPolynomial<C> p) {
2451        GenPolynomialRing<C> fac = p.ring;
2452        if (fac.nvar <= 2) { // univariate or bi-variate
2453            return p;
2454        }
2455        int[] dep = p.degreeVector().dependencyOnVariables();
2456        if (fac.nvar == dep.length) { // all variables appear
2457            return p;
2458        }
2459        if (dep.length == 0) { // no variables
2460            GenPolynomialRing<C> fac0 = new GenPolynomialRing<C>(fac.coFac, 0);
2461            GenPolynomial<C> p0 = new GenPolynomial<C>(fac0, p.leadingBaseCoefficient());
2462            return p0;
2463        }
2464        ExpVector e1 = p.leadingExpVector();
2465        if (dep.length == 1) { // one variable
2466            TermOrder to = new TermOrder(fac.tord.getEvord());
2467            int i = dep[0];
2468            String v1 = e1.indexVarName(i, fac.getVars());
2469            String[] vars = new String[] { v1 };
2470            GenPolynomialRing<C> fac1 = new GenPolynomialRing<C>(fac.coFac, to, vars);
2471            GenPolynomial<C> p1 = fac1.getZERO().copy();
2472            for (Monomial<C> m : p) {
2473                ExpVector e = m.e;
2474                ExpVector f = ExpVector.create(1, 0, e.getVal(i));
2475                p1.doPutToMap(f, m.c);
2476            }
2477            return p1;
2478        }
2479        GenPolynomialRing<GenPolynomial<C>> rfac = fac.recursive(1);
2480        GenPolynomial<GenPolynomial<C>> mpr = recursive(rfac, p);
2481
2482        int l = dep[0]; // higher variable
2483        int r = fac.nvar - dep[1]; // next variable
2484        //System.out.println("l  = " + l);
2485        //System.out.println("r  = " + r);
2486
2487        TermOrder to = new TermOrder(fac.tord.getEvord());
2488        String[] vs = fac.getVars();
2489        String[] vars = new String[r + 1];
2490        for (int i = 0; i < r; i++) {
2491            vars[i] = vs[i];
2492        }
2493        vars[r] = e1.indexVarName(l, vs);
2494        //System.out.println("fac  = " + fac);
2495        GenPolynomialRing<C> dfac = new GenPolynomialRing<C>(fac.coFac, to, vars);
2496        //System.out.println("dfac = " + dfac);
2497        GenPolynomialRing<GenPolynomial<C>> fac2 = dfac.recursive(1);
2498        GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) fac2.coFac;
2499        GenPolynomial<GenPolynomial<C>> p2r = fac2.getZERO().copy();
2500        for (Monomial<GenPolynomial<C>> m : mpr) {
2501            ExpVector e = m.e;
2502            GenPolynomial<C> a = m.c;
2503            Map<ExpVector, GenPolynomial<C>> cc = a.contract(cfac);
2504            for (Map.Entry<ExpVector, GenPolynomial<C>> me : cc.entrySet()) {
2505                ExpVector f = me.getKey();
2506                if (f.isZERO()) {
2507                    GenPolynomial<C> c = me.getValue(); //cc.get(f);
2508                    p2r.doPutToMap(e, c);
2509                } else {
2510                    throw new RuntimeException("this should not happen " + cc);
2511                }
2512            }
2513        }
2514        GenPolynomial<C> p2 = distribute(dfac, p2r);
2515        return p2;
2516    }
2517
2518
2519    /**
2520     * Select polynomial with univariate leading term in variable i.
2521     * @param i variable index.
2522     * @return polynomial with head term in variable i
2523     */
2524    public static <C extends RingElem<C>> GenPolynomial<C> selectWithVariable(List<GenPolynomial<C>> P, int i) {
2525        for (GenPolynomial<C> p : P) {
2526            int[] dep = p.leadingExpVector().dependencyOnVariables();
2527            if (dep.length == 1 && dep[0] == i) {
2528                return p;
2529            }
2530        }
2531        return null; // not found       
2532    }
2533
2534}
2535
2536
2537/**
2538 * Conversion of distributive to recursive representation.
2539 */
2540class DistToRec<C extends RingElem<C>> implements
2541                UnaryFunctor<GenPolynomial<C>, GenPolynomial<GenPolynomial<C>>> {
2542
2543
2544    GenPolynomialRing<GenPolynomial<C>> fac;
2545
2546
2547    public DistToRec(GenPolynomialRing<GenPolynomial<C>> fac) {
2548        this.fac = fac;
2549    }
2550
2551
2552    public GenPolynomial<GenPolynomial<C>> eval(GenPolynomial<C> c) {
2553        if (c == null) {
2554            return fac.getZERO();
2555        }
2556        return PolyUtil.<C> recursive(fac, c);
2557    }
2558}
2559
2560
2561/**
2562 * Conversion of recursive to distributive representation.
2563 */
2564class RecToDist<C extends RingElem<C>> implements
2565                UnaryFunctor<GenPolynomial<GenPolynomial<C>>, GenPolynomial<C>> {
2566
2567
2568    GenPolynomialRing<C> fac;
2569
2570
2571    public RecToDist(GenPolynomialRing<C> fac) {
2572        this.fac = fac;
2573    }
2574
2575
2576    public GenPolynomial<C> eval(GenPolynomial<GenPolynomial<C>> c) {
2577        if (c == null) {
2578            return fac.getZERO();
2579        }
2580        return PolyUtil.<C> distribute(fac, c);
2581    }
2582}
2583
2584
2585/**
2586 * BigRational numerator functor.
2587 */
2588class RatNumer implements UnaryFunctor<BigRational, BigInteger> {
2589
2590
2591    public BigInteger eval(BigRational c) {
2592        if (c == null) {
2593            return new BigInteger();
2594        }
2595        return new BigInteger(c.numerator());
2596    }
2597}
2598
2599
2600/**
2601 * Conversion of symmetric ModInteger to BigInteger functor.
2602 */
2603class ModSymToInt<C extends RingElem<C> & Modular> implements UnaryFunctor<C, BigInteger> {
2604
2605
2606    public BigInteger eval(C c) {
2607        if (c == null) {
2608            return new BigInteger();
2609        }
2610        return c.getSymmetricInteger();
2611    }
2612}
2613
2614
2615/**
2616 * Conversion of ModInteger to BigInteger functor.
2617 */
2618class ModToInt<C extends RingElem<C> & Modular> implements UnaryFunctor<C, BigInteger> {
2619
2620
2621    public BigInteger eval(C c) {
2622        if (c == null) {
2623            return new BigInteger();
2624        }
2625        return c.getInteger();
2626    }
2627}
2628
2629
2630/**
2631 * Conversion of BigRational to BigInteger with division by lcm functor. result
2632 * = num*(lcm/denom).
2633 */
2634class RatToInt implements UnaryFunctor<BigRational, BigInteger> {
2635
2636
2637    java.math.BigInteger lcm;
2638
2639
2640    public RatToInt(java.math.BigInteger lcm) {
2641        this.lcm = lcm; //.getVal();
2642    }
2643
2644
2645    public BigInteger eval(BigRational c) {
2646        if (c == null) {
2647            return new BigInteger();
2648        }
2649        // p = num*(lcm/denom)
2650        java.math.BigInteger b = lcm.divide(c.denominator());
2651        return new BigInteger(c.numerator().multiply(b));
2652    }
2653}
2654
2655
2656/**
2657 *  * Conversion of BigRational to BigInteger. result = (num/gcd)*(lcm/denom).  
2658 */
2659class RatToIntFactor implements UnaryFunctor<BigRational, BigInteger> {
2660
2661
2662    final java.math.BigInteger lcm;
2663
2664
2665    final java.math.BigInteger gcd;
2666
2667
2668    public RatToIntFactor(java.math.BigInteger gcd, java.math.BigInteger lcm) {
2669        this.gcd = gcd;
2670        this.lcm = lcm; // .getVal();
2671    }
2672
2673
2674    public BigInteger eval(BigRational c) {
2675        if (c == null) {
2676            return new BigInteger();
2677        }
2678        if (gcd.equals(java.math.BigInteger.ONE)) {
2679            // p = num*(lcm/denom)
2680            java.math.BigInteger b = lcm.divide(c.denominator());
2681            return new BigInteger(c.numerator().multiply(b));
2682        }
2683        // p = (num/gcd)*(lcm/denom)
2684        java.math.BigInteger a = c.numerator().divide(gcd);
2685        java.math.BigInteger b = lcm.divide(c.denominator());
2686        return new BigInteger(a.multiply(b));
2687    }
2688}
2689
2690
2691/**
2692 * Conversion of Rational to BigDecimal. result = decimal(r).
2693 */
2694class RatToDec<C extends Element<C> & Rational> implements UnaryFunctor<C, BigDecimal> {
2695
2696
2697    public BigDecimal eval(C c) {
2698        if (c == null) {
2699            return new BigDecimal();
2700        }
2701        return new BigDecimal(c.getRational());
2702    }
2703}
2704
2705
2706/**
2707 * Conversion of Complex Rational to Complex BigDecimal. result = decimal(r).
2708 */
2709class CompRatToDec<C extends RingElem<C> & Rational> implements UnaryFunctor<Complex<C>, Complex<BigDecimal>> {
2710
2711
2712    ComplexRing<BigDecimal> ring;
2713
2714
2715    public CompRatToDec(RingFactory<Complex<BigDecimal>> ring) {
2716        this.ring = (ComplexRing<BigDecimal>) ring;
2717    }
2718
2719
2720    public Complex<BigDecimal> eval(Complex<C> c) {
2721        if (c == null) {
2722            return ring.getZERO();
2723        }
2724        BigDecimal r = new BigDecimal(c.getRe().getRational());
2725        BigDecimal i = new BigDecimal(c.getIm().getRational());
2726        return new Complex<BigDecimal>(ring, r, i);
2727    }
2728}
2729
2730
2731/**
2732 * Conversion from BigInteger functor.
2733 */
2734class FromInteger<D extends RingElem<D>> implements UnaryFunctor<BigInteger, D> {
2735
2736
2737    RingFactory<D> ring;
2738
2739
2740    public FromInteger(RingFactory<D> ring) {
2741        this.ring = ring;
2742    }
2743
2744
2745    public D eval(BigInteger c) {
2746        if (c == null) {
2747            return ring.getZERO();
2748        }
2749        return ring.fromInteger(c.getVal());
2750    }
2751}
2752
2753
2754/**
2755 * Conversion from GenPolynomial<BigInteger> functor.
2756 */
2757class FromIntegerPoly<D extends RingElem<D>> implements
2758                UnaryFunctor<GenPolynomial<BigInteger>, GenPolynomial<D>> {
2759
2760
2761    GenPolynomialRing<D> ring;
2762
2763
2764    FromInteger<D> fi;
2765
2766
2767    public FromIntegerPoly(GenPolynomialRing<D> ring) {
2768        if (ring == null) {
2769            throw new IllegalArgumentException("ring must not be null");
2770        }
2771        this.ring = ring;
2772        fi = new FromInteger<D>(ring.coFac);
2773    }
2774
2775
2776    public GenPolynomial<D> eval(GenPolynomial<BigInteger> c) {
2777        if (c == null) {
2778            return ring.getZERO();
2779        }
2780        return PolyUtil.<BigInteger, D> map(ring, c, fi);
2781    }
2782}
2783
2784
2785/**
2786 * Conversion from GenPolynomial<BigRational> to GenPolynomial<BigInteger>
2787 * functor.
2788 */
2789class RatToIntPoly implements UnaryFunctor<GenPolynomial<BigRational>, GenPolynomial<BigInteger>> {
2790
2791
2792    GenPolynomialRing<BigInteger> ring;
2793
2794
2795    public RatToIntPoly(GenPolynomialRing<BigInteger> ring) {
2796        if (ring == null) {
2797            throw new IllegalArgumentException("ring must not be null");
2798        }
2799        this.ring = ring;
2800    }
2801
2802
2803    public GenPolynomial<BigInteger> eval(GenPolynomial<BigRational> c) {
2804        if (c == null) {
2805            return ring.getZERO();
2806        }
2807        return PolyUtil.integerFromRationalCoefficients(ring, c);
2808    }
2809}
2810
2811
2812/**
2813 * Real part functor.
2814 */
2815class RealPart implements UnaryFunctor<BigComplex, BigRational> {
2816
2817
2818    public BigRational eval(BigComplex c) {
2819        if (c == null) {
2820            return new BigRational();
2821        }
2822        return c.getRe();
2823    }
2824}
2825
2826
2827/**
2828 * Imaginary part functor.
2829 */
2830class ImagPart implements UnaryFunctor<BigComplex, BigRational> {
2831
2832
2833    public BigRational eval(BigComplex c) {
2834        if (c == null) {
2835            return new BigRational();
2836        }
2837        return c.getIm();
2838    }
2839}
2840
2841
2842/**
2843 * Real part functor.
2844 */
2845class RealPartComplex<C extends RingElem<C>> implements UnaryFunctor<Complex<C>, C> {
2846
2847
2848    public C eval(Complex<C> c) {
2849        if (c == null) {
2850            return null;
2851        }
2852        return c.getRe();
2853    }
2854}
2855
2856
2857/**
2858 * Imaginary part functor.
2859 */
2860class ImagPartComplex<C extends RingElem<C>> implements UnaryFunctor<Complex<C>, C> {
2861
2862
2863    public C eval(Complex<C> c) {
2864        if (c == null) {
2865            return null;
2866        }
2867        return c.getIm();
2868    }
2869}
2870
2871
2872/**
2873 * Rational to complex functor.
2874 */
2875class ToComplex<C extends RingElem<C>> implements UnaryFunctor<C, Complex<C>> {
2876
2877
2878    final protected ComplexRing<C> cfac;
2879
2880
2881    @SuppressWarnings("unchecked")
2882    public ToComplex(RingFactory<Complex<C>> fac) {
2883        if (fac == null) {
2884            throw new IllegalArgumentException("fac must not be null");
2885        }
2886        cfac = (ComplexRing<C>) fac;
2887    }
2888
2889
2890    public Complex<C> eval(C c) {
2891        if (c == null) {
2892            return cfac.getZERO();
2893        }
2894        return new Complex<C>(cfac, c);
2895    }
2896}
2897
2898
2899/**
2900 * Rational to complex functor.
2901 */
2902class RatToCompl implements UnaryFunctor<BigRational, BigComplex> {
2903
2904
2905    public BigComplex eval(BigRational c) {
2906        if (c == null) {
2907            return new BigComplex();
2908        }
2909        return new BigComplex(c);
2910    }
2911}
2912
2913
2914/**
2915 * Any ring element to generic complex functor.
2916 */
2917class AnyToComplex<C extends GcdRingElem<C>> implements UnaryFunctor<C, Complex<C>> {
2918
2919
2920    final protected ComplexRing<C> cfac;
2921
2922
2923    public AnyToComplex(ComplexRing<C> fac) {
2924        if (fac == null) {
2925            throw new IllegalArgumentException("fac must not be null");
2926        }
2927        cfac = fac;
2928    }
2929
2930
2931    public AnyToComplex(RingFactory<C> fac) {
2932        this(new ComplexRing<C>(fac));
2933    }
2934
2935
2936    public Complex<C> eval(C a) {
2937        if (a == null || a.isZERO()) { // should not happen
2938            return cfac.getZERO();
2939        } else if (a.isONE()) {
2940            return cfac.getONE();
2941        } else {
2942            return new Complex<C>(cfac, a);
2943        }
2944    }
2945}
2946
2947
2948/**
2949 * Algebraic to generic complex functor.
2950 */
2951class AlgebToCompl<C extends GcdRingElem<C>> implements UnaryFunctor<AlgebraicNumber<C>, Complex<C>> {
2952
2953
2954    final protected ComplexRing<C> cfac;
2955
2956
2957    public AlgebToCompl(ComplexRing<C> fac) {
2958        if (fac == null) {
2959            throw new IllegalArgumentException("fac must not be null");
2960        }
2961        cfac = fac;
2962    }
2963
2964
2965    public Complex<C> eval(AlgebraicNumber<C> a) {
2966        if (a == null || a.isZERO()) { // should not happen
2967            return cfac.getZERO();
2968        } else if (a.isONE()) {
2969            return cfac.getONE();
2970        } else {
2971            GenPolynomial<C> p = a.getVal();
2972            C real = cfac.ring.getZERO();
2973            C imag = cfac.ring.getZERO();
2974            for (Monomial<C> m : p) {
2975                if (m.exponent().getVal(0) == 1L) {
2976                    imag = m.coefficient();
2977                } else if (m.exponent().getVal(0) == 0L) {
2978                    real = m.coefficient();
2979                } else {
2980                    throw new IllegalArgumentException("unexpected monomial " + m);
2981                }
2982            }
2983            //Complex<C> c = new Complex<C>(cfac,real,imag);
2984            return new Complex<C>(cfac, real, imag);
2985        }
2986    }
2987}
2988
2989
2990/**
2991 * Ceneric complex to algebraic number functor.
2992 */
2993class ComplToAlgeb<C extends GcdRingElem<C>> implements UnaryFunctor<Complex<C>, AlgebraicNumber<C>> {
2994
2995
2996    final protected AlgebraicNumberRing<C> afac;
2997
2998
2999    final protected AlgebraicNumber<C> I;
3000
3001
3002    public ComplToAlgeb(AlgebraicNumberRing<C> fac) {
3003        if (fac == null) {
3004            throw new IllegalArgumentException("fac must not be null");
3005        }
3006        afac = fac;
3007        I = afac.getGenerator();
3008    }
3009
3010
3011    public AlgebraicNumber<C> eval(Complex<C> c) {
3012        if (c == null || c.isZERO()) { // should not happen
3013            return afac.getZERO();
3014        } else if (c.isONE()) {
3015            return afac.getONE();
3016        } else if (c.isIMAG()) {
3017            return I;
3018        } else {
3019            return I.multiply(c.getIm()).sum(c.getRe());
3020        }
3021    }
3022}
3023
3024
3025/**
3026 * Algebraic to polynomial functor.
3027 */
3028class AlgToPoly<C extends GcdRingElem<C>> implements UnaryFunctor<AlgebraicNumber<C>, GenPolynomial<C>> {
3029
3030
3031    public GenPolynomial<C> eval(AlgebraicNumber<C> c) {
3032        if (c == null) {
3033            return null;
3034        }
3035        return c.val;
3036    }
3037}
3038
3039
3040/**
3041 * Polynomial to algebriac functor.
3042 */
3043class PolyToAlg<C extends GcdRingElem<C>> implements UnaryFunctor<GenPolynomial<C>, AlgebraicNumber<C>> {
3044
3045
3046    final protected AlgebraicNumberRing<C> afac;
3047
3048
3049    public PolyToAlg(AlgebraicNumberRing<C> fac) {
3050        if (fac == null) {
3051            throw new IllegalArgumentException("fac must not be null");
3052        }
3053        afac = fac;
3054    }
3055
3056
3057    public AlgebraicNumber<C> eval(GenPolynomial<C> c) {
3058        if (c == null) {
3059            return afac.getZERO();
3060        }
3061        return new AlgebraicNumber<C>(afac, c);
3062    }
3063}
3064
3065
3066/**
3067 * Coefficient to algebriac functor.
3068 */
3069class CoeffToAlg<C extends GcdRingElem<C>> implements UnaryFunctor<C, AlgebraicNumber<C>> {
3070
3071
3072    final protected AlgebraicNumberRing<C> afac;
3073
3074
3075    final protected GenPolynomial<C> zero;
3076
3077
3078    public CoeffToAlg(AlgebraicNumberRing<C> fac) {
3079        if (fac == null) {
3080            throw new IllegalArgumentException("fac must not be null");
3081        }
3082        afac = fac;
3083        GenPolynomialRing<C> pfac = afac.ring;
3084        zero = pfac.getZERO();
3085    }
3086
3087
3088    public AlgebraicNumber<C> eval(C c) {
3089        if (c == null) {
3090            return afac.getZERO();
3091        }
3092        return new AlgebraicNumber<C>(afac, zero.sum(c));
3093    }
3094}
3095
3096
3097/**
3098 * Coefficient to recursive algebriac functor.
3099 */
3100class CoeffToRecAlg<C extends GcdRingElem<C>> implements UnaryFunctor<C, AlgebraicNumber<C>> {
3101
3102
3103    final protected List<AlgebraicNumberRing<C>> lfac;
3104
3105
3106    final int depth;
3107
3108
3109    @SuppressWarnings("unchecked")
3110    public CoeffToRecAlg(int depth, AlgebraicNumberRing<C> fac) {
3111        if (fac == null) {
3112            throw new IllegalArgumentException("fac must not be null");
3113        }
3114        AlgebraicNumberRing<C> afac = fac;
3115        this.depth = depth;
3116        lfac = new ArrayList<AlgebraicNumberRing<C>>(this.depth);
3117        lfac.add(fac);
3118        for (int i = 1; i < this.depth; i++) {
3119            RingFactory<C> rf = afac.ring.coFac;
3120            if (!(rf instanceof AlgebraicNumberRing)) {
3121                throw new IllegalArgumentException("fac depth to low");
3122            }
3123            afac = (AlgebraicNumberRing<C>) (Object) rf;
3124            lfac.add(afac);
3125        }
3126    }
3127
3128
3129    @SuppressWarnings("unchecked")
3130    public AlgebraicNumber<C> eval(C c) {
3131        if (c == null) {
3132            return lfac.get(0).getZERO();
3133        }
3134        C ac = c;
3135        AlgebraicNumberRing<C> af = lfac.get(lfac.size() - 1);
3136        GenPolynomial<C> zero = af.ring.getZERO();
3137        AlgebraicNumber<C> an = new AlgebraicNumber<C>(af, zero.sum(ac));
3138        for (int i = lfac.size() - 2; i >= 0; i--) {
3139            af = lfac.get(i);
3140            zero = af.ring.getZERO();
3141            ac = (C) (Object) an;
3142            an = new AlgebraicNumber<C>(af, zero.sum(ac));
3143        }
3144        return an;
3145    }
3146}
3147
3148
3149/**
3150 * Evaluate main variable functor.
3151 */
3152class EvalMain<C extends RingElem<C>> implements UnaryFunctor<GenPolynomial<C>, C> {
3153
3154
3155    final RingFactory<C> cfac;
3156
3157
3158    final C a;
3159
3160
3161    public EvalMain(RingFactory<C> cfac, C a) {
3162        this.cfac = cfac;
3163        this.a = a;
3164    }
3165
3166
3167    public C eval(GenPolynomial<C> c) {
3168        if (c == null) {
3169            return cfac.getZERO();
3170        }
3171        return PolyUtil.<C> evaluateMain(cfac, c, a);
3172    }
3173}
3174
3175
3176/**
3177 * Evaluate main variable functor.
3178 */
3179class EvalMainPol<C extends RingElem<C>> implements UnaryFunctor<GenPolynomial<C>, GenPolynomial<C>> {
3180
3181
3182    final GenPolynomialRing<C> cfac;
3183
3184
3185    final C a;
3186
3187
3188    public EvalMainPol(GenPolynomialRing<C> cfac, C a) {
3189        this.cfac = cfac;
3190        this.a = a;
3191    }
3192
3193
3194    public GenPolynomial<C> eval(GenPolynomial<C> c) {
3195        if (c == null) {
3196            return cfac.getZERO();
3197        }
3198        return PolyUtil.<C> evaluateMain(cfac, c, a);
3199    }
3200}