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