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