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

edu.jas.ufd.GreatestCommonDivisorSubres Maven / Gradle / Ivy

The newest version!
/*
 * $Id: GreatestCommonDivisorSubres.java 4025 2012-07-23 16:41:43Z kredel $
 */

package edu.jas.ufd;


import org.apache.log4j.Logger;

import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.PolyUtil;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.Power;
import edu.jas.structure.RingElem;
import edu.jas.structure.RingFactory;


/**
 * Greatest common divisor algorithms with subresultant polynomial remainder
 * sequence.
 * @author Heinz Kredel
 */

public class GreatestCommonDivisorSubres> extends GreatestCommonDivisorAbstract {


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


    private boolean debug = logger.isDebugEnabled();


    /**
     * GenPolynomial pseudo remainder. For univariate polynomials.
     * @param P GenPolynomial.
     * @param S nonzero GenPolynomial.
     * @return remainder with ldcf(S)m P = quotient * S + remainder.
     * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
     * @deprecated Use {@link
     *             edu.jas.poly.PolyUtil#baseDensePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)}
     *             instead
     */
    @Deprecated
    public GenPolynomial basePseudoRemainder(GenPolynomial P, GenPolynomial S) {
        return PolyUtil. baseDensePseudoRemainder(P, S);
    }


    /**
     * GenPolynomial 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).
     * @deprecated Use {@link
     *             edu.jas.poly.PolyUtil#recursiveDensePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)} instead
     */
    @Deprecated
    public GenPolynomial> recursivePseudoRemainder(GenPolynomial> P,
                    GenPolynomial> S) {
        return PolyUtil. recursiveDensePseudoRemainder(P, S);
    }


    /**
     * Univariate GenPolynomial greatest comon divisor. Uses pseudoRemainder for
     * remainder.
     * @param P univariate GenPolynomial.
     * @param S univariate GenPolynomial.
     * @return gcd(P,S).
     */
    @Override
    public GenPolynomial baseGcd(GenPolynomial P, GenPolynomial S) {
        if (S == null || S.isZERO()) {
            return P;
        }
        if (P == null || P.isZERO()) {
            return S;
        }
        if (P.ring.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial");
        }
        long e = P.degree(0);
        long f = S.degree(0);
        GenPolynomial q;
        GenPolynomial r;
        if (f > e) {
            r = P;
            q = S;
            long g = f;
            f = e;
            e = g;
        } else {
            q = P;
            r = S;
        }
        if (debug) {
            logger.debug("degrees: e = " + e + ", f = " + f);
        }
        r = r.abs();
        q = q.abs();
        C a = baseContent(r);
        C b = baseContent(q);
        C c = gcd(a, b); // indirection
        r = divide(r, a); // indirection
        q = divide(q, b); // indirection
        if (r.isONE()) {
            return r.multiply(c);
        }
        if (q.isONE()) {
            return q.multiply(c);
        }
        C g = r.ring.getONECoefficient();
        C h = r.ring.getONECoefficient();
        GenPolynomial x;
        C z;
        while (!r.isZERO()) {
            long delta = q.degree(0) - r.degree(0);
            //System.out.println("delta    = " + delta);
            x = PolyUtil. baseDensePseudoRemainder(q, r);
            q = r;
            if (!x.isZERO()) {
                z = g.multiply(power(P.ring.coFac, h, delta));
                //System.out.println("z  = " + z);
                r = x.divide(z);
                g = q.leadingBaseCoefficient();
                z = power(P.ring.coFac, g, delta);
                h = z.divide(power(P.ring.coFac, h, delta - 1));
                //System.out.println("g  = " + g);
                //System.out.println("h  = " + h);
            } else {
                r = x;
            }
        }
        q = basePrimitivePart(q);
        return (q.multiply(c)).abs();
    }


