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

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

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

package edu.jas.ufd;


import org.apache.log4j.Logger;

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


/**
 * Greatest common divisor algorithms with monic polynomial remainder sequence.
 * If C is a field, then the monic PRS (on coefficients) is computed otherwise
 * no simplifications in the reduction are made.
 * @author Heinz Kredel
 */

public class GreatestCommonDivisorSimple> extends GreatestCommonDivisorAbstract {


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


    private final boolean debug = logger.isDebugEnabled();


    /**
     * 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");
        }
        boolean field = P.ring.coFac.isField();
        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);
        }
        C c;
        if (field) {
            r = r.monic();
            q = q.monic();
            c = P.ring.getONECoefficient();
        } else {
            r = r.abs();
            q = q.abs();
            C a = baseContent(r);
            C b = baseContent(q);
            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);
        }
        GenPolynomial x;
        //System.out.println("q = " + q);
        //System.out.println("r = " + r);
        while (!r.isZERO()) {
            x = PolyUtil. baseSparsePseudoRemainder(q, r);
            q = r;
            if (field) {
                r = x.monic();
            } else {
                r = x;
            }
            //System.out.println("q = " + q);
            //System.out.println("r = " + r);
        }
        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");
        }
        boolean field = P.leadingBaseCoefficient().ring.coFac.isField();
        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);
        }
        if (field) {
            r = PolyUtil. monic(r);
            q = PolyUtil. monic(q);
        } else {
            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> x;
        while (!r.isZERO()) {
            x = PolyUtil. recursivePseudoRemainder(q, r);
            q = r;
            if (field) {
                r = PolyUtil. monic(x);
            } else {
                r = x;
            }
        }
        q = recursivePrimitivePart(q);
        q = q.abs().multiply(c);
        return q;
    }


    /**
     * Univariate GenPolynomial resultant. 
     * @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 || P.ring.nvar == 0) {
            throw new IllegalArgumentException("no univariate polynomial");
        }
        long e = P.degree(0);
        long f = S.degree(0);
        if (f == 0 && e == 0) {
            return P.ring.getONE();
        }
        if ( e == 0 ) {
            return Power.> power(P.ring,P,f);
        }
        if ( f == 0 ) {
            return Power.> power(S.ring,S,e);
        }
        GenPolynomial q;
        GenPolynomial r;
        int s = 0; // sign is +, 1 for sign is -
        if (e < f) {
            r = P;
            q = S;
            long t = e;
            e = f;
            f = t;
            if ((e % 2 != 0) && (f % 2 != 0)) { // odd(e) && odd(f)
                s = 1;
            }
        } else {
            q = P;
            r = S;
        }
        RingFactory cofac = P.ring.coFac; 
        boolean field = cofac.isField();
        C c = cofac.getONE();
        GenPolynomial x;
        long g;
        do {
            if (field) {
                x = q.remainder(r);
            } else {
                x = PolyUtil.baseSparsePseudoRemainder(q,r);
                //System.out.println("x_s = " + x + ", lbcf(r) = " + r.leadingBaseCoefficient());
            }
            if ( x.isZERO() ) {
                return x;
            }
            //System.out.println("x = " + x);
            e = q.degree(0);
            f = r.degree(0);
            if ((e % 2 != 0) && (f % 2 != 0)) { // odd(e) && odd(f)
               s = 1 - s;
            }
            g = x.degree(0);
            C c2 = r.leadingBaseCoefficient();
            for (int i = 0; i < (e-g); i++ ) {
                c = c.multiply(c2);
            }
            q = r; 
            r = x;
        } while (g != 0);
        C c2 = r.leadingBaseCoefficient();
        for (int i = 0; i < f; i++ ) {
            c = c.multiply(c2);
        }
        if ( s == 1 ) {
            c = c.negate();
        }
        x = P.ring.getONE().multiply(c);
        return x;
    }


    /**
     * Univariate GenPolynomial recursive resultant. 
     * @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 || P.ring.nvar == 0) {
            throw new IllegalArgumentException("no recursive univariate polynomial");
        }
        long e = P.degree(0);
        long f = S.degree(0);
        if ( f == 0 && e == 0 ) {
            // if coeffs are multivariate (and non constant)
            // otherwise it would be 1
            GenPolynomial t = resultant(P.leadingBaseCoefficient(), S.leadingBaseCoefficient());
            return P.ring.getONE().multiply(t);
        }
        if ( e == 0 ) {
            return Power.>> power(P.ring,P,f);
        }
        if ( f == 0 ) {
            return Power.>> power(S.ring,S,e);
        }
        GenPolynomial> q;
        GenPolynomial> r;
        int s = 0; // sign is +, 1 for sign is -
        if (f > e) {
            r = P;
            q = S;
            long g = f;
            f = e;
            e = g;
            if ((e % 2 != 0) && (f % 2 != 0)) { // odd(e) && odd(f)
                s = 1;
            }
        } else {
            q = P;
            r = S;
        }
        GenPolynomial> x;
        RingFactory> cofac = P.ring.coFac; 
        GenPolynomial c = cofac.getONE();
        long g;
        do {
            x = PolyUtil.recursiveSparsePseudoRemainder(q,r);
            //x = PolyUtil.recursiveDensePseudoRemainder(q,r);
            if ( x.isZERO() ) {
                return x;
            }
            //no: x = recursivePrimitivePart(x);
            //System.out.println("x = " + x);
            e = q.degree(0);
            f = r.degree(0);
            if ((e % 2 != 0) && (f % 2 != 0)) { // odd(e) && odd(f)
               s = 1 - s;
            }
            g = x.degree(0);
            GenPolynomial c2 = r.leadingBaseCoefficient();
            for (int i = 0; i < (e-g); i++ ) {
                c = c.multiply(c2);
            }
            q = r; 
            r = x;
        } while (g != 0);
        GenPolynomial c2 = r.leadingBaseCoefficient();
        for (int i = 0; i < f; i++ ) {
             c = c.multiply(c2);
        }
        if ( s == 1 ) {
            c = c.negate();
        }
        x = P.ring.getONE().multiply(c);
        return x;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy