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 representations 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 representations 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 representations 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 representations 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(
1094                    final GenPolynomial<C> P, final 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        //logger.debug("P, S = " + P + ", " + S);
1112        final C c = S.leadingBaseCoefficient();
1113        final ExpVector e = S.leadingExpVector();
1114        GenPolynomial<C> h;
1115        GenPolynomial<C> r = P;
1116        GenPolynomial<C> q = S.ring.getZERO().copy();
1117
1118        while (!r.isZERO()) {
1119            ExpVector f = r.leadingExpVector();
1120            if (f.multipleOf(e)) {
1121                C a = r.leadingBaseCoefficient();
1122                f = f.subtract(e);
1123                C x = a.remainder(c);
1124                if (x.isZERO()) {
1125                    C y = a.divide(c);
1126                    q = q.sum(y, f);
1127                    h = S.multiply(y, f); // coeff a
1128                } else {
1129                    q = q.multiply(c);
1130                    q = q.sum(a, f);
1131                    r = r.multiply(c); // coeff a c
1132                    h = S.multiply(a, f); // coeff c a
1133                }
1134                r = r.subtract(h);
1135                //logger.debug("q, r = " + q + ", " + r);
1136            } else {
1137                break;
1138            }
1139        }
1140        //GenPolynomial<C> rhs = q.multiply(S).sum(r);
1141        //GenPolynomial<C> lhs = P;
1142        ret[0] = q;
1143        ret[1] = r;
1144        return ret;
1145    }
1146
1147
1148    /**
1149     * Is GenPolynomial pseudo quotient and remainder. For univariate
1150     * polynomials.
1151     * @param <C> coefficient type.
1152     * @param P base GenPolynomial.
1153     * @param S nonzero base GenPolynomial.
1154     * @return true, if P = q * S + r, else false.
1155     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1156     *      <b>Note:</b> not always meaningful and working
1157     */
1158    public static <C extends RingElem<C>> boolean isBasePseudoQuotientRemainder(GenPolynomial<C> P,
1159                    GenPolynomial<C> S, GenPolynomial<C> q, GenPolynomial<C> r) {
1160        GenPolynomial<C> rhs = q.multiply(S).sum(r);
1161        //System.out.println("rhs,1 = " + rhs);
1162        GenPolynomial<C> lhs = P;
1163        C ldcf = S.leadingBaseCoefficient();
1164        long d = P.degree(0) - S.degree(0) + 1;
1165        d = (d > 0 ? d : -d + 2);
1166        for (long i = 0; i <= d; i++) {
1167            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1168            if (lhs.equals(rhs) || lhs.negate().equals(rhs)) {
1169                //System.out.println("lhs,1 = " + lhs);
1170                return true;
1171            }
1172            lhs = lhs.multiply(ldcf);
1173        }
1174        GenPolynomial<C> Pp = P;
1175        rhs = q.multiply(S);
1176        //System.out.println("rhs,2 = " + rhs);
1177        for (long i = 0; i <= d; i++) {
1178            lhs = Pp.subtract(r);
1179            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1180            if (lhs.equals(rhs) || lhs.negate().equals(rhs)) {
1181                //System.out.println("lhs,2 = " + lhs);
1182                return true;
1183            }
1184            Pp = Pp.multiply(ldcf);
1185        }
1186        C a = P.leadingBaseCoefficient();
1187        rhs = q.multiply(S).sum(r);
1188        C b = rhs.leadingBaseCoefficient();
1189        C gcd = a.gcd(b);
1190        C p = a.multiply(b);
1191        C lcm = p.divide(gcd);
1192        C ap = lcm.divide(a);
1193        C bp = lcm.divide(b);
1194        if (P.multiply(ap).equals(rhs.multiply(bp))) {
1195            return true;
1196        }
1197        return false;
1198    }
1199
1200
1201    /**
1202     * GenPolynomial divide. For recursive polynomials. Division by coefficient
1203     * ring element.
1204     * @param <C> coefficient type.
1205     * @param P recursive GenPolynomial.
1206     * @param s GenPolynomial.
1207     * @return this/s.
1208     */
1209    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDivide(
1210                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
1211        if (s == null || s.isZERO()) {
1212            throw new ArithmeticException("division by zero " + P + ", " + s);
1213        }
1214        if (P.isZERO()) {
1215            return P;
1216        }
1217        if (s.isONE()) {
1218            return P;
1219        }
1220        GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1221        SortedMap<ExpVector, GenPolynomial<C>> pv = p.val; //getMap();
1222        for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
1223            GenPolynomial<C> c1 = m1.getValue();
1224            ExpVector e1 = m1.getKey();
1225            GenPolynomial<C> c = PolyUtil.<C> basePseudoDivide(c1, s);
1226            if (!c.isZERO()) {
1227                pv.put(e1, c); // or m1.setValue( c )
1228            } else {
1229                logger.warn("rDiv, P  = {}", P);
1230                logger.warn("rDiv, c1 = {}", c1);
1231                logger.warn("rDiv, s  = {}", s);
1232                logger.warn("rDiv, c  = {}", c);
1233                throw new RuntimeException("something is wrong");
1234            }
1235        }
1236        return p;
1237    }
1238
1239
1240    /**
1241     * GenPolynomial divide. For recursive polynomials. Division by coefficient
1242     * ring element.
1243     * @param <C> coefficient type.
1244     * @param P recursive GenPolynomial.
1245     * @param s GenPolynomial.
1246     * @return this/s.
1247     */
1248    public static <C extends RingElem<C>> GenWordPolynomial<GenPolynomial<C>> recursiveDivide(
1249                    GenWordPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
1250        if (s == null || s.isZERO()) {
1251            throw new ArithmeticException("division by zero " + P + ", " + s);
1252        }
1253        if (P.isZERO()) {
1254            return P;
1255        }
1256        if (s.isONE()) {
1257            return P;
1258        }
1259        GenWordPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1260        SortedMap<Word, GenPolynomial<C>> pv = p.val; //getMap();
1261        for (Map.Entry<Word, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
1262            GenPolynomial<C> c1 = m1.getValue();
1263            Word e1 = m1.getKey();
1264            GenPolynomial<C> c = PolyUtil.<C> basePseudoDivide(c1, s);
1265            if (!c.isZERO()) {
1266                pv.put(e1, c); // or m1.setValue( c )
1267            } else {
1268                logger.warn("rDiv, P  = {}", P);
1269                logger.warn("rDiv, c1 = {}", c1);
1270                logger.warn("rDiv, s  = {}", s);
1271                logger.warn("rDiv, c  = {}", c);
1272                throw new RuntimeException("something is wrong");
1273            }
1274        }
1275        return p;
1276    }
1277
1278
1279    /**
1280     * GenPolynomial base divide. For recursive polynomials. Division by
1281     * coefficient ring element.
1282     * @param <C> coefficient type.
1283     * @param P recursive GenPolynomial.
1284     * @param s coefficient.
1285     * @return this/s.
1286     */
1287    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> baseRecursiveDivide(
1288                    GenPolynomial<GenPolynomial<C>> P, C s) {
1289        if (s == null || s.isZERO()) {
1290            throw new ArithmeticException("division by zero " + P + ", " + s);
1291        }
1292        if (P.isZERO()) {
1293            return P;
1294        }
1295        if (s.isONE()) {
1296            return P;
1297        }
1298        GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1299        SortedMap<ExpVector, GenPolynomial<C>> pv = p.val; //getMap();
1300        for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
1301            GenPolynomial<C> c1 = m1.getValue();
1302            ExpVector e1 = m1.getKey();
1303            GenPolynomial<C> c = PolyUtil.<C> coefficientBasePseudoDivide(c1, s);
1304            if (!c.isZERO()) {
1305                pv.put(e1, c); // or m1.setValue( c )
1306            } else {
1307                logger.warn("pu, c1 = {}", c1);
1308                logger.warn("pu, s  = {}", s);
1309                logger.warn("pu, c  = {}", c);
1310                throw new RuntimeException("something is wrong");
1311            }
1312        }
1313        return p;
1314    }
1315
1316
1317    /**
1318     * GenPolynomial sparse pseudo remainder. For recursive polynomials.
1319     * @param <C> coefficient type.
1320     * @param P recursive GenPolynomial.
1321     * @param S nonzero recursive GenPolynomial.
1322     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1323     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1324     * @deprecated(forRemoval=true) Use
1325     *                              {@link #recursiveSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)}
1326     *                              instead
1327     */
1328    @Deprecated
1329    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursivePseudoRemainder(
1330                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1331        return recursiveSparsePseudoRemainder(P, S);
1332    }
1333
1334
1335    /**
1336     * GenPolynomial sparse pseudo remainder. For recursive polynomials.
1337     * @param <C> coefficient type.
1338     * @param P recursive GenPolynomial.
1339     * @param S nonzero recursive GenPolynomial.
1340     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1341     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1342     */
1343    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveSparsePseudoRemainder(
1344                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1345        if (S == null || S.isZERO()) {
1346            throw new ArithmeticException(P + " division by zero " + S);
1347        }
1348        if (P == null || P.isZERO()) {
1349            return P;
1350        }
1351        if (S.isConstant()) {
1352            return P.ring.getZERO();
1353        }
1354        GenPolynomial<C> c = S.leadingBaseCoefficient();
1355        ExpVector e = S.leadingExpVector();
1356        GenPolynomial<GenPolynomial<C>> h;
1357        GenPolynomial<GenPolynomial<C>> r = P;
1358        while (!r.isZERO()) {
1359            ExpVector f = r.leadingExpVector();
1360            if (f.multipleOf(e)) {
1361                GenPolynomial<C> a = r.leadingBaseCoefficient();
1362                f = f.subtract(e);
1363                GenPolynomial<C> x = c; //test basePseudoRemainder(a,c);
1364                if (x.isZERO()) {
1365                    GenPolynomial<C> y = PolyUtil.<C> basePseudoDivide(a, c);
1366                    h = S.multiply(y, f); // coeff a
1367                } else {
1368                    r = r.multiply(c); // coeff a c
1369                    h = S.multiply(a, f); // coeff c a
1370                }
1371                r = r.subtract(h);
1372            } else {
1373                break;
1374            }
1375        }
1376        return r;
1377    }
1378
1379
1380    /**
1381     * GenPolynomial dense pseudo remainder. For recursive polynomials.
1382     * @param P recursive GenPolynomial.
1383     * @param S nonzero recursive GenPolynomial.
1384     * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1385     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1386     */
1387    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDensePseudoRemainder(
1388                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1389        if (S == null || S.isZERO()) {
1390            throw new ArithmeticException(P + " division by zero " + S);
1391        }
1392        if (P == null || P.isZERO()) {
1393            return P;
1394        }
1395        if (S.isConstant()) {
1396            return P.ring.getZERO();
1397        }
1398        long m = P.degree(0);
1399        long n = S.degree(0);
1400        GenPolynomial<C> c = S.leadingBaseCoefficient();
1401        ExpVector e = S.leadingExpVector();
1402        GenPolynomial<GenPolynomial<C>> h;
1403        GenPolynomial<GenPolynomial<C>> r = P;
1404        for (long i = m; i >= n; i--) {
1405            if (r.isZERO()) {
1406                return r;
1407            }
1408            long k = r.degree(0);
1409            if (i == k) {
1410                ExpVector f = r.leadingExpVector();
1411                GenPolynomial<C> a = r.leadingBaseCoefficient();
1412                f = f.subtract(e); //EVDIF( f, e );
1413                //System.out.println("red div = " + f);
1414                r = r.multiply(c); // coeff ac
1415                h = S.multiply(a, f); // coeff ac
1416                r = r.subtract(h);
1417            } else {
1418                r = r.multiply(c);
1419            }
1420        }
1421        return r;
1422    }
1423
1424
1425    /**
1426     * GenPolynomial recursive pseudo divide. For recursive polynomials.
1427     * @param <C> coefficient type.
1428     * @param P recursive GenPolynomial.
1429     * @param S nonzero recursive GenPolynomial.
1430     * @return quotient with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
1431     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1432     */
1433    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursivePseudoDivide(
1434                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S) {
1435        if (S == null || S.isZERO()) {
1436            throw new ArithmeticException(P + " division by zero " + S);
1437        }
1438        //if (S.ring.nvar != 1) {
1439        // ok if exact division
1440        // throw new RuntimeException(this.getClass().getName()
1441        //                            + " univariate polynomials only");
1442        //}
1443        if (P == null || P.isZERO()) {
1444            return P;
1445        }
1446        if (S.isONE()) {
1447            return P;
1448        }
1449        GenPolynomial<C> c = S.leadingBaseCoefficient();
1450        ExpVector e = S.leadingExpVector();
1451        GenPolynomial<GenPolynomial<C>> h;
1452        GenPolynomial<GenPolynomial<C>> r = P;
1453        GenPolynomial<GenPolynomial<C>> q = S.ring.getZERO().copy();
1454        while (!r.isZERO()) {
1455            ExpVector f = r.leadingExpVector();
1456            if (f.multipleOf(e)) {
1457                GenPolynomial<C> a = r.leadingBaseCoefficient();
1458                f = f.subtract(e);
1459                GenPolynomial<C> x = PolyUtil.<C> baseSparsePseudoRemainder(a, c);
1460                if (x.isZERO() && !c.isConstant()) {
1461                    GenPolynomial<C> y = PolyUtil.<C> basePseudoDivide(a, c);
1462                    q = q.sum(y, f);
1463                    h = S.multiply(y, f); // coeff a
1464                } else {
1465                    q = q.multiply(c);
1466                    q = q.sum(a, f);
1467                    r = r.multiply(c); // coeff ac
1468                    h = S.multiply(a, f); // coeff ac
1469                }
1470                r = r.subtract(h);
1471            } else {
1472                break;
1473            }
1474        }
1475        return q;
1476    }
1477
1478
1479    /**
1480     * Is recursive GenPolynomial pseudo quotient and remainder. For recursive
1481     * polynomials.
1482     * @param <C> coefficient type.
1483     * @param P recursive GenPolynomial.
1484     * @param S nonzero recursive GenPolynomial.
1485     * @return true, if P ~= q * S + r, else false.
1486     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1487     *      <b>Note:</b> not always meaningful and working
1488     */
1489    public static <C extends RingElem<C>> boolean isRecursivePseudoQuotientRemainder(
1490                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<GenPolynomial<C>> S,
1491                    GenPolynomial<GenPolynomial<C>> q, GenPolynomial<GenPolynomial<C>> r) {
1492        GenPolynomial<GenPolynomial<C>> rhs = q.multiply(S).sum(r);
1493        GenPolynomial<GenPolynomial<C>> lhs = P;
1494        GenPolynomial<C> ldcf = S.leadingBaseCoefficient();
1495        long d = P.degree(0) - S.degree(0) + 1;
1496        d = (d > 0 ? d : -d + 2);
1497        for (long i = 0; i <= d; i++) {
1498            //System.out.println("lhs = " + lhs);
1499            //System.out.println("rhs = " + rhs);
1500            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1501            if (lhs.equals(rhs)) {
1502                return true;
1503            }
1504            lhs = lhs.multiply(ldcf);
1505        }
1506        GenPolynomial<GenPolynomial<C>> Pp = P;
1507        rhs = q.multiply(S);
1508        //System.out.println("rhs,2 = " + rhs);
1509        for (long i = 0; i <= d; i++) {
1510            lhs = Pp.subtract(r);
1511            //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
1512            if (lhs.equals(rhs)) {
1513                //System.out.println("lhs,2 = " + lhs);
1514                return true;
1515            }
1516            Pp = Pp.multiply(ldcf);
1517        }
1518        GenPolynomial<C> a = P.leadingBaseCoefficient();
1519        rhs = q.multiply(S).sum(r);
1520        GenPolynomial<C> b = rhs.leadingBaseCoefficient();
1521        GenPolynomial<GenPolynomial<C>> Pb = P.multiply(b);
1522        GenPolynomial<GenPolynomial<C>> rhsa = rhs.multiply(a);
1523        if (Pb.equals(rhsa)) {
1524            return true;
1525        }
1526        //System.out.println("b     = " + b);
1527        //System.out.println("a     = " + a);
1528        //System.out.println("P*b   = " + Pb);
1529        //System.out.println("rhs*a = " + rhsa);
1530        if (Pb.degree() != rhsa.degree()
1531                        || !Pb.leadingBaseCoefficient().equals(rhsa.leadingBaseCoefficient())) {
1532            return false;
1533        }
1534        return false;
1535    }
1536
1537
1538    /**
1539     * GenPolynomial pseudo divide. For recursive polynomials.
1540     * @param <C> coefficient type.
1541     * @param P recursive GenPolynomial.
1542     * @param s nonzero GenPolynomial.
1543     * @return quotient with ldcf(s)<sup>m</sup> P = quotient * s + remainder.
1544     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1545     */
1546    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> coefficientPseudoDivide(
1547                    GenPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
1548        if (s == null || s.isZERO()) {
1549            throw new ArithmeticException(P + " division by zero " + s);
1550        }
1551        if (P.isZERO()) {
1552            return P;
1553        }
1554        GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
1555        SortedMap<ExpVector, GenPolynomial<C>> pv = p.val;
1556        for (Map.Entry<ExpVector, GenPolynomial<C>> m : P.getMap().entrySet()) {
1557            ExpVector e = m.getKey();
1558            GenPolynomial<C> c1 = m.getValue();
1559            GenPolynomial<C> c = basePseudoDivide(c1, s);
1560            if (debug) {
1561                GenPolynomial<C> x = c1.remainder(s);
1562                if (!x.isZERO()) {
1563                    logger.info("divide x = {}", x);
1564                    throw new ArithmeticException("no exact division: " + c1 + "/" + s);
1565                }
1566            }
1567            if (c.isZERO()) {
1568                //logger.warn("no exact division: {}/{}", c1, s);
1569                throw new ArithmeticException("no exact division: " + c1 + "/" + s);
1570            }
1571            pv.put(e, c); // or m1.setValue( c )
1572        }
1573        return p;
1574    }
1575
1576
1577    /**
1578     * GenPolynomial pseudo divide. For polynomials.
1579     * @param <C> coefficient type.
1580     * @param P GenPolynomial.
1581     * @param s nonzero coefficient.
1582     * @return quotient with ldcf(s)<sup>m</sup> P = quotient * s + remainder.
1583     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
1584     */
1585    public static <C extends RingElem<C>> GenPolynomial<C> coefficientBasePseudoDivide(GenPolynomial<C> P,
1586                    C s) {
1587        if (s == null || s.isZERO()) {
1588            throw new ArithmeticException(P + " division by zero " + s);
1589        }
1590        if (P.isZERO()) {
1591            return P;
1592        }
1593        GenPolynomial<C> p = P.ring.getZERO().copy();
1594        SortedMap<ExpVector, C> pv = p.val;
1595        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1596            ExpVector e = m.getKey();
1597            C c1 = m.getValue();
1598            C c = c1.divide(s);
1599            if (debug) {
1600                C x = c1.remainder(s);
1601                if (!x.isZERO()) {
1602                    logger.info("divide x = {}", x);
1603                    throw new ArithmeticException("no exact division: " + c1 + "/" + s);
1604                }
1605            }
1606            if (c.isZERO()) {
1607                //logger.warn("no exact division: {}/{}", c1, s);
1608                throw new ArithmeticException("no exact division: " + c1 + "/" + s);
1609            }
1610            pv.put(e, c); // or m1.setValue( c )
1611        }
1612        return p;
1613    }
1614
1615
1616    /**
1617     * GenExteriorPolynomial polynomial exterior derivative.
1618     * @param <C> coefficient type.
1619     * @param P GenExteriorPolynomial.
1620     * @return exteriorDerivative(P).
1621     */
1622    public static <C extends RingElem<C>> GenExteriorPolynomial<C> exteriorDerivative(
1623                    GenExteriorPolynomial<C> P) {
1624        if (P == null || P.isZERO()) {
1625            return P;
1626        }
1627        GenExteriorPolynomialRing<C> pfac = P.ring;
1628        IndexFactory ifac = pfac.ixfac;
1629        int im = ifac.imaxlength;
1630        if (im == 0) {
1631            return pfac.getZERO();
1632        }
1633        //RingFactory<C> rf = pfac.coFac;
1634        GenExteriorPolynomial<C> d = pfac.getZERO().copy();
1635        Map<IndexList, C> dm = d.val;
1636        for (Map.Entry<IndexList, C> m : P.getMap().entrySet()) {
1637            //if (P.length() == 1) {
1638            //Map.Entry<IndexList, C> m = P.leadingMonomial();
1639            C a = m.getValue();
1640            IndexList il = m.getKey();
1641            C b;
1642            IndexList bi;
1643            for (int i = 1; i <= im; i++) {
1644                IndexList di = new IndexList(ifac, new int[] { i });
1645                bi = di.multiply(il);
1646                if (bi.signum() == 0) {
1647                    continue;
1648                }
1649                b = a; // b = a.derivative();
1650                if (bi.signum() < 0) {
1651                    bi = bi.negate();
1652                    b = b.negate();
1653                }
1654                dm.put(bi, b);
1655            }
1656        }
1657        return d;
1658    }
1659
1660
1661    /**
1662     * GenExteriorPolynomial over polynomial exterior derivative.
1663     * @param <C> coefficient type.
1664     * @param P GenExteriorPolynomial<GenPolynomial>.
1665     * @return exteriorDerivativePoly(P).
1666     */
1667    public static <C extends RingElem<C>> GenExteriorPolynomial<GenPolynomial<C>> exteriorDerivativePoly(
1668                    GenExteriorPolynomial<GenPolynomial<C>> P) {
1669        if (P == null || P.isZERO()) {
1670            return P;
1671        }
1672        GenExteriorPolynomialRing<GenPolynomial<C>> pfac = P.ring;
1673        IndexFactory ifac = pfac.ixfac;
1674        int im = ifac.imaxlength;
1675        if (im == 0) {
1676            return pfac.getZERO();
1677        }
1678        //RingFactory<GenPolynomial<C>> rf = pfac.coFac;
1679        GenExteriorPolynomial<GenPolynomial<C>> d = pfac.getZERO().copy();
1680        Map<IndexList, GenPolynomial<C>> dm = d.val;
1681        for (Map.Entry<IndexList, GenPolynomial<C>> m : P.getMap().entrySet()) {
1682            //if (P.length() == 1) {
1683            //Map.Entry<IndexList, C> m = P.leadingMonomial();
1684            GenPolynomial<C> a = m.getValue();
1685            IndexList il = m.getKey();
1686            GenPolynomial<C> b;
1687            IndexList bi;
1688            for (int i = 1; i <= im; i++) {
1689                IndexList di = new IndexList(ifac, new int[] { i });
1690                bi = di.multiply(il);
1691                if (bi.signum() == 0) {
1692                    continue;
1693                }
1694                b = PolyUtil.<C> baseDerivative(a, i - 1); //a.derivative();
1695                //System.out.println("baseDerivative a = " + a + ", i-1 = " + (i-1) + ", b = " + b);
1696                if (b.isZERO()) {
1697                    continue;
1698                }
1699                if (bi.signum() < 0) {
1700                    bi = bi.negate();
1701                    b = b.negate();
1702                }
1703                dm.put(bi, b);
1704            }
1705        }
1706        return d;
1707    }
1708
1709
1710    /**
1711     * GenPolynomial polynomial derivative main variable.
1712     * @param <C> coefficient type.
1713     * @param P GenPolynomial.
1714     * @return derivative(P).
1715     */
1716    public static <C extends RingElem<C>> GenPolynomial<C> baseDerivative(GenPolynomial<C> P) {
1717        if (P == null || P.isZERO()) {
1718            return P;
1719        }
1720        GenPolynomialRing<C> pfac = P.ring;
1721        if (pfac.nvar == 0) {
1722            return pfac.getZERO();
1723        }
1724        if (pfac.nvar > 1) {
1725            // baseContent not possible by return type
1726            throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
1727        }
1728        RingFactory<C> rf = pfac.coFac;
1729        GenPolynomial<C> d = pfac.getZERO().copy();
1730        Map<ExpVector, C> dm = d.val; //getMap();
1731        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1732            ExpVector f = m.getKey();
1733            long fl = f.getVal(0);
1734            if (fl > 0) {
1735                C cf = rf.fromInteger(fl);
1736                C a = m.getValue();
1737                C x = a.multiply(cf);
1738                if (x != null && !x.isZERO()) {
1739                    ExpVector e = ExpVector.create(1, 0, fl - 1L);
1740                    dm.put(e, x);
1741                }
1742            }
1743        }
1744        return d;
1745    }
1746
1747
1748    /**
1749     * GenPolynomial polynomial partial derivative variable r.
1750     * @param <C> coefficient type.
1751     * @param P GenPolynomial.
1752     * @param r variable for partial deriviate.
1753     * @return derivative(P,r).
1754     */
1755    public static <C extends RingElem<C>> GenPolynomial<C> baseDerivative(GenPolynomial<C> P, int r) {
1756        if (P == null || P.isZERO()) {
1757            return P;
1758        }
1759        GenPolynomialRing<C> pfac = P.ring;
1760        if (r < 0 || pfac.nvar <= r) {
1761            throw new IllegalArgumentException(
1762                            P.getClass().getName() + " derivative variable out of bound " + r);
1763        }
1764        int rp = pfac.nvar - 1 - r;
1765        RingFactory<C> rf = pfac.coFac;
1766        GenPolynomial<C> d = pfac.getZERO().copy();
1767        Map<ExpVector, C> dm = d.val; //getMap();
1768        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1769            ExpVector f = m.getKey();
1770            long fl = f.getVal(rp);
1771            if (fl > 0) {
1772                C cf = rf.fromInteger(fl);
1773                C a = m.getValue();
1774                C x = a.multiply(cf);
1775                if (x != null && !x.isZERO()) {
1776                    ExpVector e = f.subst(rp, fl - 1L);
1777                    dm.put(e, x);
1778                }
1779            }
1780        }
1781        return d;
1782    }
1783
1784
1785    /**
1786     * GenPolynomial polynomial integral main variable.
1787     * @param <C> coefficient type.
1788     * @param P GenPolynomial.
1789     * @return integral(P).
1790     */
1791    public static <C extends RingElem<C>> GenPolynomial<C> baseIntegral(GenPolynomial<C> P) {
1792        if (P == null || P.isZERO()) {
1793            return P;
1794        }
1795        GenPolynomialRing<C> pfac = P.ring;
1796        if (pfac.nvar == 0) {
1797            return pfac.getONE();
1798        }
1799        if (pfac.nvar > 1) {
1800            // baseContent not possible by return type
1801            throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
1802        }
1803        RingFactory<C> rf = pfac.coFac;
1804        GenPolynomial<C> d = pfac.getZERO().copy();
1805        Map<ExpVector, C> dm = d.val; //getMap();
1806        for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
1807            ExpVector f = m.getKey();
1808            long fl = f.getVal(0);
1809            fl++;
1810            C cf = rf.fromInteger(fl);
1811            C a = m.getValue();
1812            C x = a.divide(cf);
1813            if (x != null && !x.isZERO()) {
1814                ExpVector e = ExpVector.create(1, 0, fl);
1815                dm.put(e, x);
1816            }
1817        }
1818        return d;
1819    }
1820
1821
1822    /**
1823     * GenPolynomial recursive polynomial derivative main variable.
1824     * @param <C> coefficient type.
1825     * @param P recursive GenPolynomial.
1826     * @return derivative(P).
1827     */
1828    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDerivative(
1829                    GenPolynomial<GenPolynomial<C>> P) {
1830        if (P == null || P.isZERO()) {
1831            return P;
1832        }
1833        GenPolynomialRing<GenPolynomial<C>> pfac = P.ring;
1834        if (pfac.nvar == 0) {
1835            return pfac.getZERO();
1836        }
1837        if (pfac.nvar > 1) {
1838            // baseContent not possible by return type
1839            throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
1840        }
1841        GenPolynomialRing<C> pr = (GenPolynomialRing<C>) pfac.coFac;
1842        RingFactory<C> rf = pr.coFac;
1843        GenPolynomial<GenPolynomial<C>> d = pfac.getZERO().copy();
1844        Map<ExpVector, GenPolynomial<C>> dm = d.val; //getMap();
1845        for (Map.Entry<ExpVector, GenPolynomial<C>> m : P.getMap().entrySet()) {
1846            ExpVector f = m.getKey();
1847            long fl = f.getVal(0);
1848            if (fl > 0) {
1849                C cf = rf.fromInteger(fl);
1850                GenPolynomial<C> a = m.getValue();
1851                GenPolynomial<C> x = a.multiply(cf);
1852                if (x != null && !x.isZERO()) {
1853                    ExpVector e = ExpVector.create(1, 0, fl - 1L);
1854                    dm.put(e, x);
1855                }
1856            }
1857        }
1858        return d;
1859    }
1860
1861
1862    /**
1863     * Factor coefficient bound. The product of all maxNorms of potential
1864     * factors is less than or equal to 2**b times the maxNorm of A. Gelfonds
1865     * bound is used.
1866     * @param e degree vector of a GenPolynomial A.
1867     * @return 2**b.
1868     * @see "maspoly.SACIPOL.mi#IPFCB from SAC2/MAS"
1869     */
1870    public static BigInteger factorBound(ExpVector e) {
1871        long n = 0;
1872        java.math.BigInteger p = java.math.BigInteger.ONE;
1873        java.math.BigInteger v;
1874        if (e == null || e.isZERO()) {
1875            return BigInteger.ONE;
1876        }
1877        for (int i = 0; i < e.length(); i++) {
1878            if (e.getVal(i) > 0L) {
1879                n += (2 * e.getVal(i) - 1);
1880                v = new java.math.BigInteger("" + (e.getVal(i) - 1));
1881                p = p.multiply(v);
1882            }
1883        }
1884        n += (p.bitCount() + 1); // log2(p)
1885        n /= 2;
1886        v = new java.math.BigInteger("" + 2);
1887        while (n >= 16) {
1888            n -= 16;
1889            v = v.shiftLeft(16);
1890        }
1891        if (n > 0) {
1892            v = v.shiftLeft((int) n); // n < 16
1893        }
1894        BigInteger N = new BigInteger(v);
1895        return N;
1896    }
1897
1898
1899    /**
1900     * Absolute norm. Square root of the sum of the squared coefficients.
1901     * @param p GenPolynomial
1902     * @return sqrt( sum<sub>i</sub> |c<sub>i</sub>|<sup>2</sup> ).
1903     */
1904    @SuppressWarnings("unchecked")
1905    public static <C extends RingElem<C>> C absNorm(GenPolynomial<C> p) {
1906        if (p == null) {
1907            return null;
1908        }
1909        C a = p.ring.getZEROCoefficient();
1910        if (a instanceof StarRingElem) {
1911            //System.out.println("StarRingElem case");
1912            for (C c : p.val.values()) {
1913                C n = (C) ((StarRingElem) c).norm();
1914                a = a.sum(n);
1915            }
1916        } else {
1917            for (C c : p.val.values()) {
1918                C n = c.multiply(c);
1919                a = a.sum(n);
1920            }
1921        }
1922        // compute square root if possible
1923        // refactor for sqrt in RingElem ?
1924        if (a instanceof BigRational) {
1925            BigRational b = (BigRational) a;
1926            a = (C) Roots.sqrt(b);
1927        } else if (a instanceof BigComplex) {
1928            BigComplex b = (BigComplex) a;
1929            a = (C) Roots.sqrt(b);
1930        } else if (a instanceof BigInteger) {
1931            BigInteger b = (BigInteger) a;
1932            a = (C) Roots.sqrt(b);
1933        } else if (a instanceof BigDecimal) {
1934            BigDecimal b = (BigDecimal) a;
1935            a = (C) Roots.sqrt(b);
1936        } else if (a instanceof BigDecimalComplex) {
1937            BigDecimalComplex b = (BigDecimalComplex) a;
1938            a = (C) Roots.sqrt(b);
1939        } else {
1940            logger.error("no square root implemented for {}", a.toScriptFactory());
1941        }
1942        return a;
1943    }
1944
1945
1946    /**
1947     * Polynomial reciprocal transformation.
1948     * @param <C> coefficient type.
1949     * @param A is a non-zero polynomial, with n=DEG(A).
1950     * @return B with B(x) = x**n*A(1/x), where x is the main variable of A.
1951     * @see "maspoly.SACPOL.mi#PRT from SAC2/MAS"
1952     */
1953    public static <C extends RingElem<C>> GenPolynomial<C> reciprocalTransformation(GenPolynomial<C> A) {
1954        return reciprocalTransformation(A, 0);
1955    }
1956
1957
1958    /**
1959     * Polynomial reciprocal transformation.
1960     * @param <C> coefficient type.
1961     * @param A is a non-zero polynomial, with n=DEG(A,i), A(x_r, ..., x_0).
1962     * @param i variable to be transformed, 0 is the main variable.
1963     * @return B with B(x) = x_i**n*A(1/x_i), where x_i is the i-th variable of
1964     *         A.
1965     * @see "maspoly.SACPOL.mi#PRT from SAC2/MAS"
1966     */
1967    public static <C extends RingElem<C>> GenPolynomial<C> reciprocalTransformation(GenPolynomial<C> A,
1968                    int i) {
1969        if (A == null) {
1970            return null;
1971        }
1972        GenPolynomialRing<C> pfac = A.ring;
1973        GenPolynomial<C> B = pfac.getZERO().copy();
1974        if (A.isZERO()) {
1975            return B;
1976        }
1977        int m = i;
1978        long d = A.degree(m);
1979        //System.out.println("d = " + d + ", m = " + m);
1980        Map<ExpVector, C> val = A.val;
1981        Map<ExpVector, C> valb = B.val;
1982        for (Map.Entry<ExpVector, C> me : val.entrySet()) {
1983            ExpVector e = me.getKey();
1984            long de = d - e.getVal(m);
1985            ExpVector f = e.subst(m, de);
1986            C c = me.getValue();
1987            valb.put(f, c);
1988        }
1989        return B;
1990    }
1991
1992
1993    /**
1994     * Polynomial translation, main variable.
1995     * @param <C> coefficient type.
1996     * @param A is a non-zero polynomial in r variables, A(x_1, ..., x(r-1),
1997     *            x_r).
1998     * @param h is a coefficient ring element.
1999     * @return B with B(x1, ..., x(r-1), xr) = A(x1, ..., x(r-1), xr+h).
2000     * @see "maspoly.SACIPOL.mi#IPTRAN from SAC2/MAS"
2001     */
2002    public static <C extends RingElem<C>> GenPolynomial<C> translationMain(GenPolynomial<C> A, C h) {
2003        if (A == null) {
2004            return null;
2005        }
2006        if (A.isZERO() || h.isZERO()) {
2007            return A;
2008        }
2009        GenPolynomialRing<C> pfac = A.ring;
2010        GenPolynomialRing<GenPolynomial<C>> rfac = pfac.recursive(1);
2011        GenPolynomial<GenPolynomial<C>> Ar = recursive(rfac, A);
2012        GenPolynomial<GenPolynomial<C>> Br = translationMainRecursive(Ar, h);
2013        GenPolynomial<C> B = distribute(pfac, Br);
2014        return B;
2015    }
2016
2017
2018    /**
2019     * Polynomial translation, main variable.
2020     * @param <C> coefficient type.
2021     * @param A is a non-zero recursive polynomial in r variables, A(x_1, ...,
2022     *            x(r-1))(x_r).
2023     * @param h is a coefficient ring element.
2024     * @return B with B(x1, ..., x(r-1))(xr) = A(x1, ..., x(r-1))(xr+h).
2025     * @see "maspoly.SACIPOL.mi#IPTRAN from SAC2/MAS"
2026     */
2027    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> translationMainRecursive(
2028                    GenPolynomial<GenPolynomial<C>> A, C h) {
2029        if (A == null) {
2030            return null;
2031        }
2032        GenPolynomialRing<GenPolynomial<C>> pfac = A.ring;
2033        if (pfac.nvar != 1) {
2034            throw new IllegalArgumentException("translationMainRecursive no univariate polynomial");
2035        }
2036        if (A.isZERO() || h.isZERO()) {
2037            return A;
2038        }
2039        // assert descending exponents, i.e. compatible term order
2040        Map<ExpVector, GenPolynomial<C>> val = A.val;
2041        GenPolynomial<GenPolynomial<C>> c = null;
2042        ExpVector z = pfac.evzero;
2043        ExpVector x = pfac.evzero.subst(0, 1L);
2044        GenPolynomial<C> H = pfac.getONECoefficient().multiply(h);
2045        long el1 = -1; // undefined
2046        long el2 = -1;
2047        for (Map.Entry<ExpVector, GenPolynomial<C>> me : val.entrySet()) {
2048            ExpVector e = me.getKey();
2049            el2 = e.getVal(0);
2050            GenPolynomial<C> b = me.getValue();
2051            if (c == null) {
2052                c = pfac.valueOf(b, z);
2053            } else {
2054                for (long i = el2; i < el1; i++) { // i = 0, el1-el2.
2055                    GenPolynomial<GenPolynomial<C>> d1 = c.multiply(x);
2056                    GenPolynomial<GenPolynomial<C>> d2 = c.multiply(H);
2057                    c = d1.sum(d2);
2058                }
2059                c = c.sum(b);
2060            }
2061            el1 = el2;
2062        }
2063        for (long i = 0; i < el2; i++) {
2064            GenPolynomial<GenPolynomial<C>> d1 = c.multiply(x);
2065            GenPolynomial<GenPolynomial<C>> d2 = c.multiply(H);
2066            c = d1.sum(d2);
2067        }
2068        return c;
2069    }
2070
2071
2072    /**
2073     * Polynomial translation, base univariate.
2074     * @param <C> coefficient type.
2075     * @param A is a non-zero polynomial in 1 variables, A(x_1).
2076     * @param h is a coefficient ring element.
2077     * @return B with B(x1) = A(x1+h1).
2078     * @see "maspoly.SACIPOL.mi#IPTRAN from SAC2/MAS"
2079     */
2080    public static <C extends RingElem<C>> GenPolynomial<C> translationBase(GenPolynomial<C> A, C h) {
2081        if (A == null) {
2082            return null;
2083        }
2084        GenPolynomialRing<C> pfac = A.ring;
2085        if (pfac.nvar != 1) {
2086            throw new IllegalArgumentException("translationBase no univariate polynomial");
2087        }
2088        if (A.isZERO()) {
2089            return A;
2090        }
2091        // assert descending exponents, i.e. compatible term order
2092        Map<ExpVector, C> val = A.val;
2093        GenPolynomial<C> c = null;
2094        ExpVector z = pfac.evzero;
2095        ExpVector x = pfac.evzero.subst(0, 1L);
2096        long el1 = -1; // undefined
2097        long el2 = -1;
2098        for (Map.Entry<ExpVector, C> me : val.entrySet()) {
2099            ExpVector e = me.getKey();
2100            el2 = e.getVal(0);
2101            C b = me.getValue();
2102            if (c == null) {
2103                c = pfac.valueOf(b, z);
2104            } else {
2105                for (long i = el2; i < el1; i++) { // i = 0, el1-el2.
2106                    GenPolynomial<C> d1 = c.multiply(x);
2107                    GenPolynomial<C> d2 = c.multiply(h);
2108                    c = d1.sum(d2);
2109                }
2110                c = c.sum(b);
2111            }
2112            el1 = el2;
2113        }
2114        for (long i = 0; i < el2; i++) {
2115            GenPolynomial<C> d1 = c.multiply(x);
2116            GenPolynomial<C> d2 = c.multiply(h);
2117            c = d1.sum(d2);
2118        }
2119        return c;
2120    }
2121
2122
2123    /**
2124     * Polynomial translation, all variables.
2125     * @param <C> coefficient type.
2126     * @param A is a non-zero polynomial in r variables, A(x_1, ..., x(r-1),
2127     *            x_r).
2128     * @param H is a list of coefficient ring elements H = (h1, ..., hr).
2129     * @return B with B(x1, ..., x(r-1), xr) = A(x1+h1, ..., x(r-1)+h(r-1),
2130     *         xr+hr).
2131     * @see "maspoly.SACIPOL.mi#IPTRAN from SAC2/MAS"
2132     */
2133    public static <C extends RingElem<C>> GenPolynomial<C> translation(GenPolynomial<C> A, List<C> H) {
2134        if (A == null) {
2135            return null;
2136        }
2137        if (A.isZERO()) {
2138            return A;
2139        }
2140        GenPolynomialRing<C> pfac = A.ring;
2141        if (pfac.nvar <= 1) {
2142            return translationBase(A, H.get(0));
2143        }
2144        if (H == null || pfac.nvar != H.size()) {
2145            throw new IllegalArgumentException(
2146                            "number of translation points do not match number of variables " + pfac.nvar
2147                                            + " != " + H.size());
2148        }
2149        C h = H.get(0);
2150        List<C> L = H.subList(1, H.size());
2151        GenPolynomialRing<GenPolynomial<C>> rfac = pfac.recursive(1);
2152        GenPolynomial<GenPolynomial<C>> Ar = recursive(rfac, A);
2153        GenPolynomial<GenPolynomial<C>> Br = translationMainRecursive(Ar, h);
2154        GenPolynomial<GenPolynomial<C>> Cr = rfac.getZERO().copy();
2155        Map<ExpVector, GenPolynomial<C>> val = Br.val;
2156        Map<ExpVector, GenPolynomial<C>> cval = Cr.val;
2157        for (Map.Entry<ExpVector, GenPolynomial<C>> me : val.entrySet()) {
2158            ExpVector e = me.getKey();
2159            GenPolynomial<C> b = me.getValue();
2160            GenPolynomial<C> c = translation(b, L);
2161            cval.put(e, c);
2162        }
2163        GenPolynomial<C> B = distribute(pfac, Cr);
2164        return B;
2165    }
2166
2167
2168    /**
2169     * Polynomial translation, r-1 variables.
2170     * @param <C> coefficient type.
2171     * @param A is a non-zero polynomial in r variables, A(x_1, ..., x(r-1),
2172     *            x_r).
2173     * @param H is a list of coefficient ring elements H = (h2, ..., hr).
2174     * @return B with B(x1, ..., x(r-1), xr) = A(x1, x2+h2, ..., x(r-1)+h(r-1),
2175     *         xr+hr).
2176     * @see "maspoly.SACIPOL.mi#IPTRAN from SAC2/MAS"
2177     */
2178    public static <C extends RingElem<C>> GenPolynomial<C> translation1(GenPolynomial<C> A, List<C> H) {
2179        if (A == null) {
2180            return null;
2181        }
2182        if (A.isZERO()) {
2183            return A;
2184        }
2185        GenPolynomialRing<C> pfac = A.ring;
2186        if (pfac.nvar <= 1) {
2187            return A; //translationBase(A, H.get(0));
2188        }
2189        if (H == null || pfac.nvar - 1 != H.size()) {
2190            throw new IllegalArgumentException(
2191                            "number of translation points do not match number of variables " + (pfac.nvar - 1)
2192                                            + " != " + H.size());
2193        }
2194        C h = H.get(0);
2195        List<C> L = H.subList(1, H.size());
2196        GenPolynomialRing<GenPolynomial<C>> rfac = pfac.recursive(1);
2197        GenPolynomial<GenPolynomial<C>> Ar = recursive(rfac, A);
2198        GenPolynomial<GenPolynomial<C>> Br = translationMainRecursive(Ar, h);
2199        GenPolynomial<GenPolynomial<C>> Cr = rfac.getZERO().copy();
2200        Map<ExpVector, GenPolynomial<C>> val = Br.val;
2201        Map<ExpVector, GenPolynomial<C>> cval = Cr.val;
2202        for (Map.Entry<ExpVector, GenPolynomial<C>> me : val.entrySet()) {
2203            ExpVector e = me.getKey();
2204            GenPolynomial<C> b = me.getValue();
2205            GenPolynomial<C> c = translation1(b, L);
2206            cval.put(e, c);
2207        }
2208        GenPolynomial<C> B = distribute(pfac, Cr);
2209        return B;
2210    }
2211
2212
2213    /**
2214     * Evaluate at main variable.
2215     * @param <C> coefficient type.
2216     * @param cfac coefficient polynomial ring factory.
2217     * @param A recursive polynomial to be evaluated.
2218     * @param a value to evaluate at.
2219     * @return A( x_1, ..., x_{n-1}, a ).
2220     */
2221    public static <C extends RingElem<C>> GenPolynomial<C> evaluateMainRecursive(GenPolynomialRing<C> cfac,
2222                    GenPolynomial<GenPolynomial<C>> A, C a) {
2223        if (A == null || A.isZERO()) {
2224            return cfac.getZERO();
2225        }
2226        if (A.ring.nvar != 1) {
2227            throw new IllegalArgumentException("evaluateMain no univariate polynomial");
2228        }
2229        if (a == null || a.isZERO()) {
2230            return A.trailingBaseCoefficient();
2231        }
2232        // assert descending exponents, i.e. compatible term order
2233        Map<ExpVector, GenPolynomial<C>> val = A.getMap();
2234        GenPolynomial<C> B = null;
2235        long el1 = -1; // undefined
2236        long el2 = -1;
2237        for (Map.Entry<ExpVector, GenPolynomial<C>> me : val.entrySet()) {
2238            ExpVector e = me.getKey();
2239            el2 = e.getVal(0);
2240            if (B == null /*el1 < 0*/) { // first turn
2241                B = me.getValue();
2242            } else {
2243                for (long i = el2; i < el1; i++) {
2244                    B = B.multiply(a);
2245                }
2246                B = B.sum(me.getValue());
2247            }
2248            el1 = el2;
2249        }
2250        for (long i = 0; i < el2; i++) {
2251            B = B.multiply(a);
2252        }
2253        return B;
2254    }
2255
2256
2257    /**
2258     * Evaluate at main variable.
2259     * @param <C> coefficient type.
2260     * @param cfac coefficient polynomial ring factory.
2261     * @param A distributed polynomial to be evaluated.
2262     * @param a value to evaluate at.
2263     * @return A( x_1, ..., x_{n-1}, a ).
2264     */
2265    public static <C extends RingElem<C>> GenPolynomial<C> evaluateMain(GenPolynomialRing<C> cfac,
2266                    GenPolynomial<C> A, C a) {
2267        if (A == null || A.isZERO()) {
2268            return cfac.getZERO();
2269        }
2270        GenPolynomialRing<GenPolynomial<C>> rfac = A.ring.recursive(1);
2271        if (rfac.nvar + cfac.nvar != A.ring.nvar) {
2272            throw new IllegalArgumentException("evaluateMain number of variables mismatch");
2273        }
2274        GenPolynomial<GenPolynomial<C>> Ap = recursive(rfac, A);
2275        return PolyUtil.<C> evaluateMainRecursive(cfac, Ap, a);
2276    }
2277
2278
2279    /**
2280     * Evaluate at main variable.
2281     * @param <C> coefficient type.
2282     * @param cfac coefficient ring factory.
2283     * @param L list of univariate polynomials to be evaluated.
2284     * @param a value to evaluate at.
2285     * @return list( A( x_1, ..., x_{n-1}, a ) ) for A in L.
2286     */
2287    public static <C extends RingElem<C>> List<GenPolynomial<C>> evaluateMain(GenPolynomialRing<C> cfac,
2288                    List<GenPolynomial<C>> L, C a) {
2289        return ListUtil.<GenPolynomial<C>, GenPolynomial<C>> map(L, new EvalMainPol<C>(cfac, a));
2290    }
2291
2292
2293    /**
2294     * Evaluate at main variable.
2295     * @param <C> coefficient type.
2296     * @param cfac coefficient ring factory.
2297     * @param A univariate polynomial to be evaluated.
2298     * @param a value to evaluate at.
2299     * @return A( a ).
2300     */
2301    public static <C extends RingElem<C>> C evaluateMain(RingFactory<C> cfac, GenPolynomial<C> A, C a) {
2302        if (A == null || A.isZERO()) {
2303            return cfac.getZERO();
2304        }
2305        if (A.ring.nvar != 1) {
2306            throw new IllegalArgumentException("evaluateMain no univariate polynomial");
2307        }
2308        if (a == null || a.isZERO()) {
2309            return A.trailingBaseCoefficient();
2310        }
2311        // assert decreasing exponents, i.e. compatible term order
2312        Map<ExpVector, C> val = A.getMap();
2313        C B = null;
2314        long el1 = -1; // undefined
2315        long el2 = -1;
2316        for (Map.Entry<ExpVector, C> me : val.entrySet()) {
2317            ExpVector e = me.getKey();
2318            el2 = e.getVal(0);
2319            if (B == null /*el1 < 0*/) { // first turn
2320                B = me.getValue();
2321            } else {
2322                for (long i = el2; i < el1; i++) {
2323                    B = B.multiply(a);
2324                }
2325                B = B.sum(me.getValue());
2326            }
2327            el1 = el2;
2328        }
2329        for (long i = 0; i < el2; i++) {
2330            B = B.multiply(a);
2331        }
2332        return B;
2333    }
2334
2335
2336    /**
2337     * Evaluate at main variable.
2338     * @param <C> coefficient type.
2339     * @param cfac coefficient ring factory.
2340     * @param L list of univariate polynomial to be evaluated.
2341     * @param a value to evaluate at.
2342     * @return list( A( a ) ) for A in L.
2343     */
2344    public static <C extends RingElem<C>> List<C> evaluateMain(RingFactory<C> cfac, List<GenPolynomial<C>> L,
2345                    C a) {
2346        return ListUtil.<GenPolynomial<C>, C> map(L, new EvalMain<C>(cfac, a));
2347    }
2348
2349
2350    /**
2351     * Evaluate at k-th variable.
2352     * @param <C> coefficient type.
2353     * @param cfac coefficient polynomial ring in k variables C[x_1, ..., x_k]
2354     *            factory.
2355     * @param rfac coefficient polynomial ring C[x_1, ..., x_{k-1}] [x_k]
2356     *            factory, a recursive polynomial ring in 1 variable with
2357     *            coefficients in k-1 variables.
2358     * @param nfac polynomial ring in n-1 variables C[x_1, ..., x_{k-1}]
2359     *            [x_{k+1}, ..., x_n] factory, a recursive polynomial ring in
2360     *            n-k+1 variables with coefficients in k-1 variables.
2361     * @param dfac polynomial ring in n-1 variables. C[x_1, ..., x_{k-1},
2362     *            x_{k+1}, ..., x_n] factory.
2363     * @param A polynomial to be evaluated.
2364     * @param a value to evaluate at.
2365     * @return A( x_1, ..., x_{k-1}, a, x_{k+1}, ..., x_n).
2366     */
2367    public static <C extends RingElem<C>> GenPolynomial<C> evaluate(GenPolynomialRing<C> cfac,
2368                    GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomialRing<GenPolynomial<C>> nfac,
2369                    GenPolynomialRing<C> dfac, GenPolynomial<C> A, C a) {
2370        if (rfac.nvar != 1) {
2371            throw new IllegalArgumentException("evaluate coefficient ring not univariate");
2372        }
2373        if (A == null || A.isZERO()) {
2374            return cfac.getZERO();
2375        }
2376        Map<ExpVector, GenPolynomial<C>> Ap = A.contract(cfac);
2377        GenPolynomialRing<C> rcf = (GenPolynomialRing<C>) rfac.coFac;
2378        GenPolynomial<GenPolynomial<C>> Ev = nfac.getZERO().copy();
2379        Map<ExpVector, GenPolynomial<C>> Evm = Ev.val; //getMap();
2380        for (Map.Entry<ExpVector, GenPolynomial<C>> m : Ap.entrySet()) {
2381            ExpVector e = m.getKey();
2382            GenPolynomial<C> b = m.getValue();
2383            GenPolynomial<GenPolynomial<C>> c = recursive(rfac, b);
2384            GenPolynomial<C> d = evaluateMainRecursive(rcf, c, a);
2385            if (d != null && !d.isZERO()) {
2386                Evm.put(e, d);
2387            }
2388        }
2389        GenPolynomial<C> B = distribute(dfac, Ev);
2390        return B;
2391    }
2392
2393
2394    /**
2395     * Evaluate at first (lowest) variable.
2396     * @param <C> coefficient type.
2397     * @param cfac coefficient polynomial ring in first variable C[x_1] factory.
2398     * @param dfac polynomial ring in n-1 variables. C[x_2, ..., x_n] factory.
2399     * @param A polynomial to be evaluated.
2400     * @param a value to evaluate at.
2401     * @return A( a, x_2, ..., x_n).
2402     */
2403    public static <C extends RingElem<C>> GenPolynomial<C> evaluateFirst(GenPolynomialRing<C> cfac,
2404                    GenPolynomialRing<C> dfac, GenPolynomial<C> A, C a) {
2405        if (A == null || A.isZERO()) {
2406            return dfac.getZERO();
2407        }
2408        Map<ExpVector, GenPolynomial<C>> Ap = A.contract(cfac);
2409        //RingFactory<C> rcf = cfac.coFac; // == dfac.coFac
2410
2411        GenPolynomial<C> B = dfac.getZERO().copy();
2412        Map<ExpVector, C> Bm = B.val; //getMap();
2413
2414        for (Map.Entry<ExpVector, GenPolynomial<C>> m : Ap.entrySet()) {
2415            ExpVector e = m.getKey();
2416            GenPolynomial<C> b = m.getValue();
2417            C d = evaluateMain(cfac.coFac, b, a);
2418            if (d != null && !d.isZERO()) {
2419                Bm.put(e, d);
2420            }
2421        }
2422        return B;
2423    }
2424
2425
2426    /**
2427     * Evaluate at first (lowest) variable. Could also be called
2428     * <code>evaluateFirst()</code>, but type erasure of parameter
2429     * <code>A</code> does not allow the same name.
2430     * @param <C> coefficient type.
2431     * @param cfac coefficient polynomial ring in first variable C[x_1] factory.
2432     * @param dfac polynomial ring in n-1 variables. C[x_2, ..., x_n] factory.
2433     * @param A recursive polynomial to be evaluated.
2434     * @param a value to evaluate at.
2435     * @return A( a, x_2, ..., x_n).
2436     */
2437    public static <C extends RingElem<C>> GenPolynomial<C> evaluateFirstRec(GenPolynomialRing<C> cfac,
2438                    GenPolynomialRing<C> dfac, GenPolynomial<GenPolynomial<C>> A, C a) {
2439        if (A == null || A.isZERO()) {
2440            return dfac.getZERO();
2441        }
2442        Map<ExpVector, GenPolynomial<C>> Ap = A.getMap();
2443        GenPolynomial<C> B = dfac.getZERO().copy();
2444        Map<ExpVector, C> Bm = B.val; //getMap();
2445        for (Map.Entry<ExpVector, GenPolynomial<C>> m : Ap.entrySet()) {
2446            ExpVector e = m.getKey();
2447            GenPolynomial<C> b = m.getValue();
2448            C d = evaluateMain(cfac.coFac, b, a);
2449            if (d != null && !d.isZERO()) {
2450                Bm.put(e, d);
2451            }
2452        }
2453        return B;
2454    }
2455
2456
2457    /**
2458     * Evaluate all variables.
2459     * @param <C> coefficient type.
2460     * @param cfac coefficient ring factory.
2461     * @param L list of polynomials to be evaluated.
2462     * @param a = (a_1, a_2, ..., a_n) a tuple of values to evaluate at.
2463     * @return L = ( A_1(a_1, a_2, ..., a_n), ... A_k(a_1, a_2, ..., a_n)).
2464     */
2465    public static <C extends RingElem<C>> List<C> evaluateAll(RingFactory<C> cfac, List<GenPolynomial<C>> L,
2466                    List<C> a) {
2467        return ListUtil.<GenPolynomial<C>, C> map(L, new EvalAllPol<C>(cfac, a));
2468    }
2469
2470
2471    /**
2472     * Evaluate all variables.
2473     * @param <C> coefficient type.
2474     * @param cfac coefficient ring factory.
2475     * @param A polynomial to be evaluated.
2476     * @param a = (a_1, a_2, ..., a_n) a tuple of values to evaluate at.
2477     * @return A(a_1, a_2, ..., a_n).
2478     */
2479    public static <C extends RingElem<C>> C evaluateAll(RingFactory<C> cfac, GenPolynomial<C> A, List<C> a) {
2480        if (A == null || A.isZERO()) {
2481            return cfac.getZERO();
2482        }
2483        GenPolynomialRing<C> dfac = A.ring;
2484        if (a == null || a.size() != dfac.nvar) {
2485            throw new IllegalArgumentException("evaluate tuple size not equal to number of variables");
2486        }
2487        if (dfac.nvar == 0) {
2488            return A.trailingBaseCoefficient();
2489        }
2490        if (dfac.nvar == 1) {
2491            return evaluateMain(cfac, A, a.get(0));
2492        }
2493        C b = cfac.getZERO();
2494        GenPolynomial<C> Ap = A;
2495        for (int k = 0; k < dfac.nvar - 1; k++) {
2496            C ap = a.get(k);
2497            GenPolynomialRing<C> c1fac = new GenPolynomialRing<C>(cfac, 1); // no vars
2498            GenPolynomialRing<C> cnfac = new GenPolynomialRing<C>(cfac, dfac.nvar - 1 - k); // no vars
2499            GenPolynomial<C> Bp = evaluateFirst(c1fac, cnfac, Ap, ap);
2500            if (Bp.isZERO()) {
2501                return b;
2502            }
2503            Ap = Bp;
2504            //System.out.println("Ap = " + Ap);
2505        }
2506        C ap = a.get(dfac.nvar - 1);
2507        b = evaluateMain(cfac, Ap, ap);
2508        return b;
2509    }
2510
2511
2512    /**
2513     * Substitute main variable.
2514     * @param A univariate polynomial.
2515     * @param s polynomial for substitution.
2516     * @return polynomial A(x &lt;- s).
2517     */
2518    public static <C extends RingElem<C>> GenPolynomial<C> substituteMain(GenPolynomial<C> A,
2519                    GenPolynomial<C> s) {
2520        return substituteUnivariate(A, s);
2521    }
2522
2523
2524    /**
2525     * Substitute univariate polynomial.
2526     * @param f univariate polynomial.
2527     * @param t polynomial for substitution.
2528     * @return polynomial f(x &lt;- t).
2529     */
2530    public static <C extends RingElem<C>> GenPolynomial<C> substituteUnivariate(GenPolynomial<C> f,
2531                    GenPolynomial<C> t) {
2532        if (f == null || t == null) {
2533            return null;
2534        }
2535        GenPolynomialRing<C> fac = f.ring;
2536        if (fac.nvar > 1) {
2537            throw new IllegalArgumentException("only for univariate polynomial f");
2538        }
2539        if (f.isZERO() || f.isConstant()) {
2540            return f;
2541        }
2542        if (t.ring.nvar > 1) {
2543            fac = t.ring;
2544        }
2545        // assert descending exponents, i.e. compatible term order
2546        Map<ExpVector, C> val = f.getMap();
2547        GenPolynomial<C> s = null;
2548        long el1 = -1; // undefined
2549        long el2 = -1;
2550        for (Map.Entry<ExpVector, C> me : val.entrySet()) {
2551            ExpVector e = me.getKey();
2552            el2 = e.getVal(0);
2553            if (s == null /*el1 < 0*/) { // first turn
2554                s = fac.getZERO().sum(me.getValue());
2555            } else {
2556                for (long i = el2; i < el1; i++) {
2557                    s = s.multiply(t);
2558                }
2559                s = s.sum(me.getValue());
2560            }
2561            el1 = el2;
2562        }
2563        for (long i = 0; i < el2; i++) {
2564            s = s.multiply(t);
2565        }
2566        //System.out.println("s = " + s);
2567        return s;
2568    }
2569
2570
2571    /**
2572     * Substitute univariate polynomial with multivariate coefficients.
2573     * @param f univariate polynomial with multivariate coefficients.
2574     * @param t polynomial for substitution.
2575     * @return polynomial f(x &lt;- t).
2576     */
2577    public static <C extends RingElem<C>> GenPolynomial<C> substituteUnivariateMult(GenPolynomial<C> f,
2578                    GenPolynomial<C> t) {
2579        if (f == null || t == null) {
2580            return null;
2581        }
2582        GenPolynomialRing<C> fac = f.ring;
2583        if (fac.nvar == 1) {
2584            return substituteUnivariate(f, t);
2585        }
2586        GenPolynomialRing<GenPolynomial<C>> rfac = fac.recursive(1);
2587        GenPolynomial<GenPolynomial<C>> fr = PolyUtil.<C> recursive(rfac, f);
2588        GenPolynomial<GenPolynomial<C>> tr = PolyUtil.<C> recursive(rfac, t);
2589        //System.out.println("fr = " + fr);
2590        //System.out.println("tr = " + tr);
2591        GenPolynomial<GenPolynomial<C>> sr = PolyUtil.<GenPolynomial<C>> substituteUnivariate(fr, tr);
2592        //System.out.println("sr = " + sr);
2593        GenPolynomial<C> s = PolyUtil.<C> distribute(fac, sr);
2594        return s;
2595    }
2596
2597
2598    /**
2599     * Taylor series for polynomial.
2600     * @param f univariate polynomial.
2601     * @param a expansion point.
2602     * @return Taylor series (a polynomial) of f at a.
2603     */
2604    public static <C extends RingElem<C>> GenPolynomial<C> seriesOfTaylor(GenPolynomial<C> f, C a) {
2605        if (f == null) {
2606            return null;
2607        }
2608        GenPolynomialRing<C> fac = f.ring;
2609        if (fac.nvar > 1) {
2610            throw new IllegalArgumentException("only for univariate polynomials");
2611        }
2612        if (f.isZERO() || f.isConstant()) {
2613            return f;
2614        }
2615        GenPolynomial<C> s = fac.getZERO();
2616        C fa = PolyUtil.<C> evaluateMain(fac.coFac, f, a);
2617        s = s.sum(fa);
2618        long n = 1;
2619        long i = 0;
2620        GenPolynomial<C> g = PolyUtil.<C> baseDerivative(f);
2621        //GenPolynomial<C> p = fac.getONE();
2622        while (!g.isZERO()) {
2623            i++;
2624            n *= i;
2625            fa = PolyUtil.<C> evaluateMain(fac.coFac, g, a);
2626            GenPolynomial<C> q = fac.univariate(0, i); //p;
2627            q = q.multiply(fa);
2628            q = q.divide(fac.fromInteger(n));
2629            s = s.sum(q);
2630            g = PolyUtil.<C> baseDerivative(g);
2631        }
2632        //System.out.println("s = " + s);
2633        return s;
2634    }
2635
2636
2637    /**
2638     * ModInteger interpolate on first variable.
2639     * @param <C> coefficient type.
2640     * @param fac GenPolynomial<C> result factory.
2641     * @param A GenPolynomial.
2642     * @param M GenPolynomial interpolation modul of A.
2643     * @param mi inverse of M(am) in ring fac.coFac.
2644     * @param B evaluation of other GenPolynomial.
2645     * @param am evaluation point (interpolation modul) of B, i.e. P(am) = B.
2646     * @return S, with S mod M == A and S(am) == B.
2647     */
2648    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> interpolate(
2649                    GenPolynomialRing<GenPolynomial<C>> fac, GenPolynomial<GenPolynomial<C>> A,
2650                    GenPolynomial<C> M, C mi, GenPolynomial<C> B, C am) {
2651        GenPolynomial<GenPolynomial<C>> S = fac.getZERO().copy();
2652        GenPolynomial<GenPolynomial<C>> Ap = A.copy();
2653        SortedMap<ExpVector, GenPolynomial<C>> av = Ap.val; //getMap();
2654        SortedMap<ExpVector, C> bv = B.getMap();
2655        SortedMap<ExpVector, GenPolynomial<C>> sv = S.val; //getMap();
2656        GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) fac.coFac;
2657        RingFactory<C> bfac = cfac.coFac;
2658        GenPolynomial<C> c = null;
2659        for (Map.Entry<ExpVector, C> me : bv.entrySet()) {
2660            ExpVector e = me.getKey();
2661            C y = me.getValue(); //bv.get(e); // assert y != null
2662            GenPolynomial<C> x = av.get(e);
2663            if (x != null) {
2664                av.remove(e);
2665                c = PolyUtil.<C> interpolate(cfac, x, M, mi, y, am);
2666                if (!c.isZERO()) { // 0 cannot happen
2667                    sv.put(e, c);
2668                }
2669            } else {
2670                c = PolyUtil.<C> interpolate(cfac, cfac.getZERO(), M, mi, y, am);
2671                if (!c.isZERO()) { // 0 cannot happen
2672                    sv.put(e, c); // c != null
2673                }
2674            }
2675        }
2676        // assert bv is empty = done
2677        for (Map.Entry<ExpVector, GenPolynomial<C>> me : av.entrySet()) { // rest of av
2678            ExpVector e = me.getKey();
2679            GenPolynomial<C> x = me.getValue(); //av.get(e); // assert x != null
2680            c = PolyUtil.<C> interpolate(cfac, x, M, mi, bfac.getZERO(), am);
2681            if (!c.isZERO()) { // 0 cannot happen
2682                sv.put(e, c); // c != null
2683            }
2684        }
2685        return S;
2686    }
2687
2688
2689    /**
2690     * Univariate polynomial interpolation.
2691     * @param <C> coefficient type.
2692     * @param fac GenPolynomial<C> result factory.
2693     * @param A GenPolynomial.
2694     * @param M GenPolynomial interpolation modul of A.
2695     * @param mi inverse of M(am) in ring fac.coFac.
2696     * @param a evaluation of other GenPolynomial.
2697     * @param am evaluation point (interpolation modul) of a, i.e. P(am) = a.
2698     * @return S, with S mod M == A and S(am) == a.
2699     */
2700    public static <C extends RingElem<C>> GenPolynomial<C> interpolate(GenPolynomialRing<C> fac,
2701                    GenPolynomial<C> A, GenPolynomial<C> M, C mi, C a, C am) {
2702        GenPolynomial<C> s;
2703        C b = PolyUtil.<C> evaluateMain(fac.coFac, A, am);
2704        // A mod a.modul
2705        C d = a.subtract(b); // a-A mod a.modul
2706        if (d.isZERO()) {
2707            return A;
2708        }
2709        b = d.multiply(mi); // b = (a-A)*mi mod a.modul
2710        // (M*b)+A mod M = A mod M = 
2711        // (M*mi*(a-A)+A) mod a.modul = a mod a.modul
2712        s = M.multiply(b);
2713        s = s.sum(A);
2714        return s;
2715    }
2716
2717
2718    /**
2719     * Recursive GenPolynomial switch variable blocks.
2720     * @param <C> coefficient type.
2721     * @param P recursive GenPolynomial in R[X,Y].
2722     * @return this in R[Y,X].
2723     */
2724    public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> switchVariables(
2725                    GenPolynomial<GenPolynomial<C>> P) {
2726        if (P == null) {
2727            throw new IllegalArgumentException("P == null");
2728        }
2729        GenPolynomialRing<GenPolynomial<C>> rfac1 = P.ring;
2730        GenPolynomialRing<C> cfac1 = (GenPolynomialRing<C>) rfac1.coFac;
2731        GenPolynomialRing<C> cfac2 = new GenPolynomialRing<C>(cfac1.coFac, rfac1);
2732        GenPolynomial<C> zero = cfac2.getZERO();
2733        GenPolynomialRing<GenPolynomial<C>> rfac2 = new GenPolynomialRing<GenPolynomial<C>>(cfac2, cfac1);
2734        GenPolynomial<GenPolynomial<C>> B = rfac2.getZERO().copy();
2735        if (P.isZERO()) {
2736            return B;
2737        }
2738        for (Monomial<GenPolynomial<C>> mr : P) {
2739            GenPolynomial<C> cr = mr.c;
2740            for (Monomial<C> mc : cr) {
2741                GenPolynomial<C> c = zero.sum(mc.c, mr.e);
2742                B = B.sum(c, mc.e);
2743            }
2744        }
2745        return B;
2746    }
2747
2748
2749    /**
2750     * Maximal degree of leading terms of a polynomial list.
2751     * @return maximum degree of the leading terms of a polynomial list.
2752     */
2753    public static <C extends RingElem<C>> long totalDegreeLeadingTerm(List<GenPolynomial<C>> P) {
2754        long degree = 0;
2755        for (GenPolynomial<C> g : P) {
2756            long total = g.leadingExpVector().totalDeg();
2757            if (degree < total) {
2758                degree = total;
2759            }
2760        }
2761        return degree;
2762    }
2763
2764
2765    /**
2766     * Total degree of polynomial list.
2767     * @return total degree of the polynomial list.
2768     */
2769    public static <C extends RingElem<C>> long totalDegree(List<GenPolynomial<C>> P) {
2770        long degree = 0;
2771        for (GenPolynomial<C> g : P) {
2772            long total = g.totalDegree();
2773            if (degree < total) {
2774                degree = total;
2775            }
2776        }
2777        return degree;
2778    }
2779
2780
2781    /**
2782     * Maximal degree of polynomial list.
2783     * @return maximal degree of the polynomial list.
2784     */
2785    public static <C extends RingElem<C>> long maxDegree(List<GenPolynomial<C>> P) {
2786        long degree = 0;
2787        for (GenPolynomial<C> g : P) {
2788            long total = g.degree();
2789            if (degree < total) {
2790                degree = total;
2791            }
2792        }
2793        return degree;
2794    }
2795
2796
2797    /**
2798     * Maximal degree in the coefficient polynomials.
2799     * @param <C> coefficient type.
2800     * @return maximal degree in the coefficients.
2801     */
2802    public static <C extends RingElem<C>> long coeffMaxDegree(GenPolynomial<GenPolynomial<C>> A) {
2803        if (A.isZERO()) {
2804            return 0; // 0 or -1 ?;
2805        }
2806        long deg = 0;
2807        for (GenPolynomial<C> a : A.getMap().values()) {
2808            long d = a.degree();
2809            if (d > deg) {
2810                deg = d;
2811            }
2812        }
2813        return deg;
2814    }
2815
2816
2817    /**
2818     * Map a unary function to the coefficients.
2819     * @param ring result polynomial ring factory.
2820     * @param p polynomial.
2821     * @param f evaluation functor.
2822     * @return new polynomial with coefficients f(p(e)).
2823     */
2824    public static <C extends RingElem<C>, D extends RingElem<D>> GenPolynomial<D> map(
2825                    GenPolynomialRing<D> ring, GenPolynomial<C> p, UnaryFunctor<C, D> f) {
2826        GenPolynomial<D> n = ring.getZERO().copy();
2827        SortedMap<ExpVector, D> nv = n.val;
2828        for (Monomial<C> m : p) {
2829            D c = f.eval(m.c);
2830            if (c != null && !c.isZERO()) {
2831                nv.put(m.e, c);
2832            }
2833        }
2834        return n;
2835    }
2836
2837
2838    /**
2839     * Product representation.
2840     * @param <C> coefficient type.
2841     * @param pfac polynomial ring factory.
2842     * @param L list of polynomials to be represented.
2843     * @return Product representation of L in the polynomial ring pfac.
2844     */
2845    public static <C extends GcdRingElem<C>> List<GenPolynomial<Product<C>>> toProductGen(
2846                    GenPolynomialRing<Product<C>> pfac, List<GenPolynomial<C>> L) {
2847
2848        List<GenPolynomial<Product<C>>> list = new ArrayList<GenPolynomial<Product<C>>>();
2849        if (L == null || L.size() == 0) {
2850            return list;
2851        }
2852        for (GenPolynomial<C> a : L) {
2853            GenPolynomial<Product<C>> b = toProductGen(pfac, a);
2854            list.add(b);
2855        }
2856        return list;
2857    }
2858
2859
2860    /**
2861     * Product representation.
2862     * @param <C> coefficient type.
2863     * @param pfac polynomial ring factory.
2864     * @param A polynomial to be represented.
2865     * @return Product representation of A in the polynomial ring pfac.
2866     */
2867    public static <C extends GcdRingElem<C>> GenPolynomial<Product<C>> toProductGen(
2868                    GenPolynomialRing<Product<C>> pfac, GenPolynomial<C> A) {
2869
2870        GenPolynomial<Product<C>> P = pfac.getZERO().copy();
2871        if (A == null || A.isZERO()) {
2872            return P;
2873        }
2874        RingFactory<Product<C>> rpfac = pfac.coFac;
2875        ProductRing<C> rfac = (ProductRing<C>) rpfac;
2876        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
2877            ExpVector e = y.getKey();
2878            C a = y.getValue();
2879            Product<C> p = toProductGen(rfac, a);
2880            if (!p.isZERO()) {
2881                P.doPutToMap(e, p);
2882            }
2883        }
2884        return P;
2885    }
2886
2887
2888    /**
2889     * Product representation.
2890     * @param <C> coefficient type.
2891     * @param pfac product ring factory.
2892     * @param c coefficient to be represented.
2893     * @return Product representation of c in the ring pfac.
2894     */
2895    public static <C extends GcdRingElem<C>> Product<C> toProductGen(ProductRing<C> pfac, C c) {
2896
2897        SortedMap<Integer, C> elem = new TreeMap<Integer, C>();
2898        for (int i = 0; i < pfac.length(); i++) {
2899            RingFactory<C> rfac = pfac.getFactory(i);
2900            C u = rfac.copy(c);
2901            if (u != null && !u.isZERO()) {
2902                elem.put(i, u);
2903            }
2904        }
2905        return new Product<C>(pfac, elem);
2906    }
2907
2908
2909    /**
2910     * Product representation.
2911     * @param <C> coefficient type.
2912     * @param pfac product polynomial ring factory.
2913     * @param c coefficient to be used.
2914     * @param e exponent vector.
2915     * @return Product representation of c X^e in the ring pfac.
2916     */
2917    public static <C extends RingElem<C>> Product<GenPolynomial<C>> toProduct(
2918                    ProductRing<GenPolynomial<C>> pfac, C c, ExpVector e) {
2919        SortedMap<Integer, GenPolynomial<C>> elem = new TreeMap<Integer, GenPolynomial<C>>();
2920        for (int i = 0; i < e.length(); i++) {
2921            RingFactory<GenPolynomial<C>> rfac = pfac.getFactory(i);
2922            GenPolynomialRing<C> fac = (GenPolynomialRing<C>) rfac;
2923            //GenPolynomialRing<C> cfac = fac.ring;
2924            long a = e.getVal(i);
2925            GenPolynomial<C> u;
2926            if (a == 0) {
2927                u = fac.getONE();
2928            } else {
2929                u = fac.univariate(0, a);
2930            }
2931            u = u.multiply(c);
2932            elem.put(i, u);
2933        }
2934        return new Product<GenPolynomial<C>>(pfac, elem);
2935    }
2936
2937
2938    /**
2939     * Product representation.
2940     * @param <C> coefficient type.
2941     * @param pfac product polynomial ring factory.
2942     * @param A polynomial.
2943     * @return Product representation of the terms of A in the ring pfac.
2944     */
2945    public static <C extends RingElem<C>> Product<GenPolynomial<C>> toProduct(
2946                    ProductRing<GenPolynomial<C>> pfac, GenPolynomial<C> A) {
2947        Product<GenPolynomial<C>> P = pfac.getZERO();
2948        if (A == null || A.isZERO()) {
2949            return P;
2950        }
2951        for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
2952            ExpVector e = y.getKey();
2953            C a = y.getValue();
2954            Product<GenPolynomial<C>> p = toProduct(pfac, a, e);
2955            P = P.sum(p);
2956        }
2957        return P;
2958    }
2959
2960
2961    /**
2962     * Product representation.
2963     * @param pfac product ring factory.
2964     * @param c coefficient to be represented.
2965     * @return Product representation of c in the ring pfac.
2966     */
2967    public static Product<ModInteger> toProduct(ProductRing<ModInteger> pfac, BigInteger c) {
2968
2969        SortedMap<Integer, ModInteger> elem = new TreeMap<Integer, ModInteger>();
2970        for (int i = 0; i < pfac.length(); i++) {
2971            RingFactory<ModInteger> rfac = pfac.getFactory(i);
2972            ModIntegerRing fac = (ModIntegerRing) rfac;
2973            ModInteger u = fac.fromInteger(c.getVal());
2974            if (!u.isZERO()) {
2975                elem.put(i, u);
2976            }
2977        }
2978        return new Product<ModInteger>(pfac, elem);
2979    }
2980
2981
2982    /**
2983     * Product representation.
2984     * @param pfac polynomial ring factory.
2985     * @param A polynomial to be represented.
2986     * @return Product representation of A in the polynomial ring pfac.
2987     */
2988    public static GenPolynomial<Product<ModInteger>> toProduct(GenPolynomialRing<Product<ModInteger>> pfac,
2989                    GenPolynomial<BigInteger> A) {
2990
2991        GenPolynomial<Product<ModInteger>> P = pfac.getZERO().copy();
2992        if (A == null || A.isZERO()) {
2993            return P;
2994        }
2995        RingFactory<Product<ModInteger>> rpfac = pfac.coFac;
2996        ProductRing<ModInteger> fac = (ProductRing<ModInteger>) rpfac;
2997        for (Map.Entry<ExpVector, BigInteger> y : A.getMap().entrySet()) {
2998            ExpVector e = y.getKey();
2999            BigInteger a = y.getValue();
3000            Product<ModInteger> p = toProduct(fac, a);
3001            if (!p.isZERO()) {
3002                P.doPutToMap(e, p);
3003            }
3004        }
3005        return P;
3006    }
3007
3008
3009    /**
3010     * Product representation.
3011     * @param pfac polynomial ring factory.
3012     * @param L list of polynomials to be represented.
3013     * @return Product representation of L in the polynomial ring pfac.
3014     */
3015    public static List<GenPolynomial<Product<ModInteger>>> toProduct(
3016                    GenPolynomialRing<Product<ModInteger>> pfac, List<GenPolynomial<BigInteger>> L) {
3017
3018        List<GenPolynomial<Product<ModInteger>>> list = new ArrayList<GenPolynomial<Product<ModInteger>>>();
3019        if (L == null || L.size() == 0) {
3020            return list;
3021        }
3022        for (GenPolynomial<BigInteger> a : L) {
3023            GenPolynomial<Product<ModInteger>> b = toProduct(pfac, a);
3024            list.add(b);
3025        }
3026        return list;
3027    }
3028
3029
3030    /**
3031     * Intersection. Intersection of a list of polynomials with a polynomial
3032     * ring. The polynomial ring must be a contraction of the polynomial ring of
3033     * the list of polynomials and the TermOrder must be an elimination order.
3034     * @param R polynomial ring
3035     * @param F list of polynomials
3036     * @return R \cap F
3037     */
3038    public static <C extends RingElem<C>> List<GenPolynomial<C>> intersect(GenPolynomialRing<C> R,
3039                    List<GenPolynomial<C>> F) {
3040        if (F == null || F.isEmpty()) {
3041            return F;
3042        }
3043        GenPolynomialRing<C> pfac = F.get(0).ring;
3044        int d = pfac.nvar - R.nvar;
3045        if (d <= 0) {
3046            return F;
3047        }
3048        List<GenPolynomial<C>> H = new ArrayList<GenPolynomial<C>>(F.size());
3049        for (GenPolynomial<C> p : F) {
3050            Map<ExpVector, GenPolynomial<C>> m = null;
3051            m = p.contract(R);
3052            logger.debug("intersect contract m = {}", m);
3053            if (m.size() == 1) { // contains one power of variables
3054                for (Map.Entry<ExpVector, GenPolynomial<C>> me : m.entrySet()) {
3055                    ExpVector e = me.getKey();
3056                    if (e.isZERO()) {
3057                        H.add(me.getValue());
3058                    }
3059                }
3060            }
3061        }
3062        GenPolynomialRing<C> tfac = pfac.contract(d);
3063        if (tfac.equals(R)) { // check 
3064            return H;
3065        }
3066        logger.warn("tfac != R: tfac = {}, R = {}, pdac = {}", tfac.toScript(), R.toScript(),
3067                        pfac.toScript());
3068        // throw new RuntimeException("contract(pfac) != R");
3069        return H;
3070    }
3071
3072
3073    /**
3074     * Intersection. Intersection of a list of solvable polynomials with a
3075     * solvable polynomial ring. The solvable polynomial ring must be a
3076     * contraction of the solvable polynomial ring of the list of polynomials
3077     * and the TermOrder must be an elimination order.
3078     * @param R solvable polynomial ring
3079     * @param F list of solvable polynomials
3080     * @return R \cap F
3081     */
3082    @SuppressWarnings("cast")
3083    public static <C extends RingElem<C>> List<GenSolvablePolynomial<C>> intersect(
3084                    GenSolvablePolynomialRing<C> R, List<GenSolvablePolynomial<C>> F) {
3085        List<GenPolynomial<C>> Fp = PolynomialList.<C> castToList(F);
3086        GenPolynomialRing<C> Rp = (GenPolynomialRing<C>) R;
3087        List<GenPolynomial<C>> H = intersect(Rp, Fp);
3088        return PolynomialList.<C> castToSolvableList(H);
3089    }
3090
3091
3092    /**
3093     * Intersection. Intersection of a list of word polynomials with a word
3094     * polynomial ring. The polynomial ring must be a contraction of the
3095     * polynomial ring of the list of polynomials,
3096     * @param R word polynomial ring
3097     * @param F list of word polynomials
3098     * @return R \cap F
3099     */
3100    public static <C extends RingElem<C>> List<GenWordPolynomial<C>> intersect(GenWordPolynomialRing<C> R,
3101                    List<GenWordPolynomial<C>> F) {
3102        if (F == null || F.isEmpty()) {
3103            return F;
3104        }
3105        GenWordPolynomialRing<C> pfac = F.get(0).ring;
3106        assert pfac.alphabet.isSubFactory(R.alphabet) : "pfac=" + pfac.alphabet + ", R=" + R.alphabet;
3107        List<GenWordPolynomial<C>> H = new ArrayList<GenWordPolynomial<C>>(F.size());
3108        for (GenWordPolynomial<C> p : F) {
3109            if (p == null || p.isZERO()) {
3110                continue;
3111            }
3112            GenWordPolynomial<C> m = p.contract(R);
3113            logger.debug("intersect contract m = {}", m);
3114            if (!m.isZERO()) {
3115                H.add(m);
3116            }
3117        }
3118        // throw new RuntimeException("contract(pfac) != R");
3119        return H;
3120    }
3121
3122
3123    /**
3124     * Remove all upper variables which do not occur in polynomial.
3125     * @param p polynomial.
3126     * @return polynomial with removed variables
3127     */
3128    public static <C extends RingElem<C>> GenPolynomial<C> removeUnusedUpperVariables(GenPolynomial<C> p) {
3129        GenPolynomialRing<C> fac = p.ring;
3130        if (fac.nvar <= 1) { // univariate
3131            return p;
3132        }
3133        int[] dep = p.degreeVector().dependencyOnVariables();
3134        if (fac.nvar == dep.length) { // all variables appear
3135            return p;
3136        }
3137        if (dep.length == 0) { // no variables
3138            GenPolynomialRing<C> fac0 = new GenPolynomialRing<C>(fac.coFac, 0);
3139            GenPolynomial<C> p0 = new GenPolynomial<C>(fac0, p.leadingBaseCoefficient());
3140            return p0;
3141        }
3142        int l = dep[0]; // higher variable
3143        int r = dep[dep.length - 1]; // lower variable
3144        if (l == 0 /*|| l == fac.nvar-1*/) { // upper variable appears
3145            return p;
3146        }
3147        int n = l;
3148        GenPolynomialRing<C> facr = fac.contract(n);
3149        Map<ExpVector, GenPolynomial<C>> mpr = p.contract(facr);
3150        if (mpr.size() != 1) {
3151            logger.warn("upper ex, l = {}, r = {}, p = {}, fac = {}", l, r, p, fac.toScript());
3152            throw new RuntimeException("this should not happen " + mpr);
3153        }
3154        GenPolynomial<C> pr = mpr.values().iterator().next();
3155        n = fac.nvar - 1 - r;
3156        if (n == 0) {
3157            return pr;
3158        } // else case not implemented
3159        return pr;
3160    }
3161
3162
3163    /**
3164     * Remove all lower variables which do not occur in polynomial.
3165     * @param p polynomial.
3166     * @return polynomial with removed variables
3167     */
3168    public static <C extends RingElem<C>> GenPolynomial<C> removeUnusedLowerVariables(GenPolynomial<C> p) {
3169        GenPolynomialRing<C> fac = p.ring;
3170        if (fac.nvar <= 1) { // univariate
3171            return p;
3172        }
3173        int[] dep = p.degreeVector().dependencyOnVariables();
3174        if (fac.nvar == dep.length) { // all variables appear
3175            return p;
3176        }
3177        if (dep.length == 0) { // no variables
3178            GenPolynomialRing<C> fac0 = new GenPolynomialRing<C>(fac.coFac, 0);
3179            GenPolynomial<C> p0 = new GenPolynomial<C>(fac0, p.leadingBaseCoefficient());
3180            return p0;
3181        }
3182        int l = dep[0]; // higher variable
3183        int r = dep[dep.length - 1]; // lower variable
3184        if (r == fac.nvar - 1) { // lower variable appears
3185            return p;
3186        }
3187        int n = r + 1;
3188        GenPolynomialRing<GenPolynomial<C>> rfac = fac.recursive(n);
3189        GenPolynomial<GenPolynomial<C>> mpr = recursive(rfac, p);
3190        if (mpr.length() != p.length()) {
3191            logger.warn("lower ex, l = {}, r = {}, p = {}, fac = {}", l, r, p, fac.toScript());
3192            throw new RuntimeException("this should not happen " + mpr);
3193        }
3194        RingFactory<C> cf = fac.coFac;
3195        GenPolynomialRing<C> facl = new GenPolynomialRing<C>(cf, rfac);
3196        GenPolynomial<C> pr = facl.getZERO().copy();
3197        for (Monomial<GenPolynomial<C>> m : mpr) {
3198            ExpVector e = m.e;
3199            GenPolynomial<C> a = m.c;
3200            if (!a.isConstant()) {
3201                throw new RuntimeException("this can not happen " + a);
3202            }
3203            C c = a.leadingBaseCoefficient();
3204            pr.doPutToMap(e, c);
3205        }
3206        return pr;
3207    }
3208
3209
3210    /**
3211     * Remove upper block of middle variables which do not occur in polynomial.
3212     * @param p polynomial.
3213     * @return polynomial with removed variables
3214     */
3215    public static <C extends RingElem<C>> GenPolynomial<C> removeUnusedMiddleVariables(GenPolynomial<C> p) {
3216        GenPolynomialRing<C> fac = p.ring;
3217        if (fac.nvar <= 2) { // univariate or bi-variate
3218            return p;
3219        }
3220        int[] dep = p.degreeVector().dependencyOnVariables();
3221        if (fac.nvar == dep.length) { // all variables appear
3222            return p;
3223        }
3224        if (dep.length == 0) { // no variables
3225            GenPolynomialRing<C> fac0 = new GenPolynomialRing<C>(fac.coFac, 0);
3226            GenPolynomial<C> p0 = new GenPolynomial<C>(fac0, p.leadingBaseCoefficient());
3227            return p0;
3228        }
3229        ExpVector e1 = p.leadingExpVector();
3230        if (dep.length == 1) { // one variable
3231            TermOrder to = new TermOrder(fac.tord.getEvord());
3232            int i = dep[0];
3233            String v1 = e1.indexVarName(i, fac.getVars());
3234            String[] vars = new String[] { v1 };
3235            GenPolynomialRing<C> fac1 = new GenPolynomialRing<C>(fac.coFac, to, vars);
3236            GenPolynomial<C> p1 = fac1.getZERO().copy();
3237            for (Monomial<C> m : p) {
3238                ExpVector e = m.e;
3239                ExpVector f = ExpVector.create(1, 0, e.getVal(i));
3240                p1.doPutToMap(f, m.c);
3241            }
3242            return p1;
3243        }
3244        GenPolynomialRing<GenPolynomial<C>> rfac = fac.recursive(1);
3245        GenPolynomial<GenPolynomial<C>> mpr = recursive(rfac, p);
3246
3247        int l = dep[0]; // higher variable
3248        int r = fac.nvar - dep[1]; // next variable
3249        //System.out.println("l  = " + l);
3250        //System.out.println("r  = " + r);
3251
3252        TermOrder to = new TermOrder(fac.tord.getEvord());
3253        String[] vs = fac.getVars();
3254        String[] vars = new String[r + 1];
3255        for (int i = 0; i < r; i++) {
3256            vars[i] = vs[i];
3257        }
3258        vars[r] = e1.indexVarName(l, vs);
3259        //System.out.println("fac  = " + fac);
3260        GenPolynomialRing<C> dfac = new GenPolynomialRing<C>(fac.coFac, to, vars);
3261        //System.out.println("dfac = " + dfac);
3262        GenPolynomialRing<GenPolynomial<C>> fac2 = dfac.recursive(1);
3263        GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) fac2.coFac;
3264        GenPolynomial<GenPolynomial<C>> p2r = fac2.getZERO().copy();
3265        for (Monomial<GenPolynomial<C>> m : mpr) {
3266            ExpVector e = m.e;
3267            GenPolynomial<C> a = m.c;
3268            Map<ExpVector, GenPolynomial<C>> cc = a.contract(cfac);
3269            for (Map.Entry<ExpVector, GenPolynomial<C>> me : cc.entrySet()) {
3270                ExpVector f = me.getKey();
3271                if (f.isZERO()) {
3272                    GenPolynomial<C> c = me.getValue(); //cc.get(f);
3273                    p2r.doPutToMap(e, c);
3274                } else {
3275                    throw new RuntimeException("this should not happen " + cc);
3276                }
3277            }
3278        }
3279        GenPolynomial<C> p2 = distribute(dfac, p2r);
3280        return p2;
3281    }
3282
3283
3284    /**
3285     * Select polynomial with univariate leading term in variable i.
3286     * @param i variable index.
3287     * @return polynomial with head term in variable i
3288     */
3289    public static <C extends RingElem<C>> GenPolynomial<C> selectWithVariable(List<GenPolynomial<C>> P,
3290                    int i) {
3291        for (GenPolynomial<C> p : P) {
3292            int[] dep = p.leadingExpVector().dependencyOnVariables();
3293            if (dep.length == 1 && dep[0] == i) {
3294                return p;
3295            }
3296        }
3297        return null; // not found       
3298    }
3299
3300}
3301
3302
3303/**
3304 * Conversion of distributive to recursive representation.
3305 */
3306class DistToRec<C extends RingElem<C>>
3307                implements UnaryFunctor<GenPolynomial<C>, GenPolynomial<GenPolynomial<C>>> {
3308
3309
3310    GenPolynomialRing<GenPolynomial<C>> fac;
3311
3312
3313    public DistToRec(GenPolynomialRing<GenPolynomial<C>> fac) {
3314        this.fac = fac;
3315    }
3316
3317
3318    public GenPolynomial<GenPolynomial<C>> eval(GenPolynomial<C> c) {
3319        if (c == null) {
3320            return fac.getZERO();
3321        }
3322        return PolyUtil.<C> recursive(fac, c);
3323    }
3324}
3325
3326
3327/**
3328 * Conversion of recursive to distributive representation.
3329 */
3330class RecToDist<C extends RingElem<C>>
3331                implements UnaryFunctor<GenPolynomial<GenPolynomial<C>>, GenPolynomial<C>> {
3332
3333
3334    GenPolynomialRing<C> fac;
3335
3336
3337    public RecToDist(GenPolynomialRing<C> fac) {
3338        this.fac = fac;
3339    }
3340
3341
3342    public GenPolynomial<C> eval(GenPolynomial<GenPolynomial<C>> c) {
3343        if (c == null) {
3344            return fac.getZERO();
3345        }
3346        return PolyUtil.<C> distribute(fac, c);
3347    }
3348}
3349
3350
3351/**
3352 * BigRational numerator functor.
3353 */
3354class RatNumer implements UnaryFunctor<BigRational, BigInteger> {
3355
3356
3357    public BigInteger eval(BigRational c) {
3358        if (c == null) {
3359            return new BigInteger();
3360        }
3361        return new BigInteger(c.numerator());
3362    }
3363}
3364
3365
3366/**
3367 * Conversion of symmetric ModInteger to BigInteger functor.
3368 */
3369class ModSymToInt<C extends RingElem<C> & Modular> implements UnaryFunctor<C, BigInteger> {
3370
3371
3372    public BigInteger eval(C c) {
3373        if (c == null) {
3374            return new BigInteger();
3375        }
3376        return c.getSymmetricInteger();
3377    }
3378}
3379
3380
3381/**
3382 * Conversion of ModInteger to BigInteger functor.
3383 */
3384class ModToInt<C extends RingElem<C> & Modular> implements UnaryFunctor<C, BigInteger> {
3385
3386
3387    public BigInteger eval(C c) {
3388        if (c == null) {
3389            return new BigInteger();
3390        }
3391        return c.getInteger();
3392    }
3393}
3394
3395
3396/**
3397 * Conversion of BigRational to BigInteger with division by lcm functor. result
3398 * = num*(lcm/denom).
3399 */
3400class RatToInt implements UnaryFunctor<BigRational, BigInteger> {
3401
3402
3403    java.math.BigInteger lcm;
3404
3405
3406    public RatToInt(java.math.BigInteger lcm) {
3407        this.lcm = lcm; //.getVal();
3408    }
3409
3410
3411    public BigInteger eval(BigRational c) {
3412        if (c == null) {
3413            return new BigInteger();
3414        }
3415        // p = num*(lcm/denom)
3416        java.math.BigInteger b = lcm.divide(c.denominator());
3417        return new BigInteger(c.numerator().multiply(b));
3418    }
3419}
3420
3421
3422/**
3423 * Conversion of BigRational to BigInteger. result = (num/gcd)*(lcm/denom).
3424 */
3425class RatToIntFactor implements UnaryFunctor<BigRational, BigInteger> {
3426
3427
3428    final java.math.BigInteger lcm;
3429
3430
3431    final java.math.BigInteger gcd;
3432
3433
3434    public RatToIntFactor(java.math.BigInteger gcd, java.math.BigInteger lcm) {
3435        this.gcd = gcd;
3436        this.lcm = lcm; // .getVal();
3437    }
3438
3439
3440    public BigInteger eval(BigRational c) {
3441        if (c == null) {
3442            return new BigInteger();
3443        }
3444        if (gcd.equals(java.math.BigInteger.ONE)) {
3445            // p = num*(lcm/denom)
3446            java.math.BigInteger b = lcm.divide(c.denominator());
3447            return new BigInteger(c.numerator().multiply(b));
3448        }
3449        // p = (num/gcd)*(lcm/denom)
3450        java.math.BigInteger a = c.numerator().divide(gcd);
3451        java.math.BigInteger b = lcm.divide(c.denominator());
3452        return new BigInteger(a.multiply(b));
3453    }
3454}
3455
3456
3457/**
3458 * Conversion of Rational to BigDecimal. result = decimal(r).
3459 */
3460class RatToDec<C extends Element<C> & Rational> implements UnaryFunctor<C, BigDecimal> {
3461
3462
3463    public BigDecimal eval(C c) {
3464        if (c == null) {
3465            return new BigDecimal();
3466        }
3467        return new BigDecimal(c.getRational());
3468    }
3469}
3470
3471
3472/**
3473 * Conversion of Complex Rational to Complex BigDecimal. result = decimal(r).
3474 */
3475class CompRatToDec<C extends RingElem<C> & Rational>
3476                implements UnaryFunctor<Complex<C>, Complex<BigDecimal>> {
3477
3478
3479    ComplexRing<BigDecimal> ring;
3480
3481
3482    public CompRatToDec(RingFactory<Complex<BigDecimal>> ring) {
3483        this.ring = (ComplexRing<BigDecimal>) ring;
3484    }
3485
3486
3487    public Complex<BigDecimal> eval(Complex<C> c) {
3488        if (c == null) {
3489            return ring.getZERO();
3490        }
3491        BigDecimal r = new BigDecimal(c.getRe().getRational());
3492        BigDecimal i = new BigDecimal(c.getIm().getRational());
3493        return new Complex<BigDecimal>(ring, r, i);
3494    }
3495}
3496
3497
3498/**
3499 * Conversion from BigInteger functor.
3500 */
3501class FromInteger<D extends RingElem<D>> implements UnaryFunctor<BigInteger, D> {
3502
3503
3504    RingFactory<D> ring;
3505
3506
3507    public FromInteger(RingFactory<D> ring) {
3508        this.ring = ring;
3509    }
3510
3511
3512    public D eval(BigInteger c) {
3513        if (c == null) {
3514            return ring.getZERO();
3515        }
3516        return ring.fromInteger(c.getVal());
3517    }
3518}
3519
3520
3521/**
3522 * Conversion from GenPolynomial<BigInteger> functor.
3523 */
3524class FromIntegerPoly<D extends RingElem<D>>
3525                implements UnaryFunctor<GenPolynomial<BigInteger>, GenPolynomial<D>> {
3526
3527
3528    GenPolynomialRing<D> ring;
3529
3530
3531    FromInteger<D> fi;
3532
3533
3534    public FromIntegerPoly(GenPolynomialRing<D> ring) {
3535        if (ring == null) {
3536            throw new IllegalArgumentException("ring must not be null");
3537        }
3538        this.ring = ring;
3539        fi = new FromInteger<D>(ring.coFac);
3540    }
3541
3542
3543    public GenPolynomial<D> eval(GenPolynomial<BigInteger> c) {
3544        if (c == null) {
3545            return ring.getZERO();
3546        }
3547        return PolyUtil.<BigInteger, D> map(ring, c, fi);
3548    }
3549}
3550
3551
3552/**
3553 * Conversion from GenPolynomial<BigRational> to GenPolynomial <BigInteger>
3554 * functor.
3555 */
3556class RatToIntPoly implements UnaryFunctor<GenPolynomial<BigRational>, GenPolynomial<BigInteger>> {
3557
3558
3559    GenPolynomialRing<BigInteger> ring;
3560
3561
3562    public RatToIntPoly(GenPolynomialRing<BigInteger> ring) {
3563        if (ring == null) {
3564            throw new IllegalArgumentException("ring must not be null");
3565        }
3566        this.ring = ring;
3567    }
3568
3569
3570    public GenPolynomial<BigInteger> eval(GenPolynomial<BigRational> c) {
3571        if (c == null) {
3572            return ring.getZERO();
3573        }
3574        return PolyUtil.integerFromRationalCoefficients(ring, c);
3575    }
3576}
3577
3578
3579/**
3580 * Real part functor.
3581 */
3582class RealPart implements UnaryFunctor<BigComplex, BigRational> {
3583
3584
3585    public BigRational eval(BigComplex c) {
3586        if (c == null) {
3587            return new BigRational();
3588        }
3589        return c.getRe();
3590    }
3591}
3592
3593
3594/**
3595 * Imaginary part functor.
3596 */
3597class ImagPart implements UnaryFunctor<BigComplex, BigRational> {
3598
3599
3600    public BigRational eval(BigComplex c) {
3601        if (c == null) {
3602            return new BigRational();
3603        }
3604        return c.getIm();
3605    }
3606}
3607
3608
3609/**
3610 * Real part functor.
3611 */
3612class RealPartComplex<C extends RingElem<C>> implements UnaryFunctor<Complex<C>, C> {
3613
3614
3615    public C eval(Complex<C> c) {
3616        if (c == null) {
3617            return null;
3618        }
3619        return c.getRe();
3620    }
3621}
3622
3623
3624/**
3625 * Imaginary part functor.
3626 */
3627class ImagPartComplex<C extends RingElem<C>> implements UnaryFunctor<Complex<C>, C> {
3628
3629
3630    public C eval(Complex<C> c) {
3631        if (c == null) {
3632            return null;
3633        }
3634        return c.getIm();
3635    }
3636}
3637
3638
3639/**
3640 * Rational to complex functor.
3641 */
3642class ToComplex<C extends RingElem<C>> implements UnaryFunctor<C, Complex<C>> {
3643
3644
3645    final protected ComplexRing<C> cfac;
3646
3647
3648    @SuppressWarnings("unchecked")
3649    public ToComplex(RingFactory<Complex<C>> fac) {
3650        if (fac == null) {
3651            throw new IllegalArgumentException("fac must not be null");
3652        }
3653        cfac = (ComplexRing<C>) fac;
3654    }
3655
3656
3657    public Complex<C> eval(C c) {
3658        if (c == null) {
3659            return cfac.getZERO();
3660        }
3661        return new Complex<C>(cfac, c);
3662    }
3663}
3664
3665
3666/**
3667 * Rational to complex functor.
3668 */
3669class RatToCompl implements UnaryFunctor<BigRational, BigComplex> {
3670
3671
3672    public BigComplex eval(BigRational c) {
3673        if (c == null) {
3674            return new BigComplex();
3675        }
3676        return new BigComplex(c);
3677    }
3678}
3679
3680
3681/**
3682 * Any ring element to generic complex functor.
3683 */
3684class AnyToComplex<C extends GcdRingElem<C>> implements UnaryFunctor<C, Complex<C>> {
3685
3686
3687    final protected ComplexRing<C> cfac;
3688
3689
3690    public AnyToComplex(ComplexRing<C> fac) {
3691        if (fac == null) {
3692            throw new IllegalArgumentException("fac must not be null");
3693        }
3694        cfac = fac;
3695    }
3696
3697
3698    public AnyToComplex(RingFactory<C> fac) {
3699        this(new ComplexRing<C>(fac));
3700    }
3701
3702
3703    public Complex<C> eval(C a) {
3704        if (a == null || a.isZERO()) { // should not happen
3705            return cfac.getZERO();
3706        } else if (a.isONE()) {
3707            return cfac.getONE();
3708        } else {
3709            return new Complex<C>(cfac, a);
3710        }
3711    }
3712}
3713
3714
3715/**
3716 * Algebraic to generic complex functor.
3717 */
3718class AlgebToCompl<C extends GcdRingElem<C>> implements UnaryFunctor<AlgebraicNumber<C>, Complex<C>> {
3719
3720
3721    final protected ComplexRing<C> cfac;
3722
3723
3724    public AlgebToCompl(ComplexRing<C> fac) {
3725        if (fac == null) {
3726            throw new IllegalArgumentException("fac must not be null");
3727        }
3728        cfac = fac;
3729    }
3730
3731
3732    public Complex<C> eval(AlgebraicNumber<C> a) {
3733        if (a == null || a.isZERO()) { // should not happen
3734            return cfac.getZERO();
3735        } else if (a.isONE()) {
3736            return cfac.getONE();
3737        } else {
3738            GenPolynomial<C> p = a.getVal();
3739            C real = cfac.ring.getZERO();
3740            C imag = cfac.ring.getZERO();
3741            for (Monomial<C> m : p) {
3742                if (m.exponent().getVal(0) == 1L) {
3743                    imag = m.coefficient();
3744                } else if (m.exponent().getVal(0) == 0L) {
3745                    real = m.coefficient();
3746                } else {
3747                    throw new IllegalArgumentException("unexpected monomial " + m);
3748                }
3749            }
3750            //Complex<C> c = new Complex<C>(cfac,real,imag);
3751            return new Complex<C>(cfac, real, imag);
3752        }
3753    }
3754}
3755
3756
3757/**
3758 * Ceneric complex to algebraic number functor.
3759 */
3760class ComplToAlgeb<C extends GcdRingElem<C>> implements UnaryFunctor<Complex<C>, AlgebraicNumber<C>> {
3761
3762
3763    final protected AlgebraicNumberRing<C> afac;
3764
3765
3766    final protected AlgebraicNumber<C> I;
3767
3768
3769    public ComplToAlgeb(AlgebraicNumberRing<C> fac) {
3770        if (fac == null) {
3771            throw new IllegalArgumentException("fac must not be null");
3772        }
3773        afac = fac;
3774        I = afac.getGenerator();
3775    }
3776
3777
3778    public AlgebraicNumber<C> eval(Complex<C> c) {
3779        if (c == null || c.isZERO()) { // should not happen
3780            return afac.getZERO();
3781        } else if (c.isONE()) {
3782            return afac.getONE();
3783        } else if (c.isIMAG()) {
3784            return I;
3785        } else {
3786            return I.multiply(c.getIm()).sum(c.getRe());
3787        }
3788    }
3789}
3790
3791
3792/**
3793 * Algebraic to polynomial functor.
3794 */
3795class AlgToPoly<C extends GcdRingElem<C>> implements UnaryFunctor<AlgebraicNumber<C>, GenPolynomial<C>> {
3796
3797
3798    public GenPolynomial<C> eval(AlgebraicNumber<C> c) {
3799        if (c == null) {
3800            return null;
3801        }
3802        return c.val;
3803    }
3804}
3805
3806
3807/**
3808 * Polynomial to algebriac functor.
3809 */
3810class PolyToAlg<C extends GcdRingElem<C>> implements UnaryFunctor<GenPolynomial<C>, AlgebraicNumber<C>> {
3811
3812
3813    final protected AlgebraicNumberRing<C> afac;
3814
3815
3816    public PolyToAlg(AlgebraicNumberRing<C> fac) {
3817        if (fac == null) {
3818            throw new IllegalArgumentException("fac must not be null");
3819        }
3820        afac = fac;
3821    }
3822
3823
3824    public AlgebraicNumber<C> eval(GenPolynomial<C> c) {
3825        if (c == null) {
3826            return afac.getZERO();
3827        }
3828        return new AlgebraicNumber<C>(afac, c);
3829    }
3830}
3831
3832
3833/**
3834 * Coefficient to algebriac functor.
3835 */
3836class CoeffToAlg<C extends GcdRingElem<C>> implements UnaryFunctor<C, AlgebraicNumber<C>> {
3837
3838
3839    final protected AlgebraicNumberRing<C> afac;
3840
3841
3842    final protected GenPolynomial<C> zero;
3843
3844
3845    public CoeffToAlg(AlgebraicNumberRing<C> fac) {
3846        if (fac == null) {
3847            throw new IllegalArgumentException("fac must not be null");
3848        }
3849        afac = fac;
3850        GenPolynomialRing<C> pfac = afac.ring;
3851        zero = pfac.getZERO();
3852    }
3853
3854
3855    public AlgebraicNumber<C> eval(C c) {
3856        if (c == null) {
3857            return afac.getZERO();
3858        }
3859        return new AlgebraicNumber<C>(afac, zero.sum(c));
3860    }
3861}
3862
3863
3864/**
3865 * Coefficient to recursive algebriac functor.
3866 */
3867class CoeffToRecAlg<C extends GcdRingElem<C>> implements UnaryFunctor<C, AlgebraicNumber<C>> {
3868
3869
3870    final protected List<AlgebraicNumberRing<C>> lfac;
3871
3872
3873    final int depth;
3874
3875
3876    @SuppressWarnings("unchecked")
3877    public CoeffToRecAlg(int depth, AlgebraicNumberRing<C> fac) {
3878        if (fac == null) {
3879            throw new IllegalArgumentException("fac must not be null");
3880        }
3881        AlgebraicNumberRing<C> afac = fac;
3882        this.depth = depth;
3883        lfac = new ArrayList<AlgebraicNumberRing<C>>(this.depth);
3884        lfac.add(fac);
3885        for (int i = 1; i < this.depth; i++) {
3886            RingFactory<C> rf = afac.ring.coFac;
3887            if (!(rf instanceof AlgebraicNumberRing)) {
3888                throw new IllegalArgumentException("fac depth to low");
3889            }
3890            afac = (AlgebraicNumberRing<C>) (Object) rf;
3891            lfac.add(afac);
3892        }
3893    }
3894
3895
3896    @SuppressWarnings("unchecked")
3897    public AlgebraicNumber<C> eval(C c) {
3898        if (c == null) {
3899            return lfac.get(0).getZERO();
3900        }
3901        C ac = c;
3902        AlgebraicNumberRing<C> af = lfac.get(lfac.size() - 1);
3903        GenPolynomial<C> zero = af.ring.getZERO();
3904        AlgebraicNumber<C> an = new AlgebraicNumber<C>(af, zero.sum(ac));
3905        for (int i = lfac.size() - 2; i >= 0; i--) {
3906            af = lfac.get(i);
3907            zero = af.ring.getZERO();
3908            ac = (C) (Object) an;
3909            an = new AlgebraicNumber<C>(af, zero.sum(ac));
3910        }
3911        return an;
3912    }
3913}
3914
3915
3916/**
3917 * Evaluate main variable functor.
3918 */
3919class EvalMain<C extends RingElem<C>> implements UnaryFunctor<GenPolynomial<C>, C> {
3920
3921
3922    final RingFactory<C> cfac;
3923
3924
3925    final C a;
3926
3927
3928    public EvalMain(RingFactory<C> cfac, C a) {
3929        this.cfac = cfac;
3930        this.a = a;
3931    }
3932
3933
3934    public C eval(GenPolynomial<C> c) {
3935        if (c == null) {
3936            return cfac.getZERO();
3937        }
3938        return PolyUtil.<C> evaluateMain(cfac, c, a);
3939    }
3940}
3941
3942
3943/**
3944 * Evaluate main variable functor.
3945 */
3946class EvalMainPol<C extends RingElem<C>> implements UnaryFunctor<GenPolynomial<C>, GenPolynomial<C>> {
3947
3948
3949    final GenPolynomialRing<C> cfac;
3950
3951
3952    final C a;
3953
3954
3955    public EvalMainPol(GenPolynomialRing<C> cfac, C a) {
3956        this.cfac = cfac;
3957        this.a = a;
3958    }
3959
3960
3961    public GenPolynomial<C> eval(GenPolynomial<C> c) {
3962        if (c == null) {
3963            return cfac.getZERO();
3964        }
3965        return PolyUtil.<C> evaluateMain(cfac, c, a);
3966    }
3967}
3968
3969
3970/**
3971 * Evaluate all variable functor.
3972 */
3973class EvalAllPol<C extends RingElem<C>> implements UnaryFunctor<GenPolynomial<C>, C> {
3974
3975
3976    final RingFactory<C> cfac;
3977
3978
3979    final List<C> a;
3980
3981
3982    public EvalAllPol(RingFactory<C> cfac, List<C> a) {
3983        this.cfac = cfac;
3984        this.a = a;
3985    }
3986
3987
3988    public C eval(GenPolynomial<C> c) {
3989        if (c == null) {
3990            return cfac.getZERO();
3991        }
3992        return PolyUtil.<C> evaluateAll(cfac, c, a);
3993    }
3994}