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