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