    /**
     * Univariate GenPolynomial recursive greatest comon divisor. Uses
     * pseudoRemainder for remainder.
     * @param P univariate recursive GenPolynomial.
     * @param S univariate recursive GenPolynomial.
     * @return gcd(P,S).
     */
    @Override
    public GenPolynomial> recursiveUnivariateGcd(GenPolynomial> P,
                    GenPolynomial> S) {
        if (S == null || S.isZERO()) {
            return P;
        }
        if (P == null || P.isZERO()) {
            return S;
        }
        if (P.ring.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial");
        }
        long e = P.degree(0);
        long f = S.degree(0);
        GenPolynomial> q;
        GenPolynomial> r;
        if (f > e) {
            r = P;
            q = S;
            long g = f;
            f = e;
            e = g;
        } else {
            q = P;
            r = S;
        }
        if (debug) {
            logger.debug("degrees: e = " + e + ", f = " + f);
        }
        r = r.abs();
        q = q.abs();
        GenPolynomial a = recursiveContent(r);
        GenPolynomial b = recursiveContent(q);

        GenPolynomial c = gcd(a, b); // go to recursion
        //System.out.println("rgcd c = " + c);
        r = PolyUtil. recursiveDivide(r, a);
        q = PolyUtil. recursiveDivide(q, b);
        if (r.isONE()) {
            return r.multiply(c);
        }
        if (q.isONE()) {
            return q.multiply(c);
        }
        GenPolynomial g = r.ring.getONECoefficient();
        GenPolynomial h = r.ring.getONECoefficient();
        GenPolynomial> x;
        GenPolynomial z = null;
        while (!r.isZERO()) {
            long delta = q.degree(0) - r.degree(0);
            //System.out.println("rgcd delta = " + delta);
            x = PolyUtil. recursiveDensePseudoRemainder(q, r);
            q = r;
            if (!x.isZERO()) {
                z = g.multiply(power(P.ring.coFac, h, delta));
                r = PolyUtil. recursiveDivide(x, z);
                g = q.leadingBaseCoefficient();
                z = power(P.ring.coFac, g, delta);
                h = PolyUtil. basePseudoDivide(z, power(P.ring.coFac, h, delta - 1));
            } else {
                r = x;
            }
        }
        q = recursivePrimitivePart(q);
        return q.abs().multiply(c); //.abs();
    }


    /**
     * Univariate GenPolynomial resultant. Uses pseudoRemainder for remainder.
     * @param P univariate GenPolynomial.
     * @param S univariate GenPolynomial.
     * @return res(P,S).
     */
    @Override
    public GenPolynomial baseResultant(GenPolynomial P, GenPolynomial S) {
        if (S == null || S.isZERO()) {
            return S;
        }
        if (P == null || P.isZERO()) {
            return P;
        }
        if (P.ring.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial");
        }
        long e = P.degree(0);
        long f = S.degree(0);
        GenPolynomial q;
        GenPolynomial r;
        if (f > e) {
            r = P;
            q = S;
            long g = f;
            f = e;
            e = g;
        } else {
            q = P;
            r = S;
        }
        //r = r.abs();
        //q = q.abs();
        C a = baseContent(r);
        C b = baseContent(q);
        r = divide(r, a); // indirection
        q = divide(q, b); // indirection
        RingFactory cofac = P.ring.coFac;
        C g = cofac.getONE();
        C h = cofac.getONE();
        C t = power(cofac, a, e);
        t = t.multiply(power(cofac, b, f));
        long s = 1;
        GenPolynomial x;
        C z;
        while (r.degree(0) > 0) {
            long delta = q.degree(0) - r.degree(0);
            //System.out.println("delta    = " + delta);
            if ((q.degree(0) % 2 != 0) && (r.degree(0) % 2 != 0)) {
                s = -s;
            }
            x = PolyUtil. baseDensePseudoRemainder(q, r);
            //System.out.println("x  = " + x);
            q = r;
            if (x.degree(0) > 0) {
                z = g.multiply(power(cofac, h, delta));
                //System.out.println("z  = " + z);
                r = x.divide(z);
                g = q.leadingBaseCoefficient();
                z = power(cofac, g, delta);
                h = z.divide(power(cofac, h, delta - 1));
            } else {
                r = x;
            }
        }
        z = power(cofac, r.leadingBaseCoefficient(), q.degree(0));
        h = z.divide(power(cofac, h, q.degree(0) - 1));
        z = h.multiply(t);
        if ( s < 0 ) {
            z = z.negate();
        }
        x = P.ring.getONE().multiply(z);
        return x;
    }


