
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