
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