    /**
     * Univariate GenPolynomial recursive resultant. Uses pseudoRemainder for
     * remainder.
     * @param P univariate recursive GenPolynomial.
     * @param S univariate recursive GenPolynomial.
     * @return res(P,S).
     */
    @Override
    public GenPolynomial> recursiveUnivariateResultant(GenPolynomial> P,
                    GenPolynomial> S) {
        if (S == null || S.isZERO()) {
            return S;
        }
        if (P == null || P.isZERO()) {
            return P;
        }
        if (P.ring.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial");
        }
        long e = P.degree(0);
        long f = S.degree(0);
        GenPolynomial> q;
        GenPolynomial> r;
        if (f > e) {
            r = P;
            q = S;
            long g = f;
            f = e;
            e = g;
        } else {
            q = P;
            r = S;
        }
        r = r.abs();
        q = q.abs();
        GenPolynomial a = recursiveContent(r);
        GenPolynomial b = recursiveContent(q);
        r = PolyUtil. recursiveDivide(r, a);
        q = PolyUtil. recursiveDivide(q, b);
        RingFactory> cofac = P.ring.coFac;
        GenPolynomial g = cofac.getONE();
        GenPolynomial h = cofac.getONE();
        GenPolynomial> x;
        GenPolynomial t;
        if (f == 0 && e == 0 && g.ring.nvar > 0) {
            // if coeffs are multivariate (and non constant)
            // otherwise it would be 1
            t = resultant(a, b);
            x = P.ring.getONE().multiply(t);
            return x;
        }
        t = power(cofac, a, e);
        t = t.multiply(power(cofac, b, f));
        long s = 1;
        GenPolynomial z;
        while (r.degree(0) > 0) {
            long delta = q.degree(0) - r.degree(0);
            //System.out.println("delta    = " + delta);
            if ((q.degree(0) % 2 != 0) && (r.degree(0) % 2 != 0)) {
                s = -s;
            }
            x = PolyUtil. recursiveDensePseudoRemainder(q, r);
            //System.out.println("x  = " + x);
            q = r;
            if (x.degree(0) > 0) {
                z = g.multiply(power(P.ring.coFac, h, delta));
                r = PolyUtil. recursiveDivide(x, z);
                g = q.leadingBaseCoefficient();
                z = power(cofac, g, delta);
                h = PolyUtil. basePseudoDivide(z, power(cofac, h, delta - 1));
            } else {
                r = x;
            }
        }
        z = power(cofac, r.leadingBaseCoefficient(), q.degree(0));
        h = PolyUtil. basePseudoDivide(z, power(cofac, h, q.degree(0) - 1));
        z = h.multiply(t);
        if ( s < 0 ) {
            z = z.negate();
        }
        x = P.ring.getONE().multiply(z);
        return x;
    }


    /**
     * GenPolynomial base coefficient discriminant.
     * @param P GenPolynomial.
     * @return discriminant(P).
     */
    public GenPolynomial baseDiscriminant(GenPolynomial P) {
        if (P == null) {
            throw new IllegalArgumentException(this.getClass().getName() + " P != null");
        }
        if (P.isZERO()) {
            return P;
        }
        GenPolynomialRing pfac = P.ring;
        if (pfac.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " P not univariate");
        }
        C a = P.leadingBaseCoefficient();
        a = a.inverse();
        GenPolynomial Pp = PolyUtil. baseDeriviative(P);
        GenPolynomial res = baseResultant(P, Pp);
        GenPolynomial disc = res.multiply(a);
        long n = P.degree(0);
        n = n * (n - 1);
        n = n / 2;
        if (n % 2L != 0L) {
            disc = disc.negate();
        }
        return disc;
    }


    /**
     * Coefficient power.
     * @param A coefficient
     * @param i exponent.
     * @return A^i.
     */
    C power(RingFactory fac, C A, long i) {
        return Power. power(fac, A, i);
    }


    /**
     * Polynomial power.
     * @param A polynomial.
     * @param i exponent.
     * @return A^i.
     */
    GenPolynomial power(RingFactory> fac, GenPolynomial A, long i) {
        return Power.> power(fac, A, i);
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy