All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.jas.poly.PolyUtil Maven / Gradle / Ivy

The newest version!
/*
 * $Id: PolyUtil.java 4378 2013-04-26 16:50:33Z kredel $
 */

package edu.jas.poly;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.log4j.Logger;

import edu.jas.arith.BigComplex;
import edu.jas.arith.BigDecimal;
import edu.jas.arith.BigInteger;
import edu.jas.arith.BigRational;
import edu.jas.arith.ModInteger;
import edu.jas.arith.ModIntegerRing;
import edu.jas.arith.Modular;
import edu.jas.arith.ModularRingFactory;
import edu.jas.arith.Product;
import edu.jas.arith.ProductRing;
import edu.jas.arith.Rational;
import edu.jas.structure.Element;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingElem;
import edu.jas.structure.RingFactory;
import edu.jas.structure.UnaryFunctor;
import edu.jas.util.ListUtil;


/**
 * Polynomial utilities, for example conversion between different
 * representations, evaluation and interpolation.
 * @author Heinz Kredel
 */

public class PolyUtil {


    private static final Logger logger = Logger.getLogger(PolyUtil.class);


    private static boolean debug = logger.isDebugEnabled();


    /**
     * Recursive representation. Represent as polynomial in i variables with
     * coefficients in n-i variables. Works for arbitrary term orders.
     * @param  coefficient type.
     * @param rfac recursive polynomial ring factory.
     * @param A polynomial to be converted.
     * @return Recursive represenations of this in the ring rfac.
     */
    public static > GenPolynomial> recursive(
                    GenPolynomialRing> rfac, GenPolynomial A) {

        GenPolynomial> B = rfac.getZERO().copy();
        if (A.isZERO()) {
            return B;
        }
        int i = rfac.nvar;
        GenPolynomial zero = rfac.getZEROCoefficient();
        Map> Bv = B.val; //getMap();
        for (Map.Entry y : A.getMap().entrySet()) {
            ExpVector e = y.getKey();
            C a = y.getValue();
            ExpVector f = e.contract(0, i);
            ExpVector g = e.contract(i, e.length() - i);
            GenPolynomial p = Bv.get(f);
            if (p == null) {
                p = zero;
            }
            p = p.sum(a, g);
            Bv.put(f, p);
        }
        return B;
    }


    /**
     * Distribute a recursive polynomial to a generic polynomial. Works for
     * arbitrary term orders.
     * @param  coefficient type.
     * @param dfac combined polynomial ring factory of coefficients and this.
     * @param B polynomial to be converted.
     * @return distributed polynomial.
     */
    public static > GenPolynomial distribute(GenPolynomialRing dfac,
                    GenPolynomial> B) {
        GenPolynomial C = dfac.getZERO().copy();
        if (B.isZERO()) {
            return C;
        }
        Map Cm = C.val; //getMap();
        for (Map.Entry> y : B.getMap().entrySet()) {
            ExpVector e = y.getKey();
            GenPolynomial A = y.getValue();
            for (Map.Entry x : A.val.entrySet()) {
                ExpVector f = x.getKey();
                C b = x.getValue();
                ExpVector g = e.combine(f);
                assert (Cm.get(g) != null);
                //if ( Cm.get(g) != null ) { // todo assert, done
                //   throw new RuntimeException("PolyUtil debug error");
                //}
                Cm.put(g, b);
            }
        }
        return C;
    }


    /**
     * Recursive representation. Represent as polynomials in i variables with
     * coefficients in n-i variables. Works for arbitrary term orders.
     * @param  coefficient type.
     * @param rfac recursive polynomial ring factory.
     * @param L list of polynomials to be converted.
     * @return Recursive represenations of the list in the ring rfac.
     */
    public static > List>> recursive(
                    GenPolynomialRing> rfac, List> L) {
        return ListUtil., GenPolynomial>> map(L, new DistToRec(rfac));
    }


    /**
     * Distribute a recursive polynomial list to a generic polynomial list.
     * Works for arbitrary term orders.
     * @param  coefficient type.
     * @param dfac combined polynomial ring factory of coefficients and this.
     * @param L list of polynomials to be converted.
     * @return distributed polynomial list.
     */
    public static > List> distribute(GenPolynomialRing dfac,
                    List>> L) {
        return ListUtil.>, GenPolynomial> map(L, new RecToDist(dfac));
    }


    /**
     * BigInteger from ModInteger coefficients, symmetric. Represent as
     * polynomial with BigInteger coefficients by removing the modules and
     * making coefficients symmetric to 0.
     * @param fac result polynomial factory.
     * @param A polynomial with ModInteger coefficients to be converted.
     * @return polynomial with BigInteger coefficients.
     */
    public static  & Modular> GenPolynomial integerFromModularCoefficients(
                    GenPolynomialRing fac, GenPolynomial A) {
        return PolyUtil. map(fac, A, new ModSymToInt());
    }


    /**
     * BigInteger from ModInteger coefficients, symmetric. Represent as
     * polynomial with BigInteger coefficients by removing the modules and
     * making coefficients symmetric to 0.
     * @param fac result polynomial factory.
     * @param L list of polynomials with ModInteger coefficients to be
     *            converted.
     * @return list of polynomials with BigInteger coefficients.
     */
    public static  & Modular> List> integerFromModularCoefficients(
                    final GenPolynomialRing fac, List> L) {
        return ListUtil., GenPolynomial> map(L,
                        new UnaryFunctor, GenPolynomial>() {


                            public GenPolynomial eval(GenPolynomial c) {
                                return PolyUtil. integerFromModularCoefficients(fac, c);
                            }
                        });
    }


    /**
     * BigInteger from ModInteger coefficients, positive. Represent as
     * polynomial with BigInteger coefficients by removing the modules.
     * @param fac result polynomial factory.
     * @param A polynomial with ModInteger coefficients to be converted.
     * @return polynomial with BigInteger coefficients.
     */
    public static  & Modular> GenPolynomial integerFromModularCoefficientsPositive(
                    GenPolynomialRing fac, GenPolynomial A) {
        return PolyUtil. map(fac, A, new ModToInt());
    }


    /**
     * BigInteger from BigRational coefficients. Represent as polynomial with
     * BigInteger coefficients by multiplication with the lcm of the numerators
     * of the BigRational coefficients.
     * @param fac result polynomial factory.
     * @param A polynomial with BigRational coefficients to be converted.
     * @return polynomial with BigInteger coefficients.
     */
    public static GenPolynomial integerFromRationalCoefficients(
                    GenPolynomialRing fac, GenPolynomial A) {
        if (A == null || A.isZERO()) {
            return fac.getZERO();
        }
        java.math.BigInteger c = null;
        int s = 0;
        // lcm of denominators
        for (BigRational y : A.val.values()) {
            java.math.BigInteger x = y.denominator();
            // c = lcm(c,x)
            if (c == null) {
                c = x;
                s = x.signum();
            } else {
                java.math.BigInteger d = c.gcd(x);
                c = c.multiply(x.divide(d));
            }
        }
        if (s < 0) {
            c = c.negate();
        }
        return PolyUtil. map(fac, A, new RatToInt(c));
    }


    /**
     * BigInteger from BigRational coefficients. Represent as polynomial with
     * BigInteger coefficients by multiplication with the gcd of the numerators
     * and the lcm of the denominators of the BigRational coefficients. 
* Author: Axel Kramer * @param fac result polynomial factory. * @param A polynomial with BigRational coefficients to be converted. * @return Object[] with 3 entries: [0]->gcd [1]->lcm and [2]->polynomial * with BigInteger coefficients. */ public static Object[] integerFromRationalCoefficientsFactor(GenPolynomialRing fac, GenPolynomial A) { Object[] result = new Object[3]; if (A == null || A.isZERO()) { result[0] = java.math.BigInteger.ONE; result[1] = java.math.BigInteger.ZERO; result[2] = fac.getZERO(); return result; } java.math.BigInteger gcd = null; java.math.BigInteger lcm = null; int sLCM = 0; int sGCD = 0; // lcm of denominators for (BigRational y : A.val.values()) { java.math.BigInteger numerator = y.numerator(); java.math.BigInteger denominator = y.denominator(); // lcm = lcm(lcm,x) if (lcm == null) { lcm = denominator; sLCM = denominator.signum(); } else { java.math.BigInteger d = lcm.gcd(denominator); lcm = lcm.multiply(denominator.divide(d)); } // gcd = gcd(gcd,x) if (gcd == null) { gcd = numerator; sGCD = numerator.signum(); } else { gcd = gcd.gcd(numerator); } } if (sLCM < 0) { lcm = lcm.negate(); } if (sGCD < 0) { gcd = gcd.negate(); } result[0] = gcd; result[1] = lcm; result[2] = PolyUtil. map(fac, A, new RatToIntFactor(gcd, lcm)); return result; } /** * BigInteger from BigRational coefficients. Represent as list of * polynomials with BigInteger coefficients by multiplication with the lcm * of the numerators of the BigRational coefficients of each polynomial. * @param fac result polynomial factory. * @param L list of polynomials with BigRational coefficients to be * converted. * @return polynomial list with BigInteger coefficients. */ public static List> integerFromRationalCoefficients( GenPolynomialRing fac, List> L) { return ListUtil., GenPolynomial> map(L, new RatToIntPoly(fac)); } /** * From BigInteger coefficients. Represent as polynomial with type C * coefficients, e.g. ModInteger or BigRational. * @param coefficient type. * @param fac result polynomial factory. * @param A polynomial with BigInteger coefficients to be converted. * @return polynomial with type C coefficients. */ public static > GenPolynomial fromIntegerCoefficients(GenPolynomialRing fac, GenPolynomial A) { return PolyUtil. map(fac, A, new FromInteger(fac.coFac)); } /** * From BigInteger coefficients. Represent as list of polynomials with type * C coefficients, e.g. ModInteger or BigRational. * @param coefficient type. * @param fac result polynomial factory. * @param L list of polynomials with BigInteger coefficients to be * converted. * @return list of polynomials with type C coefficients. */ public static > List> fromIntegerCoefficients( GenPolynomialRing fac, List> L) { return ListUtil., GenPolynomial> map(L, new FromIntegerPoly(fac)); } /** * Convert to decimal coefficients. * @param fac result polynomial factory. * @param A polynomial with Rational coefficients to be converted. * @return polynomial with BigDecimal coefficients. */ public static & Rational> GenPolynomial decimalFromRational( GenPolynomialRing fac, GenPolynomial A) { return PolyUtil. map(fac, A, new RatToDec()); } /** * Convert to complex decimal coefficients. * @param fac result polynomial factory. * @param A polynomial with complex Rational coefficients to be converted. * @return polynomial with Complex BigDecimal coefficients. */ public static & Rational> GenPolynomial> complexDecimalFromRational( GenPolynomialRing> fac, GenPolynomial> A) { return PolyUtil., Complex> map(fac, A, new CompRatToDec(fac.coFac)); } /** * Real part. * @param fac result polynomial factory. * @param A polynomial with BigComplex coefficients to be converted. * @return polynomial with real part of the coefficients. */ public static GenPolynomial realPart(GenPolynomialRing fac, GenPolynomial A) { return PolyUtil. map(fac, A, new RealPart()); } /** * Imaginary part. * @param fac result polynomial factory. * @param A polynomial with BigComplex coefficients to be converted. * @return polynomial with imaginary part of coefficients. */ public static GenPolynomial imaginaryPart(GenPolynomialRing fac, GenPolynomial A) { return PolyUtil. map(fac, A, new ImagPart()); } /** * Real part. * @param fac result polynomial factory. * @param A polynomial with BigComplex coefficients to be converted. * @return polynomial with real part of the coefficients. */ public static > GenPolynomial realPartFromComplex(GenPolynomialRing fac, GenPolynomial> A) { return PolyUtil., C> map(fac, A, new RealPartComplex()); } /** * Imaginary part. * @param fac result polynomial factory. * @param A polynomial with BigComplex coefficients to be converted. * @return polynomial with imaginary part of coefficients. */ public static > GenPolynomial imaginaryPartFromComplex(GenPolynomialRing fac, GenPolynomial> A) { return PolyUtil., C> map(fac, A, new ImagPartComplex()); } /** * Complex from real polynomial. * @param fac result polynomial factory. * @param A polynomial with C coefficients to be converted. * @return polynomial with Complex coefficients. */ public static > GenPolynomial> toComplex( GenPolynomialRing> fac, GenPolynomial A) { return PolyUtil.> map(fac, A, new ToComplex(fac.coFac)); } /** * Complex from rational coefficients. * @param fac result polynomial factory. * @param A polynomial with BigRational coefficients to be converted. * @return polynomial with BigComplex coefficients. */ public static GenPolynomial complexFromRational(GenPolynomialRing fac, GenPolynomial A) { return PolyUtil. map(fac, A, new RatToCompl()); } /** * Complex from ring element coefficients. * @param fac result polynomial factory. * @param A polynomial with RingElem coefficients to be converted. * @return polynomial with Complex coefficients. */ public static > GenPolynomial> complexFromAny( GenPolynomialRing> fac, GenPolynomial A) { ComplexRing cr = (ComplexRing) fac.coFac; return PolyUtil.> map(fac, A, new AnyToComplex(cr)); } /** * From AlgebraicNumber coefficients. Represent as polynomial with type * GenPolynomial<C> coefficients, e.g. ModInteger or BigRational. * @param rfac result polynomial factory. * @param A polynomial with AlgebraicNumber coefficients to be converted. * @return polynomial with type GenPolynomial<C> coefficients. */ public static > GenPolynomial> fromAlgebraicCoefficients( GenPolynomialRing> rfac, GenPolynomial> A) { return PolyUtil., GenPolynomial> map(rfac, A, new AlgToPoly()); } /** * Convert to AlgebraicNumber coefficients. Represent as polynomial with * AlgebraicNumber coefficients, C is e.g. ModInteger or BigRational. * @param pfac result polynomial factory. * @param A polynomial with C coefficients to be converted. * @return polynomial with AlgebraicNumber<C> coefficients. */ public static > GenPolynomial> convertToAlgebraicCoefficients( GenPolynomialRing> pfac, GenPolynomial A) { AlgebraicNumberRing afac = (AlgebraicNumberRing) pfac.coFac; return PolyUtil.> map(pfac, A, new CoeffToAlg(afac)); } /** * Convert to recursive AlgebraicNumber coefficients. Represent as * polynomial with recursive AlgebraicNumber coefficients, C is e.g. * ModInteger or BigRational. * @param depth recursion depth of AlgebraicNumber coefficients. * @param pfac result polynomial factory. * @param A polynomial with C coefficients to be converted. * @return polynomial with AlgebraicNumber<C> coefficients. */ public static > GenPolynomial> convertToRecAlgebraicCoefficients( int depth, GenPolynomialRing> pfac, GenPolynomial A) { AlgebraicNumberRing afac = (AlgebraicNumberRing) pfac.coFac; return PolyUtil.> map(pfac, A, new CoeffToRecAlg(depth, afac)); } /** * Convert to AlgebraicNumber coefficients. Represent as polynomial with * AlgebraicNumber coefficients, C is e.g. ModInteger or BigRational. * @param pfac result polynomial factory. * @param A recursive polynomial with GenPolynomial<BigInteger> * coefficients to be converted. * @return polynomial with AlgebraicNumber<C> coefficients. */ public static > GenPolynomial> convertRecursiveToAlgebraicCoefficients( GenPolynomialRing> pfac, GenPolynomial> A) { AlgebraicNumberRing afac = (AlgebraicNumberRing) pfac.coFac; return PolyUtil., AlgebraicNumber> map(pfac, A, new PolyToAlg(afac)); } /** * Complex from algebraic coefficients. * @param fac result polynomial factory. * @param A polynomial with AlgebraicNumber coefficients Q(i) to be * converted. * @return polynomial with Complex coefficients. */ public static > GenPolynomial> complexFromAlgebraic( GenPolynomialRing> fac, GenPolynomial> A) { ComplexRing cfac = (ComplexRing) fac.coFac; return PolyUtil., Complex> map(fac, A, new AlgebToCompl(cfac)); } /** * AlgebraicNumber from complex coefficients. * @param fac result polynomial factory over Q(i). * @param A polynomial with Complex coefficients to be converted. * @return polynomial with AlgebraicNumber coefficients. */ public static > GenPolynomial> algebraicFromComplex( GenPolynomialRing> fac, GenPolynomial> A) { AlgebraicNumberRing afac = (AlgebraicNumberRing) fac.coFac; return PolyUtil., AlgebraicNumber> map(fac, A, new ComplToAlgeb(afac)); } /** * ModInteger chinese remainder algorithm on coefficients. * @param fac GenPolynomial<ModInteger> result factory with * A.coFac.modul*B.coFac.modul = C.coFac.modul. * @param A GenPolynomial<ModInteger>. * @param B other GenPolynomial<ModInteger>. * @param mi inverse of A.coFac.modul in ring B.coFac. * @return S = cra(A,B), with S mod A.coFac.modul == A and S mod * B.coFac.modul == B. */ public static & Modular> GenPolynomial chineseRemainder( GenPolynomialRing fac, GenPolynomial A, C mi, GenPolynomial B) { ModularRingFactory cfac = (ModularRingFactory) fac.coFac; // get RingFactory GenPolynomial S = fac.getZERO().copy(); GenPolynomial Ap = A.copy(); SortedMap av = Ap.val; //getMap(); SortedMap bv = B.getMap(); SortedMap sv = S.val; //getMap(); C c = null; for (Map.Entry me : bv.entrySet()) { ExpVector e = me.getKey(); C y = me.getValue(); //bv.get(e); // assert y != null C x = av.get(e); if (x != null) { av.remove(e); c = cfac.chineseRemainder(x, mi, y); if (!c.isZERO()) { // 0 cannot happen sv.put(e, c); } } else { //c = cfac.fromInteger( y.getVal() ); c = cfac.chineseRemainder(A.ring.coFac.getZERO(), mi, y); if (!c.isZERO()) { // 0 cannot happen sv.put(e, c); // c != null } } } // assert bv is empty = done for (Map.Entry me : av.entrySet()) { // rest of av ExpVector e = me.getKey(); C x = me.getValue(); // av.get(e); // assert x != null //c = cfac.fromInteger( x.getVal() ); c = cfac.chineseRemainder(x, mi, B.ring.coFac.getZERO()); if (!c.isZERO()) { // 0 cannot happen sv.put(e, c); // c != null } } return S; } /** * GenPolynomial monic, i.e. leadingBaseCoefficient == 1. If * leadingBaseCoefficient is not invertible returns this unmodified. * @param coefficient type. * @param p recursive GenPolynomial>. * @return monic(p). */ public static > GenPolynomial> monic( GenPolynomial> p) { if (p == null || p.isZERO()) { return p; } C lc = p.leadingBaseCoefficient().leadingBaseCoefficient(); if (!lc.isUnit()) { return p; } C lm = lc.inverse(); GenPolynomial L = p.ring.coFac.getONE(); L = L.multiply(lm); return p.multiply(L); } /** * Polynomial list monic. * @param coefficient type. * @param L list of polynomials with field coefficients. * @return list of polynomials with leading coefficient 1. */ public static > List> monic(List> L) { return ListUtil., GenPolynomial> map(L, new UnaryFunctor, GenPolynomial>() { public GenPolynomial eval(GenPolynomial c) { if (c == null) { return null; } return c.monic(); } }); } /** * Recursive polynomial list monic. * @param coefficient type. * @param L list of recursive polynomials with field coefficients. * @return list of polynomials with leading base coefficient 1. */ public static > List>> monicRec(List>> L) { return ListUtil.>, GenPolynomial>> map(L, new UnaryFunctor>, GenPolynomial>>() { public GenPolynomial> eval(GenPolynomial> c) { if (c == null) { return null; } return PolyUtil. monic(c); } }); } /** * Polynomial list leading exponent vectors. * @param coefficient type. * @param L list of polynomials. * @return list of leading exponent vectors. */ public static > List leadingExpVector(List> L) { return ListUtil., ExpVector> map(L, new UnaryFunctor, ExpVector>() { public ExpVector eval(GenPolynomial c) { if (c == null) { return null; } return c.leadingExpVector(); } }); } /** * Extend coefficient variables. Extend all coefficient ExpVectors by i * elements and multiply by x_j^k. * @param pfac extended polynomial ring factory (by i variables in the * coefficients). * @param j index of variable to be used for multiplication. * @param k exponent for x_j. * @return extended polynomial. */ public static > GenPolynomial> extendCoefficients( GenPolynomialRing> pfac, GenPolynomial> A, int j, long k) { GenPolynomial> Cp = pfac.getZERO().copy(); if (A.isZERO()) { return Cp; } GenPolynomialRing cfac = (GenPolynomialRing) pfac.coFac; //GenPolynomialRing acfac = (GenPolynomialRing) A.ring.coFac; //int i = cfac.nvar - acfac.nvar; Map> CC = Cp.val; //getMap(); for (Map.Entry> y : A.val.entrySet()) { ExpVector e = y.getKey(); GenPolynomial a = y.getValue(); GenPolynomial f = a.extend(cfac, j, k); CC.put(e, f); } return Cp; } /** * Extend coefficient variables. Extend all coefficient ExpVectors by i * elements and multiply by x_j^k. * @param pfac extended polynomial ring factory (by i variables in the * coefficients). * @param j index of variable to be used for multiplication. * @param k exponent for x_j. * @return extended polynomial. */ public static > GenSolvablePolynomial> extendCoefficients(GenSolvablePolynomialRing> pfac, GenSolvablePolynomial> A, int j, long k) { GenSolvablePolynomial> Cp = pfac.getZERO().copy(); if (A.isZERO()) { return Cp; } GenPolynomialRing cfac = (GenPolynomialRing) pfac.coFac; //GenPolynomialRing acfac = (GenPolynomialRing) A.ring.coFac; //int i = cfac.nvar - acfac.nvar; Map> CC = Cp.val; //getMap(); for (Map.Entry> y : A.val.entrySet()) { ExpVector e = y.getKey(); GenPolynomial a = y.getValue(); GenPolynomial f = a.extend(cfac, j, k); CC.put(e, f); } return Cp; } /** * To recursive representation. Represent as polynomial in i+r variables * with coefficients in i variables. Works for arbitrary term orders. * @param coefficient type. * @param rfac recursive polynomial ring factory. * @param A polynomial to be converted. * @return Recursive represenations of A in the ring rfac. */ public static > GenPolynomial> toRecursive( GenPolynomialRing> rfac, GenPolynomial A) { GenPolynomial> B = rfac.getZERO().copy(); if (A.isZERO()) { return B; } //int i = rfac.nvar; //GenPolynomial zero = rfac.getZEROCoefficient(); GenPolynomial one = rfac.getONECoefficient(); Map> Bv = B.val; //getMap(); for (Monomial m : A) { ExpVector e = m.e; C a = m.c; GenPolynomial p = one.multiply(a); Bv.put(e, p); } return B; } /** * To recursive representation. Represent as solvable polynomial in i+r variables * with coefficients in i variables. Works for arbitrary term orders. * @param coefficient type. * @param rfac recursive solvable polynomial ring factory. * @param A solvable polynomial to be converted. * @return Recursive represenations of A in the ring rfac. */ public static > GenSolvablePolynomial> toRecursive( GenSolvablePolynomialRing> rfac, GenSolvablePolynomial A) { GenSolvablePolynomial> B = rfac.getZERO().copy(); if (A.isZERO()) { return B; } //int i = rfac.nvar; //GenPolynomial zero = rfac.getZEROCoefficient(); GenPolynomial one = rfac.getONECoefficient(); Map> Bv = B.val; //getMap(); for (Monomial m : A) { ExpVector e = m.e; C a = m.c; GenPolynomial p = one.multiply(a); Bv.put(e, p); } return B; } /** * GenPolynomial coefficient wise remainder. * @param coefficient type. * @param P GenPolynomial. * @param s nonzero coefficient. * @return coefficient wise remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial baseRemainderPoly(GenPolynomial P, C s) { if (s == null || s.isZERO()) { throw new ArithmeticException(P + " division by zero " + s); } GenPolynomial h = P.ring.getZERO().copy(); Map hm = h.val; //getMap(); for (Map.Entry m : P.getMap().entrySet()) { ExpVector f = m.getKey(); C a = m.getValue(); C x = a.remainder(s); hm.put(f, x); } return h; } /** * GenPolynomial sparse pseudo remainder. For univariate polynomials. * @param coefficient type. * @param P GenPolynomial. * @param S nonzero GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * m' ≤ deg(P)-deg(S) * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). * @deprecated Use * {@link #baseSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)} * instead */ @Deprecated public static > GenPolynomial basePseudoRemainder(GenPolynomial P, GenPolynomial S) { return baseSparsePseudoRemainder(P, S); } /** * GenPolynomial sparse pseudo remainder. For univariate polynomials. * @param coefficient type. * @param P GenPolynomial. * @param S nonzero GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * m' ≤ deg(P)-deg(S) * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial baseSparsePseudoRemainder(GenPolynomial P, GenPolynomial S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P.toString() + " division by zero " + S); } if (P.isZERO()) { return P; } if (S.isONE()) { return P.ring.getZERO(); } C c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial h; GenPolynomial r = P; while (!r.isZERO()) { ExpVector f = r.leadingExpVector(); if (f.multipleOf(e)) { C a = r.leadingBaseCoefficient(); f = f.subtract(e); C x = a.remainder(c); if (x.isZERO()) { C y = a.divide(c); h = S.multiply(y, f); // coeff a } else { r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac } r = r.subtract(h); } else { break; } } return r; } /** * GenPolynomial dense pseudo remainder. For univariate polynomials. * @param P GenPolynomial. * @param S nonzero GenPolynomial. * @return remainder with ldcf(S)m P = quotient * S + remainder. * m == deg(P)-deg(S) * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial baseDensePseudoRemainder(GenPolynomial P, GenPolynomial S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P + " division by zero " + S); } if (P.isZERO()) { return P; } if (S.degree() <= 0) { return P.ring.getZERO(); } long m = P.degree(0); long n = S.degree(0); C c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial h; GenPolynomial r = P; for (long i = m; i >= n; i--) { if (r.isZERO()) { return r; } long k = r.degree(0); if (i == k) { ExpVector f = r.leadingExpVector(); C a = r.leadingBaseCoefficient(); f = f.subtract(e); // EVDIF( f, e ); //System.out.println("red div = " + f); r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac r = r.subtract(h); } else { r = r.multiply(c); } } return r; } /** * GenPolynomial dense pseudo quotient. For univariate polynomials. * @param P GenPolynomial. * @param S nonzero GenPolynomial. * @return quotient with ldcf(S)m P = quotient * S + remainder. m * == deg(P)-deg(S) * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial baseDensePseudoQuotient(GenPolynomial P, GenPolynomial S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P + " division by zero " + S); } if (P.isZERO()) { return P; } //if (S.degree() <= 0) { // return l^n P; //P.ring.getZERO(); //} long m = P.degree(0); long n = S.degree(0); C c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial q = P.ring.getZERO(); GenPolynomial h; GenPolynomial r = P; for (long i = m; i >= n; i--) { if (r.isZERO()) { return q; } long k = r.degree(0); if (i == k) { ExpVector f = r.leadingExpVector(); C a = r.leadingBaseCoefficient(); f = f.subtract(e); // EVDIF( f, e ); //System.out.println("red div = " + f); r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac r = r.subtract(h); q = q.multiply(c); q = q.sum(a, f); } else { q = q.multiply(c); r = r.multiply(c); } } return q; } /** * GenPolynomial sparse pseudo divide. For univariate polynomials or exact * division. * @param coefficient type. * @param P GenPolynomial. * @param S nonzero GenPolynomial. * @return quotient with ldcf(S)m' P = quotient * S + remainder. * m' ≤ deg(P)-deg(S) * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial basePseudoDivide(GenPolynomial P, GenPolynomial S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P.toString() + " division by zero " + S); } //if (S.ring.nvar != 1) { // ok if exact division // throw new RuntimeException(this.getClass().getName() // + " univariate polynomials only"); //} if (P.isZERO() || S.isONE()) { return P; } C c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial h; GenPolynomial r = P; GenPolynomial q = S.ring.getZERO().copy(); while (!r.isZERO()) { ExpVector f = r.leadingExpVector(); if (f.multipleOf(e)) { C a = r.leadingBaseCoefficient(); f = f.subtract(e); C x = a.remainder(c); if (x.isZERO()) { C y = a.divide(c); q = q.sum(y, f); h = S.multiply(y, f); // coeff a } else { q = q.multiply(c); q = q.sum(a, f); r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac } r = r.subtract(h); } else { break; } } return q; } /** * GenPolynomial sparse pseudo quotient and remainder. For univariate * polynomials or exact division. * @param coefficient type. * @param P GenPolynomial. * @param S nonzero GenPolynomial. * @return [ quotient, remainder ] with ldcf(S)m' P = quotient * * S + remainder. m' ≤ deg(P)-deg(S) * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial). */ @SuppressWarnings("unchecked") public static > GenPolynomial[] basePseudoQuotientRemainder(GenPolynomial P, GenPolynomial S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P.toString() + " division by zero " + S); } //if (S.ring.nvar != 1) { // ok if exact division // throw new RuntimeException(this.getClass().getName() // + " univariate polynomials only"); //} GenPolynomial[] ret = new GenPolynomial[2]; ret[0] = null; ret[1] = null; if (P.isZERO() || S.isONE()) { ret[0] = P; ret[1] = S.ring.getZERO(); return ret; } C c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial h; GenPolynomial r = P; GenPolynomial q = S.ring.getZERO().copy(); while (!r.isZERO()) { ExpVector f = r.leadingExpVector(); if (f.multipleOf(e)) { C a = r.leadingBaseCoefficient(); f = f.subtract(e); C x = a.remainder(c); if (x.isZERO()) { C y = a.divide(c); q = q.sum(y, f); h = S.multiply(y, f); // coeff a } else { q = q.multiply(c); q = q.sum(a, f); r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac } r = r.subtract(h); } else { break; } } //GenPolynomial rhs = q.multiply(S).sum(r); //GenPolynomial lhs = P; ret[0] = q; ret[1] = r; return ret; } /** * Is GenPolynomial pseudo quotient and remainder. For univariate * polynomials. * @param coefficient type. * @param P base GenPolynomial. * @param S nonzero base GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). * Note: not always meaningful and working */ public static > boolean isBasePseudoQuotientRemainder(GenPolynomial P, GenPolynomial S, GenPolynomial q, GenPolynomial r) { GenPolynomial rhs = q.multiply(S).sum(r); //System.out.println("rhs,1 = " + rhs); GenPolynomial lhs = P; C ldcf = S.leadingBaseCoefficient(); long d = P.degree(0) - S.degree(0) + 1; d = (d > 0 ? d : -d + 2); for (long i = 0; i <= d; i++) { //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); if (lhs.equals(rhs)) { //System.out.println("lhs,1 = " + lhs); return true; } lhs = lhs.multiply(ldcf); } GenPolynomial Pp = P; rhs = q.multiply(S); //System.out.println("rhs,2 = " + rhs); for (long i = 0; i <= d; i++) { lhs = Pp.subtract(r); //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); if (lhs.equals(rhs)) { //System.out.println("lhs,2 = " + lhs); return true; } Pp = Pp.multiply(ldcf); } return false; } /** * GenPolynomial divide. For recursive polynomials. Division by coefficient * ring element. * @param coefficient type. * @param P recursive GenPolynomial. * @param s GenPolynomial. * @return this/s. */ public static > GenPolynomial> recursiveDivide( GenPolynomial> P, GenPolynomial s) { if (s == null || s.isZERO()) { throw new ArithmeticException("division by zero " + P + ", " + s); } if (P.isZERO()) { return P; } if (s.isONE()) { return P; } GenPolynomial> p = P.ring.getZERO().copy(); SortedMap> pv = p.val; //getMap(); for (Map.Entry> m1 : P.getMap().entrySet()) { GenPolynomial c1 = m1.getValue(); ExpVector e1 = m1.getKey(); GenPolynomial c = PolyUtil. basePseudoDivide(c1, s); if (!c.isZERO()) { pv.put(e1, c); // or m1.setValue( c ) } else { System.out.println("pu, c1 = " + c1); System.out.println("pu, s = " + s); System.out.println("pu, c = " + c); throw new RuntimeException("something is wrong"); } } return p; } /** * GenPolynomial base divide. For recursive polynomials. Division by * coefficient ring element. * @param coefficient type. * @param P recursive GenPolynomial. * @param s coefficient. * @return this/s. */ public static > GenPolynomial> baseRecursiveDivide( GenPolynomial> P, C s) { if (s == null || s.isZERO()) { throw new ArithmeticException("division by zero " + P + ", " + s); } if (P.isZERO()) { return P; } if (s.isONE()) { return P; } GenPolynomial> p = P.ring.getZERO().copy(); SortedMap> pv = p.val; //getMap(); for (Map.Entry> m1 : P.getMap().entrySet()) { GenPolynomial c1 = m1.getValue(); ExpVector e1 = m1.getKey(); GenPolynomial c = PolyUtil. coefficientBasePseudoDivide(c1, s); if (!c.isZERO()) { pv.put(e1, c); // or m1.setValue( c ) } else { System.out.println("pu, c1 = " + c1); System.out.println("pu, s = " + s); System.out.println("pu, c = " + c); throw new RuntimeException("something is wrong"); } } return p; } /** * GenPolynomial sparse pseudo remainder. For recursive polynomials. * @param coefficient type. * @param P recursive GenPolynomial. * @param S nonzero recursive GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). * @deprecated Use * {@link #recursiveSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)} * instead */ @Deprecated public static > GenPolynomial> recursivePseudoRemainder( GenPolynomial> P, GenPolynomial> S) { return recursiveSparsePseudoRemainder(P, S); } /** * GenPolynomial sparse pseudo remainder. For recursive polynomials. * @param coefficient type. * @param P recursive GenPolynomial. * @param S nonzero recursive GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial> recursiveSparsePseudoRemainder( GenPolynomial> P, GenPolynomial> S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P + " division by zero " + S); } if (P == null || P.isZERO()) { return P; } if (S.isONE()) { return P.ring.getZERO(); } GenPolynomial c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial> h; GenPolynomial> r = P; while (!r.isZERO()) { ExpVector f = r.leadingExpVector(); if (f.multipleOf(e)) { GenPolynomial a = r.leadingBaseCoefficient(); f = f.subtract(e); GenPolynomial x = c; //test basePseudoRemainder(a,c); if (x.isZERO()) { GenPolynomial y = PolyUtil. basePseudoDivide(a, c); h = S.multiply(y, f); // coeff a } else { r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac } r = r.subtract(h); } else { break; } } return r; } /** * GenPolynomial dense pseudo remainder. For recursive polynomials. * @param P recursive GenPolynomial. * @param S nonzero recursive GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial> recursiveDensePseudoRemainder( GenPolynomial> P, GenPolynomial> S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P + " division by zero " + S); } if (P == null || P.isZERO()) { return P; } if (S.degree() <= 0) { return P.ring.getZERO(); } long m = P.degree(0); long n = S.degree(0); GenPolynomial c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial> h; GenPolynomial> r = P; for (long i = m; i >= n; i--) { if (r.isZERO()) { return r; } long k = r.degree(0); if (i == k) { ExpVector f = r.leadingExpVector(); GenPolynomial a = r.leadingBaseCoefficient(); f = f.subtract(e); //EVDIF( f, e ); //System.out.println("red div = " + f); r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac r = r.subtract(h); } else { r = r.multiply(c); } } return r; } /** * GenPolynomial recursive pseudo divide. For recursive polynomials. * @param coefficient type. * @param P recursive GenPolynomial. * @param S nonzero recursive GenPolynomial. * @return quotient with ldcf(S)m' P = quotient * S + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial> recursivePseudoDivide( GenPolynomial> P, GenPolynomial> S) { if (S == null || S.isZERO()) { throw new ArithmeticException(P + " division by zero " + S); } //if (S.ring.nvar != 1) { // ok if exact division // throw new RuntimeException(this.getClass().getName() // + " univariate polynomials only"); //} if (P == null || P.isZERO()) { return P; } if (S.isONE()) { return P; } GenPolynomial c = S.leadingBaseCoefficient(); ExpVector e = S.leadingExpVector(); GenPolynomial> h; GenPolynomial> r = P; GenPolynomial> q = S.ring.getZERO().copy(); while (!r.isZERO()) { ExpVector f = r.leadingExpVector(); if (f.multipleOf(e)) { GenPolynomial a = r.leadingBaseCoefficient(); f = f.subtract(e); GenPolynomial x = PolyUtil. baseSparsePseudoRemainder(a, c); if (x.isZERO() && !c.isConstant()) { GenPolynomial y = PolyUtil. basePseudoDivide(a, c); q = q.sum(y, f); h = S.multiply(y, f); // coeff a } else { q = q.multiply(c); q = q.sum(a, f); r = r.multiply(c); // coeff ac h = S.multiply(a, f); // coeff ac } r = r.subtract(h); } else { break; } } return q; } /** * Is GenPolynomial pseudo quotient and remainder. For recursive * polynomials. * @param coefficient type. * @param P recursive GenPolynomial. * @param S nonzero recursive GenPolynomial. * @return remainder with ldcf(S)m' P = quotient * S + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). * Note: not always meaningful and working */ public static > boolean isRecursivePseudoQuotientRemainder( GenPolynomial> P, GenPolynomial> S, GenPolynomial> q, GenPolynomial> r) { GenPolynomial> rhs = q.multiply(S).sum(r); GenPolynomial> lhs = P; GenPolynomial ldcf = S.leadingBaseCoefficient(); long d = P.degree(0) - S.degree(0) + 1; d = (d > 0 ? d : -d + 2); for (long i = 0; i <= d; i++) { //System.out.println("lhs = " + lhs); //System.out.println("rhs = " + rhs); //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); if (lhs.equals(rhs)) { return true; } lhs = lhs.multiply(ldcf); } GenPolynomial> Pp = P; rhs = q.multiply(S); //System.out.println("rhs,2 = " + rhs); for (long i = 0; i <= d; i++) { lhs = Pp.subtract(r); //System.out.println("lhs-rhs = " + lhs.subtract(rhs)); if (lhs.equals(rhs)) { //System.out.println("lhs,2 = " + lhs); return true; } Pp = Pp.multiply(ldcf); } return false; } /** * GenPolynomial pseudo divide. For recursive polynomials. * @param coefficient type. * @param P recursive GenPolynomial. * @param s nonzero GenPolynomial. * @return quotient with ldcf(s)m P = quotient * s + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial> coefficientPseudoDivide( GenPolynomial> P, GenPolynomial s) { if (s == null || s.isZERO()) { throw new ArithmeticException(P + " division by zero " + s); } if (P.isZERO()) { return P; } GenPolynomial> p = P.ring.getZERO().copy(); SortedMap> pv = p.val; for (Map.Entry> m : P.getMap().entrySet()) { ExpVector e = m.getKey(); GenPolynomial c1 = m.getValue(); GenPolynomial c = basePseudoDivide(c1, s); if (debug) { GenPolynomial x = c1.remainder(s); if (!x.isZERO()) { logger.info("divide x = " + x); throw new ArithmeticException(" no exact division: " + c1 + "/" + s); } } if (c.isZERO()) { System.out.println(" no exact division: " + c1 + "/" + s); //throw new ArithmeticException(" no exact division: " + c1 + "/" + s); } else { pv.put(e, c); // or m1.setValue( c ) } } return p; } /** * GenPolynomial pseudo divide. For polynomials. * @param coefficient type. * @param P GenPolynomial. * @param s nonzero coefficient. * @return quotient with ldcf(s)m P = quotient * s + remainder. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial). */ public static > GenPolynomial coefficientBasePseudoDivide(GenPolynomial P, C s) { if (s == null || s.isZERO()) { throw new ArithmeticException(P + " division by zero " + s); } if (P.isZERO()) { return P; } GenPolynomial p = P.ring.getZERO().copy(); SortedMap pv = p.val; for (Map.Entry m : P.getMap().entrySet()) { ExpVector e = m.getKey(); C c1 = m.getValue(); C c = c1.divide(s); if (debug) { C x = c1.remainder(s); if (!x.isZERO()) { logger.info("divide x = " + x); throw new ArithmeticException(" no exact division: " + c1 + "/" + s); } } if (c.isZERO()) { System.out.println(" no exact division: " + c1 + "/" + s); //throw new ArithmeticException(" no exact division: " + c1 + "/" + s); } else { pv.put(e, c); // or m1.setValue( c ) } } return p; } /** * GenPolynomial polynomial derivative main variable. * @param coefficient type. * @param P GenPolynomial. * @return deriviative(P). */ public static > GenPolynomial baseDeriviative(GenPolynomial P) { if (P == null || P.isZERO()) { return P; } GenPolynomialRing pfac = P.ring; if (pfac.nvar > 1) { // baseContent not possible by return type throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); } RingFactory rf = pfac.coFac; GenPolynomial d = pfac.getZERO().copy(); Map dm = d.val; //getMap(); for (Map.Entry m : P.getMap().entrySet()) { ExpVector f = m.getKey(); long fl = f.getVal(0); if (fl > 0) { C cf = rf.fromInteger(fl); C a = m.getValue(); C x = a.multiply(cf); if (x != null && !x.isZERO()) { ExpVector e = ExpVector.create(1, 0, fl - 1L); dm.put(e, x); } } } return d; } /** * GenPolynomial polynomial partial derivative variable r. * @param coefficient type. * @param P GenPolynomial. * @param r variable for partial deriviate. * @return deriviative(P,r). */ public static > GenPolynomial baseDeriviative(GenPolynomial P, int r) { if (P == null || P.isZERO()) { return P; } GenPolynomialRing pfac = P.ring; if (r < 0 || pfac.nvar <= r) { throw new IllegalArgumentException(P.getClass().getName() + " deriviative variable out of bound " + r); } int rp = pfac.nvar - 1 - r; RingFactory rf = pfac.coFac; GenPolynomial d = pfac.getZERO().copy(); Map dm = d.val; //getMap(); for (Map.Entry m : P.getMap().entrySet()) { ExpVector f = m.getKey(); long fl = f.getVal(rp); if (fl > 0) { C cf = rf.fromInteger(fl); C a = m.getValue(); C x = a.multiply(cf); if (x != null && !x.isZERO()) { ExpVector e = f.subst(rp, fl - 1L); dm.put(e, x); } } } return d; } /** * GenPolynomial polynomial integral main variable. * @param coefficient type. * @param P GenPolynomial. * @return integral(P). */ public static > GenPolynomial baseIntegral(GenPolynomial P) { if (P == null || P.isZERO()) { return P; } GenPolynomialRing pfac = P.ring; if (pfac.nvar > 1) { // baseContent not possible by return type throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); } RingFactory rf = pfac.coFac; GenPolynomial d = pfac.getZERO().copy(); Map dm = d.val; //getMap(); for (Map.Entry m : P.getMap().entrySet()) { ExpVector f = m.getKey(); long fl = f.getVal(0); fl++; C cf = rf.fromInteger(fl); C a = m.getValue(); C x = a.divide(cf); if (x != null && !x.isZERO()) { ExpVector e = ExpVector.create(1, 0, fl); dm.put(e, x); } } return d; } /** * GenPolynomial recursive polynomial derivative main variable. * @param coefficient type. * @param P recursive GenPolynomial. * @return deriviative(P). */ public static > GenPolynomial> recursiveDeriviative( GenPolynomial> P) { if (P == null || P.isZERO()) { return P; } GenPolynomialRing> pfac = P.ring; if (pfac.nvar > 1) { // baseContent not possible by return type throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials"); } GenPolynomialRing pr = (GenPolynomialRing) pfac.coFac; RingFactory rf = pr.coFac; GenPolynomial> d = pfac.getZERO().copy(); Map> dm = d.val; //getMap(); for (Map.Entry> m : P.getMap().entrySet()) { ExpVector f = m.getKey(); long fl = f.getVal(0); if (fl > 0) { C cf = rf.fromInteger(fl); GenPolynomial a = m.getValue(); GenPolynomial x = a.multiply(cf); if (x != null && !x.isZERO()) { ExpVector e = ExpVector.create(1, 0, fl - 1L); dm.put(e, x); } } } return d; } /** * Factor coefficient bound. See SACIPOL.IPFCB: the product of all maxNorms * of potential factors is less than or equal to 2**b times the maxNorm of * A. * @param e degree vector of a GenPolynomial A. * @return 2**b. */ public static BigInteger factorBound(ExpVector e) { int n = 0; java.math.BigInteger p = java.math.BigInteger.ONE; java.math.BigInteger v; if (e == null || e.isZERO()) { return BigInteger.ONE; } for (int i = 0; i < e.length(); i++) { if (e.getVal(i) > 0) { n += (2 * e.getVal(i) - 1); v = new java.math.BigInteger("" + (e.getVal(i) - 1)); p = p.multiply(v); } } n += (p.bitCount() + 1); // log2(p) n /= 2; v = new java.math.BigInteger("" + 2); v = v.shiftLeft(n); BigInteger N = new BigInteger(v); return N; } /** * Evaluate at main variable. * @param coefficient type. * @param cfac coefficent polynomial ring factory. * @param A recursive polynomial to be evaluated. * @param a value to evaluate at. * @return A( x_1, ..., x_{n-1}, a ). */ public static > GenPolynomial evaluateMainRecursive(GenPolynomialRing cfac, GenPolynomial> A, C a) { if (A == null || A.isZERO()) { return cfac.getZERO(); } if (A.ring.nvar != 1) { // todo assert throw new IllegalArgumentException("evaluateMain no univariate polynomial"); } if (a == null || a.isZERO()) { return A.trailingBaseCoefficient(); } // assert descending exponents, i.e. compatible term order Map> val = A.getMap(); GenPolynomial B = null; long el1 = -1; // undefined long el2 = -1; for (Map.Entry> me : val.entrySet()) { ExpVector e = me.getKey(); el2 = e.getVal(0); if (B == null /*el1 < 0*/) { // first turn B = me.getValue(); //val.get(e); } else { for (long i = el2; i < el1; i++) { B = B.multiply(a); } B = B.sum(me.getValue()); //val.get(e)); } el1 = el2; } for (long i = 0; i < el2; i++) { B = B.multiply(a); } return B; } /** * Evaluate at main variable. * @param coefficient type. * @param cfac coefficent polynomial ring factory. * @param A distributed polynomial to be evaluated. * @param a value to evaluate at. * @return A( x_1, ..., x_{n-1}, a ). */ public static > GenPolynomial evaluateMain(GenPolynomialRing cfac, GenPolynomial A, C a) { if (A == null || A.isZERO()) { return cfac.getZERO(); } GenPolynomialRing> rfac = new GenPolynomialRing>(cfac, 1); if (rfac.nvar + cfac.nvar != A.ring.nvar) { throw new IllegalArgumentException("evaluateMain number of variabes mismatch"); } GenPolynomial> Ap = recursive(rfac, A); return PolyUtil. evaluateMainRecursive(cfac, Ap, a); } /** * Evaluate at main variable. * @param coefficient type. * @param cfac coefficent ring factory. * @param L list of univariate polynomials to be evaluated. * @param a value to evaluate at. * @return list( A( x_1, ..., x_{n-1}, a ) ) for A in L. */ public static > List> evaluateMain(GenPolynomialRing cfac, List> L, C a) { return ListUtil., GenPolynomial> map(L, new EvalMainPol(cfac, a)); } /** * Evaluate at main variable. * @param coefficient type. * @param cfac coefficent ring factory. * @param A univariate polynomial to be evaluated. * @param a value to evaluate at. * @return A( a ). */ public static > C evaluateMain(RingFactory cfac, GenPolynomial A, C a) { if (A == null || A.isZERO()) { return cfac.getZERO(); } if (A.ring.nvar != 1) { // todo assert throw new IllegalArgumentException("evaluateMain no univariate polynomial"); } if (a == null || a.isZERO()) { return A.trailingBaseCoefficient(); } // assert decreasing exponents, i.e. compatible term order Map val = A.getMap(); C B = null; long el1 = -1; // undefined long el2 = -1; for (Map.Entry me : val.entrySet()) { ExpVector e = me.getKey(); el2 = e.getVal(0); if (B == null /*el1 < 0*/) { // first turn B = me.getValue(); // val.get(e); } else { for (long i = el2; i < el1; i++) { B = B.multiply(a); } B = B.sum(me.getValue()); //val.get(e)); } el1 = el2; } for (long i = 0; i < el2; i++) { B = B.multiply(a); } return B; } /** * Evaluate at main variable. * @param coefficient type. * @param cfac coefficent ring factory. * @param L list of univariate polynomial to be evaluated. * @param a value to evaluate at. * @return list( A( a ) ) for A in L. */ public static > List evaluateMain(RingFactory cfac, List> L, C a) { return ListUtil., C> map(L, new EvalMain(cfac, a)); } /** * Evaluate at k-th variable. * @param coefficient type. * @param cfac coefficient polynomial ring in k variables C[x_1, ..., x_k] * factory. * @param rfac coefficient polynomial ring C[x_1, ..., x_{k-1}] [x_k] * factory, a recursive polynomial ring in 1 variable with * coefficients in k-1 variables. * @param nfac polynomial ring in n-1 varaibles C[x_1, ..., x_{k-1}] * [x_{k+1}, ..., x_n] factory, a recursive polynomial ring in * n-k+1 variables with coefficients in k-1 variables. * @param dfac polynomial ring in n-1 variables. C[x_1, ..., x_{k-1}, * x_{k+1}, ..., x_n] factory. * @param A polynomial to be evaluated. * @param a value to evaluate at. * @return A( x_1, ..., x_{k-1}, a, x_{k+1}, ..., x_n). */ public static > GenPolynomial evaluate(GenPolynomialRing cfac, GenPolynomialRing> rfac, GenPolynomialRing> nfac, GenPolynomialRing dfac, GenPolynomial A, C a) { if (rfac.nvar != 1) { // todo assert throw new IllegalArgumentException("evaluate coefficient ring not univariate"); } if (A == null || A.isZERO()) { return cfac.getZERO(); } Map> Ap = A.contract(cfac); GenPolynomialRing rcf = (GenPolynomialRing) rfac.coFac; GenPolynomial> Ev = nfac.getZERO().copy(); Map> Evm = Ev.val; //getMap(); for (Map.Entry> m : Ap.entrySet()) { ExpVector e = m.getKey(); GenPolynomial b = m.getValue(); GenPolynomial> c = recursive(rfac, b); GenPolynomial d = evaluateMainRecursive(rcf, c, a); if (d != null && !d.isZERO()) { Evm.put(e, d); } } GenPolynomial B = distribute(dfac, Ev); return B; } /** * Evaluate at first (lowest) variable. * @param coefficient type. * @param cfac coefficient polynomial ring in first variable C[x_1] factory. * @param dfac polynomial ring in n-1 variables. C[x_2, ..., x_n] factory. * @param A polynomial to be evaluated. * @param a value to evaluate at. * @return A( a, x_2, ..., x_n). */ public static > GenPolynomial evaluateFirst(GenPolynomialRing cfac, GenPolynomialRing dfac, GenPolynomial A, C a) { if (A == null || A.isZERO()) { return dfac.getZERO(); } Map> Ap = A.contract(cfac); //RingFactory rcf = cfac.coFac; // == dfac.coFac GenPolynomial B = dfac.getZERO().copy(); Map Bm = B.val; //getMap(); for (Map.Entry> m : Ap.entrySet()) { ExpVector e = m.getKey(); GenPolynomial b = m.getValue(); C d = evaluateMain(cfac.coFac, b, a); if (d != null && !d.isZERO()) { Bm.put(e, d); } } return B; } /** * Evaluate at first (lowest) variable. * @param coefficient type. Could also be called evaluateFirst(), but * type erasure of A parameter does not allow same name. * @param cfac coefficient polynomial ring in first variable C[x_1] factory. * @param dfac polynomial ring in n-1 variables. C[x_2, ..., x_n] factory. * @param A recursive polynomial to be evaluated. * @param a value to evaluate at. * @return A( a, x_2, ..., x_n). */ public static > GenPolynomial evaluateFirstRec(GenPolynomialRing cfac, GenPolynomialRing dfac, GenPolynomial> A, C a) { if (A == null || A.isZERO()) { return dfac.getZERO(); } Map> Ap = A.getMap(); GenPolynomial B = dfac.getZERO().copy(); Map Bm = B.val; //getMap(); for (Map.Entry> m : Ap.entrySet()) { ExpVector e = m.getKey(); GenPolynomial b = m.getValue(); C d = evaluateMain(cfac.coFac, b, a); if (d != null && !d.isZERO()) { Bm.put(e, d); } } return B; } /** * Evaluate all variables. * @param coefficient type. * @param cfac coefficient ring factory. * @param dfac polynomial ring in n variables. C[x_1, x_2, ..., x_n] * factory. * @param A polynomial to be evaluated. * @param a = (a_1, a_2, ..., a_n) a tuple of values to evaluate at. * @return A(a_1, a_2, ..., a_n). * @deprecated use evaluateAll() with three arguments */ @Deprecated public static > C evaluateAll(RingFactory cfac, GenPolynomialRing dfac, GenPolynomial A, List a) { return evaluateAll(cfac,A,a); } /** * Evaluate all variables. * @param coefficient type. * @param cfac coefficient ring factory. * @param A polynomial to be evaluated. * @param a = (a_1, a_2, ..., a_n) a tuple of values to evaluate at. * @return A(a_1, a_2, ..., a_n). */ public static > C evaluateAll(RingFactory cfac, GenPolynomial A, List a) { if (A == null || A.isZERO()) { return cfac.getZERO(); } GenPolynomialRing dfac = A.ring; if (a == null || a.size() != dfac.nvar) { throw new IllegalArgumentException("evaluate tuple size not equal to number of variables"); } if (dfac.nvar == 0) { return A.trailingBaseCoefficient(); } if (dfac.nvar == 1) { return evaluateMain(cfac, A, a.get(0)); } C b = cfac.getZERO(); GenPolynomial Ap = A; for (int k = 0; k < dfac.nvar - 1; k++) { C ap = a.get(k); GenPolynomialRing c1fac = new GenPolynomialRing(cfac, 1); GenPolynomialRing cnfac = new GenPolynomialRing(cfac, dfac.nvar - 1 - k); GenPolynomial Bp = evaluateFirst(c1fac, cnfac, Ap, ap); if (Bp.isZERO()) { return b; } Ap = Bp; //System.out.println("Ap = " + Ap); } C ap = a.get(dfac.nvar - 1); b = evaluateMain(cfac, Ap, ap); return b; } /** * Substitute main variable. * @param A univariate polynomial. * @param s polynomial for substitution. * @return polynomial A(x <- s). */ public static > GenPolynomial substituteMain(GenPolynomial A, GenPolynomial s) { return substituteUnivariate(A, s); } /** * Substitute univariate polynomial. * @param f univariate polynomial. * @param t polynomial for substitution. * @return polynomial A(x <- t). */ public static > GenPolynomial substituteUnivariate(GenPolynomial f, GenPolynomial t) { if (f == null || t == null) { return null; } GenPolynomialRing fac = f.ring; if (fac.nvar > 1) { throw new IllegalArgumentException("only for univariate polynomial f"); } if (f.isZERO() || f.isConstant()) { return f; } if (t.ring.nvar > 1) { fac = t.ring; } // assert decending exponents, i.e. compatible term order Map val = f.getMap(); GenPolynomial s = null; long el1 = -1; // undefined long el2 = -1; for (Map.Entry me : val.entrySet()) { ExpVector e = me.getKey(); el2 = e.getVal(0); if (s == null /*el1 < 0*/) { // first turn s = fac.getZERO().sum(me.getValue()); //val.get(e)); } else { for (long i = el2; i < el1; i++) { s = s.multiply(t); } s = s.sum(me.getValue()); //val.get(e)); } el1 = el2; } for (long i = 0; i < el2; i++) { s = s.multiply(t); } //System.out.println("s = " + s); return s; } /** * Taylor series for polynomial. * @param f univariate polynomial. * @param a expansion point. * @return Taylor series (a polynomial) of f at a. */ public static > GenPolynomial seriesOfTaylor(GenPolynomial f, C a) { if (f == null) { return null; } GenPolynomialRing fac = f.ring; if (fac.nvar > 1) { throw new IllegalArgumentException("only for univariate polynomials"); } if (f.isZERO() || f.isConstant()) { return f; } GenPolynomial s = fac.getZERO(); C fa = PolyUtil. evaluateMain(fac.coFac, f, a); s = s.sum(fa); long n = 1; long i = 0; GenPolynomial g = PolyUtil. baseDeriviative(f); //GenPolynomial p = fac.getONE(); while (!g.isZERO()) { i++; n *= i; fa = PolyUtil. evaluateMain(fac.coFac, g, a); GenPolynomial q = fac.univariate(0, i); //p; q = q.multiply(fa); q = q.divide(fac.fromInteger(n)); s = s.sum(q); g = PolyUtil. baseDeriviative(g); } //System.out.println("s = " + s); return s; } /** * ModInteger interpolate on first variable. * @param coefficient type. * @param fac GenPolynomial result factory. * @param A GenPolynomial. * @param M GenPolynomial interpolation modul of A. * @param mi inverse of M(am) in ring fac.coFac. * @param B evaluation of other GenPolynomial. * @param am evaluation point (interpolation modul) of B, i.e. P(am) = B. * @return S, with S mod M == A and S(am) == B. */ public static > GenPolynomial> interpolate( GenPolynomialRing> fac, GenPolynomial> A, GenPolynomial M, C mi, GenPolynomial B, C am) { GenPolynomial> S = fac.getZERO().copy(); GenPolynomial> Ap = A.copy(); SortedMap> av = Ap.val; //getMap(); SortedMap bv = B.getMap(); SortedMap> sv = S.val; //getMap(); GenPolynomialRing cfac = (GenPolynomialRing) fac.coFac; RingFactory bfac = cfac.coFac; GenPolynomial c = null; for (Map.Entry me : bv.entrySet()) { ExpVector e = me.getKey(); C y = me.getValue(); //bv.get(e); // assert y != null GenPolynomial x = av.get(e); if (x != null) { av.remove(e); c = PolyUtil. interpolate(cfac, x, M, mi, y, am); if (!c.isZERO()) { // 0 cannot happen sv.put(e, c); } } else { c = PolyUtil. interpolate(cfac, cfac.getZERO(), M, mi, y, am); if (!c.isZERO()) { // 0 cannot happen sv.put(e, c); // c != null } } } // assert bv is empty = done for (Map.Entry> me : av.entrySet()) { // rest of av ExpVector e = me.getKey(); GenPolynomial x = me.getValue(); //av.get(e); // assert x != null c = PolyUtil. interpolate(cfac, x, M, mi, bfac.getZERO(), am); if (!c.isZERO()) { // 0 cannot happen sv.put(e, c); // c != null } } return S; } /** * Univariate polynomial interpolation. * @param coefficient type. * @param fac GenPolynomial result factory. * @param A GenPolynomial. * @param M GenPolynomial interpolation modul of A. * @param mi inverse of M(am) in ring fac.coFac. * @param a evaluation of other GenPolynomial. * @param am evaluation point (interpolation modul) of a, i.e. P(am) = a. * @return S, with S mod M == A and S(am) == a. */ public static > GenPolynomial interpolate(GenPolynomialRing fac, GenPolynomial A, GenPolynomial M, C mi, C a, C am) { GenPolynomial s; C b = PolyUtil. evaluateMain(fac.coFac, A, am); // A mod a.modul C d = a.subtract(b); // a-A mod a.modul if (d.isZERO()) { return A; } b = d.multiply(mi); // b = (a-A)*mi mod a.modul // (M*b)+A mod M = A mod M = // (M*mi*(a-A)+A) mod a.modul = a mod a.modul s = M.multiply(b); s = s.sum(A); return s; } /** * Recursive GenPolynomial switch varaible blocks. * @param coefficient type. * @param P recursive GenPolynomial in R[X,Y]. * @return this in R[Y,X]. */ public static > GenPolynomial> switchVariables( GenPolynomial> P) { if (P == null) { throw new IllegalArgumentException("P == null"); } GenPolynomialRing> rfac1 = P.ring; GenPolynomialRing cfac1 = (GenPolynomialRing) rfac1.coFac; GenPolynomialRing cfac2 = new GenPolynomialRing(cfac1.coFac, rfac1); GenPolynomial zero = cfac2.getZERO(); GenPolynomialRing> rfac2 = new GenPolynomialRing>(cfac2, cfac1); GenPolynomial> B = rfac2.getZERO().copy(); if (P.isZERO()) { return B; } for (Monomial> mr : P) { GenPolynomial cr = mr.c; for (Monomial mc : cr) { GenPolynomial c = zero.sum(mc.c, mr.e); B = B.sum(c, mc.e); } } return B; } /** * Maximal degree of leading terms of a polynomial list. * @return maximum degree of the leading terms of a polynomial list. */ public static > long totalDegreeLeadingTerm(List> P) { long degree = 0; for (GenPolynomial g : P) { long total = g.leadingExpVector().totalDeg(); if (degree < total) { degree = total; } } return degree; } /** * Maximal degree of polynomial list. * @return maximum degree of the polynomial list. */ public static > long totalDegree(List> P) { long degree = 0; for (GenPolynomial g : P) { long total = g.degree(); if (degree < total) { degree = total; } } return degree; } /** * Maximal degree in the coefficient polynomials. * @param coefficient type. * @return maximal degree in the coefficients. */ public static > long coeffMaxDegree(GenPolynomial> A) { if (A.isZERO()) { return 0; // 0 or -1 ?; } long deg = 0; for (GenPolynomial a : A.getMap().values()) { long d = a.degree(); if (d > deg) { deg = d; } } return deg; } /** * Map a unary function to the coefficients. * @param ring result polynomial ring factory. * @param p polynomial. * @param f evaluation functor. * @return new polynomial with coefficients f(p(e)). */ public static , D extends RingElem> GenPolynomial map( GenPolynomialRing ring, GenPolynomial p, UnaryFunctor f) { GenPolynomial n = ring.getZERO().copy(); SortedMap nv = n.val; for (Monomial m : p) { D c = f.eval(m.c); if (c != null && !c.isZERO()) { nv.put(m.e, c); } } return n; } /** * Product representation. * @param coefficient type. * @param pfac polynomial ring factory. * @param L list of polynomials to be represented. * @return Product represenation of L in the polynomial ring pfac. */ public static > List>> toProductGen( GenPolynomialRing> pfac, List> L) { List>> list = new ArrayList>>(); if (L == null || L.size() == 0) { return list; } for (GenPolynomial a : L) { GenPolynomial> b = toProductGen(pfac, a); list.add(b); } return list; } /** * Product representation. * @param coefficient type. * @param pfac polynomial ring factory. * @param A polynomial to be represented. * @return Product represenation of A in the polynomial ring pfac. */ public static > GenPolynomial> toProductGen( GenPolynomialRing> pfac, GenPolynomial A) { GenPolynomial> P = pfac.getZERO().copy(); if (A == null || A.isZERO()) { return P; } RingFactory> rpfac = pfac.coFac; ProductRing rfac = (ProductRing) rpfac; for (Map.Entry y : A.getMap().entrySet()) { ExpVector e = y.getKey(); C a = y.getValue(); Product p = toProductGen(rfac, a); if (!p.isZERO()) { P.doPutToMap(e, p); } } return P; } /** * Product representation. * @param coefficient type. * @param pfac product ring factory. * @param c coefficient to be represented. * @return Product represenation of c in the ring pfac. */ public static > Product toProductGen(ProductRing pfac, C c) { SortedMap elem = new TreeMap(); for (int i = 0; i < pfac.length(); i++) { RingFactory rfac = pfac.getFactory(i); C u = rfac.copy(c); if (u != null && !u.isZERO()) { elem.put(i, u); } } return new Product(pfac, elem); } /** * Product representation. * @param coefficient type. * @param pfac product polynomial ring factory. * @param c coefficient to be used. * @param e exponent vector. * @return Product represenation of c X^e in the ring pfac. */ public static > Product> toProduct( ProductRing> pfac, C c, ExpVector e) { SortedMap> elem = new TreeMap>(); for (int i = 0; i < e.length(); i++) { RingFactory> rfac = pfac.getFactory(i); GenPolynomialRing fac = (GenPolynomialRing) rfac; //GenPolynomialRing cfac = fac.ring; long a = e.getVal(i); GenPolynomial u; if (a == 0) { u = fac.getONE(); } else { u = fac.univariate(0, a); } u = u.multiply(c); elem.put(i, u); } return new Product>(pfac, elem); } /** * Product representation. * @param coefficient type. * @param pfac product polynomial ring factory. * @param A polynomial. * @return Product represenation of the terms of A in the ring pfac. */ public static > Product> toProduct( ProductRing> pfac, GenPolynomial A) { Product> P = pfac.getZERO(); if (A == null || A.isZERO()) { return P; } for (Map.Entry y : A.getMap().entrySet()) { ExpVector e = y.getKey(); C a = y.getValue(); Product> p = toProduct(pfac, a, e); P = P.sum(p); } return P; } /** * Product representation. * @param pfac product ring factory. * @param c coefficient to be represented. * @return Product represenation of c in the ring pfac. */ public static Product toProduct(ProductRing pfac, BigInteger c) { SortedMap elem = new TreeMap(); for (int i = 0; i < pfac.length(); i++) { RingFactory rfac = pfac.getFactory(i); ModIntegerRing fac = (ModIntegerRing) rfac; ModInteger u = fac.fromInteger(c.getVal()); if (!u.isZERO()) { elem.put(i, u); } } return new Product(pfac, elem); } /** * Product representation. * @param pfac polynomial ring factory. * @param A polynomial to be represented. * @return Product represenation of A in the polynomial ring pfac. */ public static GenPolynomial> toProduct(GenPolynomialRing> pfac, GenPolynomial A) { GenPolynomial> P = pfac.getZERO().copy(); if (A == null || A.isZERO()) { return P; } RingFactory> rpfac = pfac.coFac; ProductRing fac = (ProductRing) rpfac; for (Map.Entry y : A.getMap().entrySet()) { ExpVector e = y.getKey(); BigInteger a = y.getValue(); Product p = toProduct(fac, a); if (!p.isZERO()) { P.doPutToMap(e, p); } } return P; } /** * Product representation. * @param pfac polynomial ring factory. * @param L list of polynomials to be represented. * @return Product represenation of L in the polynomial ring pfac. */ public static List>> toProduct( GenPolynomialRing> pfac, List> L) { List>> list = new ArrayList>>(); if (L == null || L.size() == 0) { return list; } for (GenPolynomial a : L) { GenPolynomial> b = toProduct(pfac, a); list.add(b); } return list; } /** * Remove all upper variables which do not occur in polynomial. * @param p polynomial. * @return polynomial with removed variables */ public static > GenPolynomial removeUnusedUpperVariables(GenPolynomial p) { GenPolynomialRing fac = p.ring; if (fac.nvar <= 1) { // univariate return p; } int[] dep = p.degreeVector().dependencyOnVariables(); if (fac.nvar == dep.length) { // all variables appear return p; } if (dep.length == 0) { // no variables GenPolynomialRing fac0 = new GenPolynomialRing(fac.coFac, 0); GenPolynomial p0 = new GenPolynomial(fac0, p.leadingBaseCoefficient()); return p0; } int l = dep[0]; // higher variable int r = dep[dep.length - 1]; // lower variable if (l == 0 /*|| l == fac.nvar-1*/) { // upper variable appears return p; } int n = l; GenPolynomialRing facr = fac.contract(n); Map> mpr = p.contract(facr); if (mpr.size() != 1) { System.out.println("upper ex, l = " + l + ", r = " + r + ", p = " + p + ", fac = " + fac.toScript()); throw new RuntimeException("this should not happen " + mpr); } GenPolynomial pr = mpr.values().iterator().next(); n = fac.nvar - 1 - r; if (n == 0) { return pr; } // else case not implemented return pr; } /** * Remove all lower variables which do not occur in polynomial. * @param p polynomial. * @return polynomial with removed variables */ public static > GenPolynomial removeUnusedLowerVariables(GenPolynomial p) { GenPolynomialRing fac = p.ring; if (fac.nvar <= 1) { // univariate return p; } int[] dep = p.degreeVector().dependencyOnVariables(); if (fac.nvar == dep.length) { // all variables appear return p; } if (dep.length == 0) { // no variables GenPolynomialRing fac0 = new GenPolynomialRing(fac.coFac, 0); GenPolynomial p0 = new GenPolynomial(fac0, p.leadingBaseCoefficient()); return p0; } int l = dep[0]; // higher variable int r = dep[dep.length - 1]; // lower variable if (r == fac.nvar - 1) { // lower variable appears return p; } int n = r + 1; GenPolynomialRing> rfac = fac.recursive(n); GenPolynomial> mpr = recursive(rfac, p); if (mpr.length() != p.length()) { System.out.println("lower ex, l = " + l + ", r = " + r + ", p = " + p + ", fac = " + fac.toScript()); throw new RuntimeException("this should not happen " + mpr); } RingFactory cf = fac.coFac; GenPolynomialRing facl = new GenPolynomialRing(cf, rfac); GenPolynomial pr = facl.getZERO().copy(); for (Monomial> m : mpr) { ExpVector e = m.e; GenPolynomial a = m.c; if (!a.isConstant()) { throw new RuntimeException("this can not happen " + a); } C c = a.leadingBaseCoefficient(); pr.doPutToMap(e, c); } return pr; } /** * Remove upper block of middle variables which do not occur in polynomial. * @param p polynomial. * @return polynomial with removed variables */ public static > GenPolynomial removeUnusedMiddleVariables(GenPolynomial p) { GenPolynomialRing fac = p.ring; if (fac.nvar <= 2) { // univariate or bi-variate return p; } int[] dep = p.degreeVector().dependencyOnVariables(); if (fac.nvar == dep.length) { // all variables appear return p; } if (dep.length == 0) { // no variables GenPolynomialRing fac0 = new GenPolynomialRing(fac.coFac, 0); GenPolynomial p0 = new GenPolynomial(fac0, p.leadingBaseCoefficient()); return p0; } ExpVector e1 = p.leadingExpVector(); if (dep.length == 1) { // one variable TermOrder to = new TermOrder(fac.tord.getEvord()); int i = dep[0]; String v1 = e1.indexVarName(i, fac.getVars()); String[] vars = new String[] { v1 }; GenPolynomialRing fac1 = new GenPolynomialRing(fac.coFac, to, vars); GenPolynomial p1 = fac1.getZERO().copy(); for (Monomial m : p) { ExpVector e = m.e; ExpVector f = ExpVector.create(1, 0, e.getVal(i)); p1.doPutToMap(f, m.c); } return p1; } GenPolynomialRing> rfac = fac.recursive(1); GenPolynomial> mpr = recursive(rfac, p); int l = dep[0]; // higher variable int r = fac.nvar - dep[1]; // next variable //System.out.println("l = " + l); //System.out.println("r = " + r); TermOrder to = new TermOrder(fac.tord.getEvord()); String[] vs = fac.getVars(); String[] vars = new String[r + 1]; for (int i = 0; i < r; i++) { vars[i] = vs[i]; } vars[r] = e1.indexVarName(l, vs); //System.out.println("fac = " + fac); GenPolynomialRing dfac = new GenPolynomialRing(fac.coFac, to, vars); //System.out.println("dfac = " + dfac); GenPolynomialRing> fac2 = dfac.recursive(1); GenPolynomialRing cfac = (GenPolynomialRing) fac2.coFac; GenPolynomial> p2r = fac2.getZERO().copy(); for (Monomial> m : mpr) { ExpVector e = m.e; GenPolynomial a = m.c; Map> cc = a.contract(cfac); for (Map.Entry> me : cc.entrySet()) { ExpVector f = me.getKey(); if (f.isZERO()) { GenPolynomial c = me.getValue(); //cc.get(f); p2r.doPutToMap(e, c); } else { throw new RuntimeException("this should not happen " + cc); } } } GenPolynomial p2 = distribute(dfac, p2r); return p2; } /** * Select polynomial with univariate leading term in variable i. * @param i variable index. * @return polynomial with head term in variable i */ public static > GenPolynomial selectWithVariable(List> P, int i) { for (GenPolynomial p : P) { int[] dep = p.leadingExpVector().dependencyOnVariables(); if (dep.length == 1 && dep[0] == i) { return p; } } return null; // not found } } /** * Conversion of distributive to recursive representation. */ class DistToRec> implements UnaryFunctor, GenPolynomial>> { GenPolynomialRing> fac; public DistToRec(GenPolynomialRing> fac) { this.fac = fac; } public GenPolynomial> eval(GenPolynomial c) { if (c == null) { return fac.getZERO(); } return PolyUtil. recursive(fac, c); } } /** * Conversion of recursive to distributive representation. */ class RecToDist> implements UnaryFunctor>, GenPolynomial> { GenPolynomialRing fac; public RecToDist(GenPolynomialRing fac) { this.fac = fac; } public GenPolynomial eval(GenPolynomial> c) { if (c == null) { return fac.getZERO(); } return PolyUtil. distribute(fac, c); } } /** * BigRational numerator functor. */ class RatNumer implements UnaryFunctor { public BigInteger eval(BigRational c) { if (c == null) { return new BigInteger(); } return new BigInteger(c.numerator()); } } /** * Conversion of symmetric ModInteger to BigInteger functor. */ class ModSymToInt & Modular> implements UnaryFunctor { public BigInteger eval(C c) { if (c == null) { return new BigInteger(); } return c.getSymmetricInteger(); } } /** * Conversion of ModInteger to BigInteger functor. */ class ModToInt & Modular> implements UnaryFunctor { public BigInteger eval(C c) { if (c == null) { return new BigInteger(); } return c.getInteger(); } } /** * Conversion of BigRational to BigInteger with division by lcm functor. result * = num*(lcm/denom). */ class RatToInt implements UnaryFunctor { java.math.BigInteger lcm; public RatToInt(java.math.BigInteger lcm) { this.lcm = lcm; //.getVal(); } public BigInteger eval(BigRational c) { if (c == null) { return new BigInteger(); } // p = num*(lcm/denom) java.math.BigInteger b = lcm.divide(c.denominator()); return new BigInteger(c.numerator().multiply(b)); } } /** *  * Conversion of BigRational to BigInteger. result = (num/gcd)*(lcm/denom).   */ class RatToIntFactor implements UnaryFunctor { final java.math.BigInteger lcm; final java.math.BigInteger gcd; public RatToIntFactor(java.math.BigInteger gcd, java.math.BigInteger lcm) { this.gcd = gcd; this.lcm = lcm; // .getVal(); } public BigInteger eval(BigRational c) { if (c == null) { return new BigInteger(); } if (gcd.equals(java.math.BigInteger.ONE)) { // p = num*(lcm/denom) java.math.BigInteger b = lcm.divide(c.denominator()); return new BigInteger(c.numerator().multiply(b)); } // p = (num/gcd)*(lcm/denom) java.math.BigInteger a = c.numerator().divide(gcd); java.math.BigInteger b = lcm.divide(c.denominator()); return new BigInteger(a.multiply(b)); } } /** * Conversion of Rational to BigDecimal. result = decimal(r). */ class RatToDec & Rational> implements UnaryFunctor { public BigDecimal eval(C c) { if (c == null) { return new BigDecimal(); } return new BigDecimal(c.getRational()); } } /** * Conversion of Complex Rational to Complex BigDecimal. result = decimal(r). */ class CompRatToDec & Rational> implements UnaryFunctor, Complex> { ComplexRing ring; public CompRatToDec(RingFactory> ring) { this.ring = (ComplexRing) ring; } public Complex eval(Complex c) { if (c == null) { return ring.getZERO(); } BigDecimal r = new BigDecimal(c.getRe().getRational()); BigDecimal i = new BigDecimal(c.getIm().getRational()); return new Complex(ring, r, i); } } /** * Conversion from BigInteger functor. */ class FromInteger> implements UnaryFunctor { RingFactory ring; public FromInteger(RingFactory ring) { this.ring = ring; } public D eval(BigInteger c) { if (c == null) { return ring.getZERO(); } return ring.fromInteger(c.getVal()); } } /** * Conversion from GenPolynomial functor. */ class FromIntegerPoly> implements UnaryFunctor, GenPolynomial> { GenPolynomialRing ring; FromInteger fi; public FromIntegerPoly(GenPolynomialRing ring) { if (ring == null) { throw new IllegalArgumentException("ring must not be null"); } this.ring = ring; fi = new FromInteger(ring.coFac); } public GenPolynomial eval(GenPolynomial c) { if (c == null) { return ring.getZERO(); } return PolyUtil. map(ring, c, fi); } } /** * Conversion from GenPolynomial to GenPolynomial * functor. */ class RatToIntPoly implements UnaryFunctor, GenPolynomial> { GenPolynomialRing ring; public RatToIntPoly(GenPolynomialRing ring) { if (ring == null) { throw new IllegalArgumentException("ring must not be null"); } this.ring = ring; } public GenPolynomial eval(GenPolynomial c) { if (c == null) { return ring.getZERO(); } return PolyUtil.integerFromRationalCoefficients(ring, c); } } /** * Real part functor. */ class RealPart implements UnaryFunctor { public BigRational eval(BigComplex c) { if (c == null) { return new BigRational(); } return c.getRe(); } } /** * Imaginary part functor. */ class ImagPart implements UnaryFunctor { public BigRational eval(BigComplex c) { if (c == null) { return new BigRational(); } return c.getIm(); } } /** * Real part functor. */ class RealPartComplex> implements UnaryFunctor, C> { public C eval(Complex c) { if (c == null) { return null; } return c.getRe(); } } /** * Imaginary part functor. */ class ImagPartComplex> implements UnaryFunctor, C> { public C eval(Complex c) { if (c == null) { return null; } return c.getIm(); } } /** * Rational to complex functor. */ class ToComplex> implements UnaryFunctor> { final protected ComplexRing cfac; @SuppressWarnings("unchecked") public ToComplex(RingFactory> fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } cfac = (ComplexRing) fac; } public Complex eval(C c) { if (c == null) { return cfac.getZERO(); } return new Complex(cfac, c); } } /** * Rational to complex functor. */ class RatToCompl implements UnaryFunctor { public BigComplex eval(BigRational c) { if (c == null) { return new BigComplex(); } return new BigComplex(c); } } /** * Any ring element to generic complex functor. */ class AnyToComplex> implements UnaryFunctor> { final protected ComplexRing cfac; public AnyToComplex(ComplexRing fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } cfac = fac; } public AnyToComplex(RingFactory fac) { this(new ComplexRing(fac)); } public Complex eval(C a) { if (a == null || a.isZERO()) { // should not happen return cfac.getZERO(); } else if (a.isONE()) { return cfac.getONE(); } else { return new Complex(cfac, a); } } } /** * Algebraic to generic complex functor. */ class AlgebToCompl> implements UnaryFunctor, Complex> { final protected ComplexRing cfac; public AlgebToCompl(ComplexRing fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } cfac = fac; } public Complex eval(AlgebraicNumber a) { if (a == null || a.isZERO()) { // should not happen return cfac.getZERO(); } else if (a.isONE()) { return cfac.getONE(); } else { GenPolynomial p = a.getVal(); C real = cfac.ring.getZERO(); C imag = cfac.ring.getZERO(); for (Monomial m : p) { if (m.exponent().getVal(0) == 1L) { imag = m.coefficient(); } else if (m.exponent().getVal(0) == 0L) { real = m.coefficient(); } else { throw new IllegalArgumentException("unexpected monomial " + m); } } //Complex c = new Complex(cfac,real,imag); return new Complex(cfac, real, imag); } } } /** * Ceneric complex to algebraic number functor. */ class ComplToAlgeb> implements UnaryFunctor, AlgebraicNumber> { final protected AlgebraicNumberRing afac; final protected AlgebraicNumber I; public ComplToAlgeb(AlgebraicNumberRing fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } afac = fac; I = afac.getGenerator(); } public AlgebraicNumber eval(Complex c) { if (c == null || c.isZERO()) { // should not happen return afac.getZERO(); } else if (c.isONE()) { return afac.getONE(); } else if (c.isIMAG()) { return I; } else { return I.multiply(c.getIm()).sum(c.getRe()); } } } /** * Algebraic to polynomial functor. */ class AlgToPoly> implements UnaryFunctor, GenPolynomial> { public GenPolynomial eval(AlgebraicNumber c) { if (c == null) { return null; } return c.val; } } /** * Polynomial to algebriac functor. */ class PolyToAlg> implements UnaryFunctor, AlgebraicNumber> { final protected AlgebraicNumberRing afac; public PolyToAlg(AlgebraicNumberRing fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } afac = fac; } public AlgebraicNumber eval(GenPolynomial c) { if (c == null) { return afac.getZERO(); } return new AlgebraicNumber(afac, c); } } /** * Coefficient to algebriac functor. */ class CoeffToAlg> implements UnaryFunctor> { final protected AlgebraicNumberRing afac; final protected GenPolynomial zero; public CoeffToAlg(AlgebraicNumberRing fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } afac = fac; GenPolynomialRing pfac = afac.ring; zero = pfac.getZERO(); } public AlgebraicNumber eval(C c) { if (c == null) { return afac.getZERO(); } return new AlgebraicNumber(afac, zero.sum(c)); } } /** * Coefficient to recursive algebriac functor. */ class CoeffToRecAlg> implements UnaryFunctor> { final protected List> lfac; final int depth; @SuppressWarnings("unchecked") public CoeffToRecAlg(int depth, AlgebraicNumberRing fac) { if (fac == null) { throw new IllegalArgumentException("fac must not be null"); } AlgebraicNumberRing afac = fac; this.depth = depth; lfac = new ArrayList>(this.depth); lfac.add(fac); for (int i = 1; i < this.depth; i++) { RingFactory rf = afac.ring.coFac; if (!(rf instanceof AlgebraicNumberRing)) { throw new IllegalArgumentException("fac depth to low"); } afac = (AlgebraicNumberRing) (Object) rf; lfac.add(afac); } } @SuppressWarnings("unchecked") public AlgebraicNumber eval(C c) { if (c == null) { return lfac.get(0).getZERO(); } C ac = c; AlgebraicNumberRing af = lfac.get(lfac.size() - 1); GenPolynomial zero = af.ring.getZERO(); AlgebraicNumber an = new AlgebraicNumber(af, zero.sum(ac)); for (int i = lfac.size() - 2; i >= 0; i--) { af = lfac.get(i); zero = af.ring.getZERO(); ac = (C) (Object) an; an = new AlgebraicNumber(af, zero.sum(ac)); } return an; } } /** * Evaluate main variable functor. */ class EvalMain> implements UnaryFunctor, C> { final RingFactory cfac; final C a; public EvalMain(RingFactory cfac, C a) { this.cfac = cfac; this.a = a; } public C eval(GenPolynomial c) { if (c == null) { return cfac.getZERO(); } return PolyUtil. evaluateMain(cfac, c, a); } } /** * Evaluate main variable functor. */ class EvalMainPol> implements UnaryFunctor, GenPolynomial> { final GenPolynomialRing cfac; final C a; public EvalMainPol(GenPolynomialRing cfac, C a) { this.cfac = cfac; this.a = a; } public GenPolynomial eval(GenPolynomial c) { if (c == null) { return cfac.getZERO(); } return PolyUtil. evaluateMain(cfac, c, a); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy