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