/*
* $Id$
*/
package edu.jas.ufd;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import edu.jas.arith.BigInteger;
import edu.jas.poly.AlgebraicNumber;
import edu.jas.poly.AlgebraicNumberRing;
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.RingElem;
import edu.jas.structure.RingFactory;
import edu.jas.structure.UnaryFunctor;
import edu.jas.util.ListUtil;
/**
* Polynomial ufd utilities, like conversion between different representations
* and Hensel lifting.
* @author Heinz Kredel
*/
public class PolyUfdUtil {
private static final Logger logger = Logger.getLogger(PolyUfdUtil.class);
private static boolean debug = logger.isDebugEnabled();
/**
* Integral polynomial from rational function coefficients. Represent as
* polynomial with integral polynomial coefficients by multiplication with
* the lcm of the numerators of the rational function coefficients.
* @param fac result polynomial factory.
* @param A polynomial with rational function coefficients to be converted.
* @return polynomial with integral polynomial coefficients.
*/
public static > GenPolynomial> integralFromQuotientCoefficients(
GenPolynomialRing> fac, GenPolynomial> A) {
GenPolynomial> B = fac.getZERO().copy();
if (A == null || A.isZERO()) {
return B;
}
GenPolynomial c = null;
GenPolynomial d;
GenPolynomial x;
GreatestCommonDivisor ufd = new GreatestCommonDivisorSubres();
int s = 0;
// lcm of denominators
for (Quotient y : A.getMap().values()) {
x = y.den;
// c = lcm(c,x)
if (c == null) {
c = x;
s = x.signum();
} else {
d = ufd.gcd(c, x);
c = c.multiply(x.divide(d));
}
}
if (s < 0) {
c = c.negate();
}
for (Map.Entry> y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
Quotient a = y.getValue();
// p = n*(c/d)
GenPolynomial b = c.divide(a.den);
GenPolynomial p = a.num.multiply(b);
//B = B.sum( p, e ); // inefficient
B.doPutToMap(e, p);
}
return B;
}
/**
* Integral polynomial from rational function coefficients. Represent as
* polynomial with integral polynomial coefficients by multiplication with
* the lcm of the numerators of the rational function coefficients.
* @param fac result polynomial factory.
* @param L list of polynomial with rational function coefficients to be
* converted.
* @return list of polynomials with integral polynomial coefficients.
*/
public static > List>> integralFromQuotientCoefficients(
GenPolynomialRing> fac, Collection>> L) {
if (L == null) {
return null;
}
List>> list = new ArrayList>>(L.size());
for (GenPolynomial> p : L) {
list.add(integralFromQuotientCoefficients(fac, p));
}
return list;
}
/**
* Rational function from integral polynomial coefficients. Represent as
* polynomial with type Quotient coefficients.
* @param fac result polynomial factory.
* @param A polynomial with integral polynomial coefficients to be
* converted.
* @return polynomial with type Quotient coefficients.
*/
public static > GenPolynomial> quotientFromIntegralCoefficients(
GenPolynomialRing> fac, GenPolynomial> A) {
GenPolynomial> B = fac.getZERO().copy();
if (A == null || A.isZERO()) {
return B;
}
RingFactory> cfac = fac.coFac;
QuotientRing qfac = (QuotientRing) cfac;
for (Map.Entry> y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
GenPolynomial a = y.getValue();
Quotient p = new Quotient(qfac, a); // can not be zero
if (!p.isZERO()) {
//B = B.sum( p, e ); // inefficient
B.doPutToMap(e, p);
}
}
return B;
}
/**
* Rational function from integral polynomial coefficients. Represent as
* polynomial with type Quotient coefficients.
* @param fac result polynomial factory.
* @param L list of polynomials with integral polynomial coefficients to be
* converted.
* @return list of polynomials with type Quotient coefficients.
*/
public static > List>> quotientFromIntegralCoefficients(
GenPolynomialRing> fac, Collection>> L) {
if (L == null) {
return null;
}
List>> list = new ArrayList>>(L.size());
for (GenPolynomial> p : L) {
list.add(quotientFromIntegralCoefficients(fac, p));
}
return list;
}
/**
* From BigInteger coefficients. Represent as polynomial with type
* GenPolynomial<C> coefficients, e.g. ModInteger or BigRational.
* @param fac result polynomial factory.
* @param A polynomial with GenPolynomial<BigInteger> coefficients to
* be converted.
* @return polynomial with type GenPolynomial<C> coefficients.
*/
public static > GenPolynomial> fromIntegerCoefficients(
GenPolynomialRing> fac, GenPolynomial> A) {
GenPolynomial> B = fac.getZERO().copy();
if (A == null || A.isZERO()) {
return B;
}
RingFactory> cfac = fac.coFac;
GenPolynomialRing rfac = (GenPolynomialRing) cfac;
for (Map.Entry> y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
GenPolynomial a = y.getValue();
GenPolynomial p = PolyUtil. fromIntegerCoefficients(rfac, a);
if (!p.isZERO()) {
//B = B.sum( p, e ); // inefficient
B.doPutToMap(e, p);
}
}
return B;
}
/**
* From BigInteger coefficients. Represent as polynomial with type
* GenPolynomial<C> coefficients, e.g. ModInteger or BigRational.
* @param fac result polynomial factory.
* @param L polynomial list with GenPolynomial<BigInteger>
* coefficients to be converted.
* @return polynomial list with polynomials with type GenPolynomial<C>
* coefficients.
*/
public static > List>> fromIntegerCoefficients(
GenPolynomialRing> fac, List>> L) {
List>> K = null;
if (L == null) {
return K;
}
K = new ArrayList>>(L.size());
if (L.size() == 0) {
return K;
}
for (GenPolynomial> a : L) {
GenPolynomial> b = fromIntegerCoefficients(fac, a);
K.add(b);
}
return K;
}
/**
* Introduce lower variable. Represent as polynomial with type
* GenPolynomial<C> coefficients.
* @param rfac result polynomial factory.
* @param A polynomial to be extended.
* @return polynomial with type GenPolynomial<C> coefficients.
*/
public static > GenPolynomial> introduceLowerVariable(
GenPolynomialRing> rfac, GenPolynomial A) {
if (A == null || rfac == null) {
return null;
}
GenPolynomial> Pc = rfac.getONE().multiply(A);
if (Pc.isZERO()) {
return Pc;
}
Pc = PolyUtil. switchVariables(Pc);
return Pc;
}
/**
* 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.
* @param k for (y-k x) substitution.
* @return polynomial with type GenPolynomial<C> coefficients.
*/
public static > GenPolynomial> substituteFromAlgebraicCoefficients(
GenPolynomialRing> rfac, GenPolynomial> A, long k) {
if (A == null || rfac == null) {
return null;
}
if (A.isZERO()) {
return rfac.getZERO();
}
// setup x - k alpha
GenPolynomialRing> apfac = A.ring;
GenPolynomial> x = apfac.univariate(0);
AlgebraicNumberRing afac = (AlgebraicNumberRing) A.ring.coFac;
AlgebraicNumber alpha = afac.getGenerator();
AlgebraicNumber ka = afac.fromInteger(k);
GenPolynomial> s = x.subtract(ka.multiply(alpha)); // x - k alpha
if (debug) {
logger.info("x - k alpha: " + s);
}
// substitute, convert and switch
GenPolynomial> B = PolyUtil.> substituteMain(A, s);
GenPolynomial> Pc = PolyUtil. fromAlgebraicCoefficients(rfac, B); // Q[alpha][x]
Pc = PolyUtil. switchVariables(Pc); // Q[x][alpha]
return Pc;
}
/**
* 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 GenPolynomial<BigInteger> coefficients to
* be converted.
* @param k for (y-k x) substitution.
* @return polynomial with AlgebraicNumber<C> coefficients.
*/
public static > GenPolynomial> substituteConvertToAlgebraicCoefficients(
GenPolynomialRing> pfac, GenPolynomial A, long k) {
if (A == null || pfac == null) {
return null;
}
if (A.isZERO()) {
return pfac.getZERO();
}
// convert to Q(alpha)[x]
GenPolynomial> B = PolyUtil. convertToAlgebraicCoefficients(pfac, A);
// setup x .+. k alpha for back substitution
GenPolynomial> x = pfac.univariate(0);
AlgebraicNumberRing afac = (AlgebraicNumberRing) pfac.coFac;
AlgebraicNumber alpha = afac.getGenerator();
AlgebraicNumber ka = afac.fromInteger(k);
GenPolynomial> s = x.sum(ka.multiply(alpha)); // x + k alpha
// substitute
GenPolynomial> N = PolyUtil.> substituteMain(B, s);
return N;
}
/**
* Norm of a polynomial with AlgebraicNumber coefficients.
* @param A polynomial from GenPolynomial<AlgebraicNumber<C>>.
* @param k for (y - k x) substitution.
* @return norm(A) = res_x(A(x,y),m(x)) in GenPolynomialRing<C>.
*/
public static > GenPolynomial norm(GenPolynomial> A, long k) {
if (A == null) {
return null;
}
GenPolynomialRing> pfac = A.ring; // Q(alpha)[x]
if (pfac.nvar > 1) {
throw new IllegalArgumentException("only for univariate polynomials");
}
AlgebraicNumberRing afac = (AlgebraicNumberRing) pfac.coFac;
GenPolynomial agen = afac.modul;
GenPolynomialRing cfac = afac.ring;
if (A.isZERO()) {
return cfac.getZERO();
}
AlgebraicNumber ldcf = A.leadingBaseCoefficient();
if (!ldcf.isONE()) {
A = A.monic();
}
GenPolynomialRing> rfac = new GenPolynomialRing>(cfac, pfac);
// transform minimal polynomial to bi-variate polynomial
GenPolynomial> Ac = PolyUfdUtil. introduceLowerVariable(rfac, agen);
//System.out.println("Ac = " + Ac.toScript());
// transform to bi-variate polynomial,
// switching varaible sequence from Q[alpha][x] to Q[X][alpha]
GenPolynomial> Pc = PolyUfdUtil. substituteFromAlgebraicCoefficients(rfac, A, k);
Pc = PolyUtil. monic(Pc);
//System.out.println("Pc = " + Pc.toScript());
GreatestCommonDivisorSubres engine = new GreatestCommonDivisorSubres( /*cfac.coFac*/);
// = (GreatestCommonDivisorAbstract)GCDFactory.getImplementation( cfac.coFac );
GenPolynomial> Rc = engine.recursiveUnivariateResultant(Pc, Ac);
//System.out.println("Rc = " + Rc.toScript());
GenPolynomial res = Rc.leadingBaseCoefficient();
res = res.monic();
return res;
}
/**
* Norm of a polynomial with AlgebraicNumber coefficients.
* @param A polynomial from GenPolynomial<AlgebraicNumber<C>>.
* @return norm(A) = resultant_x( A(x,y), m(x) ) in K[y].
*/
public static > GenPolynomial norm(GenPolynomial> A) {
return norm(A, 0L);
}
/**
* Ensure that the field property is determined. Checks if modul is
* irreducible and modifies the algebraic number ring.
* @param afac algebraic number ring.
*/
public static > void ensureFieldProperty(AlgebraicNumberRing afac) {
if (afac.getField() != -1) {
return;
}
if (!afac.ring.coFac.isField()) {
afac.setField(false);
return;
}
Factorization mf = FactorFactory. getImplementation(afac.ring);
if (mf.isIrreducible(afac.modul)) {
afac.setField(true);
} else {
afac.setField(false);
}
}
/**
* Kronecker substitution. Substitute x_i by x**d**(i-1) to construct a
* univariate polynomial.
* @param A polynomial to be converted.
* @return a univariate polynomial.
*/
public static > GenPolynomial substituteKronecker(GenPolynomial A) {
if (A == null) {
return A;
}
long d = A.degree() + 1L;
return substituteKronecker(A, d);
}
/**
* Kronecker substitution. Substitute x_i by x**d**(i-1) to construct a
* univariate polynomial.
* @param A polynomial to be converted.
* @return a univariate polynomial.
*/
public static > GenPolynomial substituteKronecker(GenPolynomial A, long d) {
if (A == null) {
return A;
}
RingFactory cfac = A.ring.coFac;
GenPolynomialRing ufac = new GenPolynomialRing(cfac, 1);
GenPolynomial B = ufac.getZERO().copy();
if (A.isZERO()) {
return B;
}
for (Map.Entry y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
C a = y.getValue();
long f = 0L;
long h = 1L;
for (int i = 0; i < e.length(); i++) {
long j = e.getVal(i) * h;
f += j;
h *= d;
}
ExpVector g = ExpVector.create(1, 0, f);
B.doPutToMap(g, a);
}
return B;
}
/**
* Kronecker substitution. Substitute x_i by x**d**(i-1) to construct a
* univariate polynomials.
* @param A list of polynomials to be converted.
* @return a list of univariate polynomials.
*/
public static > List> substituteKronecker(
List> A, int d) {
if (A == null || A.get(0) == null) {
return null;
}
return ListUtil., GenPolynomial> map(A, new SubstKronecker(d));
}
/**
* Kronecker back substitution. Substitute x**d**(i-1) to x_i to construct a
* multivariate polynomial.
* @param A polynomial to be converted.
* @param fac result polynomial factory.
* @return a multivariate polynomial.
*/
public static > GenPolynomial backSubstituteKronecker(
GenPolynomialRing fac, GenPolynomial A, long d) {
if (A == null) {
return A;
}
if (fac == null) {
throw new IllegalArgumentException("null factory not allowed ");
}
int n = fac.nvar;
GenPolynomial B = fac.getZERO().copy();
if (A.isZERO()) {
return B;
}
for (Map.Entry y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
C a = y.getValue();
long f = e.getVal(0);
ExpVector g = ExpVector.create(n);
for (int i = 0; i < n; i++) {
long j = f % d;
f /= d;
g = g.subst(i, j);
}
B.doPutToMap(g, a);
}
return B;
}
/**
* Kronecker back substitution. Substitute x**d**(i-1) to x_i to construct a
* multivariate polynomials.
* @param A list of polynomials to be converted.
* @param fac result polynomial factory.
* @return a list of multivariate polynomials.
*/
public static > List> backSubstituteKronecker(
GenPolynomialRing fac, List> A, long d) {
return ListUtil., GenPolynomial> map(A, new BackSubstKronecker(fac, d));
}
}
/**
* Kronecker substitutuion functor.
*/
class SubstKronecker> implements UnaryFunctor, GenPolynomial> {
final long d;
public SubstKronecker(long d) {
this.d = d;
}
public GenPolynomial eval(GenPolynomial c) {
if (c == null) {
return null;
}
return PolyUfdUtil. substituteKronecker(c, d);
}
}
/**
* Kronecker back substitutuion functor.
*/
class BackSubstKronecker> implements
UnaryFunctor, GenPolynomial> {
final long d;
final GenPolynomialRing fac;
public BackSubstKronecker(GenPolynomialRing fac, long d) {
this.d = d;
this.fac = fac;
}
public GenPolynomial eval(GenPolynomial c) {
if (c == null) {
return null;
}
return PolyUfdUtil. backSubstituteKronecker(fac, c, d);
}
}
Ads help maintain this website.