/*
* $Id$
*/
package edu.jas.ufd;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.log4j.Logger;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.PolyUtil;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingFactory;
/**
* Squarefree decomposition for coefficient fields of characteristic 0.
* @author Heinz Kredel
*/
public class SquarefreeFieldChar0> extends SquarefreeAbstract {
private static final Logger logger = Logger.getLogger(SquarefreeFieldChar0.class);
//private final boolean debug = logger.isDebugEnabled();
/**
* Factory for field of characteristic 0 coefficients.
*/
protected final RingFactory coFac;
/**
* Constructor.
*/
public SquarefreeFieldChar0(RingFactory fac) {
super(GCDFactory. getProxy(fac));
if (!fac.isField()) {
throw new IllegalArgumentException("fac must be a field");
}
if (fac.characteristic().signum() != 0) {
throw new IllegalArgumentException("characterisic(fac) must be zero");
}
coFac = fac;
}
/**
* Get the String representation.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return getClass().getName() + " with " + engine + " over " + coFac;
}
/**
* GenPolynomial polynomial greatest squarefree divisor.
* @param P GenPolynomial.
* @return squarefree(pp(P)).
*/
@Override
public GenPolynomial baseSquarefreePart(GenPolynomial P) {
if (P == null || P.isZERO()) {
return P;
}
GenPolynomialRing pfac = P.ring;
if (pfac.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
}
GenPolynomial pp = P.monic();
if (pp.isConstant()) {
return pp;
}
GenPolynomial d = PolyUtil. baseDeriviative(pp);
d = d.monic();
//System.out.println("d = " + d);
GenPolynomial g = engine.baseGcd(pp, d);
g = g.monic();
GenPolynomial q = PolyUtil. basePseudoDivide(pp, g);
q = q.monic();
return q;
}
/**
* GenPolynomial test if is squarefree.
* @param P GenPolynomial.
* @return true if P is squarefree, else false.
*/
public boolean isBaseSquarefree(GenPolynomial P) {
if (P == null || P.isZERO()) {
return true;
}
GenPolynomialRing pfac = P.ring;
if (pfac.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
}
GenPolynomial pp = P.monic();
if (pp.isConstant()) {
return true;
}
GenPolynomial d = PolyUtil. baseDeriviative(pp);
d = d.monic();
//System.out.println("d = " + d);
GenPolynomial g = engine.baseGcd(pp, d);
g = g.monic();
return g.isONE();
}
/**
* GenPolynomial polynomial squarefree factorization.
* @param A GenPolynomial.
* @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i}
* and p_i squarefree.
*/
@Override
public SortedMap, Long> baseSquarefreeFactors(GenPolynomial A) {
SortedMap, Long> sfactors = new TreeMap, Long>();
if (A == null || A.isZERO()) {
return sfactors;
}
if (A.isConstant()) {
sfactors.put(A, 1L);
return sfactors;
}
GenPolynomialRing pfac = A.ring;
if (pfac.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
}
C ldbcf = A.leadingBaseCoefficient();
if (!ldbcf.isONE()) {
A = A.divide(ldbcf);
GenPolynomial f1 = pfac.getONE().multiply(ldbcf);
//System.out.println("gcda sqf f1 = " + f1);
sfactors.put(f1, 1L);
ldbcf = pfac.coFac.getONE();
}
GenPolynomial T0 = A;
GenPolynomial Tp;
GenPolynomial T = null;
GenPolynomial V = null;
long k = 0L;
boolean init = true;
while (true) {
if (init) {
if (T0.isConstant() || T0.isZERO()) {
break;
}
Tp = PolyUtil. baseDeriviative(T0);
T = engine.baseGcd(T0, Tp);
T = T.monic();
V = PolyUtil. basePseudoDivide(T0, T);
//System.out.println("iT0 = " + T0);
//System.out.println("iTp = " + Tp);
//System.out.println("iT = " + T);
//System.out.println("iV = " + V);
k = 0L;
init = false;
}
if (V.isConstant()) {
break;
}
k++;
GenPolynomial W = engine.baseGcd(T, V);
W = W.monic();
GenPolynomial z = PolyUtil. basePseudoDivide(V, W);
//System.out.println("W = " + W);
//System.out.println("z = " + z);
V = W;
T = PolyUtil. basePseudoDivide(T, V);
//System.out.println("V = " + V);
//System.out.println("T = " + T);
if (z.degree(0) > 0) {
if (ldbcf.isONE() && !z.leadingBaseCoefficient().isONE()) {
z = z.monic();
logger.info("z,monic = " + z);
}
sfactors.put(z, k);
}
}
// look, a stupid error:
// if ( pfac.coFac.isField() && !ldbcf.isONE() ) {
// GenPolynomial f1 = sfactors.firstKey();
// long e1 = sfactors.remove(f1);
// System.out.println("gcda sqf c = " + c);
// f1 = f1.multiply(c);
// //System.out.println("gcda sqf f1e = " + f1);
// sfactors.put(f1,e1);
// }
return normalizeFactorization(sfactors);
}
/**
* GenPolynomial recursive univariate polynomial greatest squarefree
* divisor.
* @param P recursive univariate GenPolynomial.
* @return squarefree(pp(P)).
*/
@Override
public GenPolynomial> recursiveUnivariateSquarefreePart(GenPolynomial> P) {
if (P == null || P.isZERO()) {
return P;
}
GenPolynomialRing> pfac = P.ring;
if (pfac.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName()
+ " only for multivariate polynomials");
}
// squarefree content
GenPolynomial> pp = P;
GenPolynomial Pc = engine.recursiveContent(P);
Pc = Pc.monic();
if (!Pc.isONE()) {
pp = PolyUtil. coefficientPseudoDivide(pp, Pc);
//System.out.println("pp,sqp = " + pp);
//GenPolynomial Pr = squarefreePart(Pc);
//Pr = Pr.monic();
//System.out.println("Pr,sqp = " + Pr);
}
if (pp.leadingExpVector().getVal(0) < 1) {
//System.out.println("pp = " + pp);
//System.out.println("Pc = " + Pc);
return pp.multiply(Pc);
}
GenPolynomial> d = PolyUtil. recursiveDeriviative(pp);
//System.out.println("d = " + d);
GenPolynomial> g = engine.recursiveUnivariateGcd(pp, d);
//System.out.println("g,rec = " + g);
g = PolyUtil. monic(g);
GenPolynomial> q = PolyUtil. recursivePseudoDivide(pp, g);
q = PolyUtil. monic(q);
return q.multiply(Pc);
}
/**
* GenPolynomial test if is squarefree.
* @param P GenPolynomial.
* @return true if P is squarefree, else false.
*/
public boolean isRecursiveUnivariateSquarefree(GenPolynomial> P) {
if (P == null || P.isZERO()) {
return true;
}
GenPolynomialRing> pfac = P.ring;
if (pfac.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName()
+ " only for multivariate polynomials");
}
// squarefree content
GenPolynomial> pp = P;
GenPolynomial Pc = engine.recursiveContent(P);
if (logger.isInfoEnabled()) {
logger.info("recursiveContent = " + Pc);
}
if (!isSquarefree(Pc)) {
return false;
}
Pc = Pc.monic();
if (!Pc.isONE()) {
pp = PolyUtil. coefficientPseudoDivide(pp, Pc);
//System.out.println("pp,sqp = " + pp);
}
if (pp.leadingExpVector().getVal(0) <= 1) {
//System.out.println("pp = " + pp);
//System.out.println("Pc = " + Pc);
return true;
}
GenPolynomial> d = PolyUtil. recursiveDeriviative(pp);
//System.out.println("d = " + d);
GenPolynomial> g = engine.recursiveUnivariateGcd(pp, d);
if (logger.isInfoEnabled()) {
logger.info("gcd = " + g);
}
//System.out.println("g,rec = " + g);
g = PolyUtil. monic(g);
return g.isONE();
}
/**
* GenPolynomial recursive univariate polynomial squarefree factorization.
* @param P recursive univariate GenPolynomial.
* @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i}
* and p_i squarefree.
*/
@Override
public SortedMap>, Long> recursiveUnivariateSquarefreeFactors(
GenPolynomial> P) {
SortedMap>, Long> sfactors = new TreeMap>, Long>();
if (P == null || P.isZERO()) {
return sfactors;
}
GenPolynomialRing> pfac = P.ring;
if (pfac.nvar > 1) {
// recursiveContent not possible by return type
throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
}
// if base coefficient ring is a field, make monic
GenPolynomialRing cfac = (GenPolynomialRing) pfac.coFac;
C ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient();
if (!ldbcf.isONE()) {
GenPolynomial lc = cfac.getONE().multiply(ldbcf);
GenPolynomial> pl = pfac.getONE().multiply(lc);
sfactors.put(pl, 1L);
C li = ldbcf.inverse();
//System.out.println("li = " + li);
P = P.multiply(cfac.getONE().multiply(li));
//System.out.println("P,monic = " + P);
ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient();
}
// factors of content
GenPolynomial Pc = engine.recursiveContent(P);
if (logger.isInfoEnabled()) {
logger.info("recursiveContent = " + Pc);
}
Pc = Pc.monic();
if (!Pc.isONE()) {
P = PolyUtil. coefficientPseudoDivide(P, Pc);
}
SortedMap, Long> rsf = squarefreeFactors(Pc);
if (logger.isInfoEnabled()) {
logger.info("squarefreeFactors = " + rsf);
}
// add factors of content
for (Map.Entry, Long> me : rsf.entrySet()) {
GenPolynomial c = me.getKey();
if (!c.isONE()) {
GenPolynomial> cr = pfac.getONE().multiply(c);
Long rk = me.getValue(); // rsf.get(c);
sfactors.put(cr, rk);
}
}
// factors of recursive polynomial
GenPolynomial> T0 = P;
GenPolynomial> Tp;
GenPolynomial> T = null;
GenPolynomial> V = null;
long k = 0L;
boolean init = true;
while (true) {
if (init) {
if (T0.isConstant() || T0.isZERO()) {
break;
}
Tp = PolyUtil. recursiveDeriviative(T0);
T = engine.recursiveUnivariateGcd(T0, Tp);
T = PolyUtil. monic(T);
V = PolyUtil. recursivePseudoDivide(T0, T);
//System.out.println("iT0 = " + T0);
//System.out.println("iTp = " + Tp);
//System.out.println("iT = " + T);
//System.out.println("iV = " + V);
k = 0L;
init = false;
}
if (V.isConstant()) {
break;
}
k++;
GenPolynomial> W = engine.recursiveUnivariateGcd(T, V);
W = PolyUtil. monic(W);
GenPolynomial> z = PolyUtil. recursivePseudoDivide(V, W);
//System.out.println("W = " + W);
//System.out.println("z = " + z);
V = W;
T = PolyUtil. recursivePseudoDivide(T, V);
//System.out.println("V = " + V);
//System.out.println("T = " + T);
//was: if ( z.degree(0) > 0 ) {
if (!z.isONE() && !z.isZERO()) {
if (ldbcf.isONE()) {
z = PolyUtil. monic(z);
logger.info("z,monic = " + z);
}
sfactors.put(z, k);
}
}
return sfactors;
}
/**
* GenPolynomial greatest squarefree divisor.
* @param P GenPolynomial.
* @return squarefree(pp(P)).
*/
@Override
public GenPolynomial squarefreePart(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) {
return baseSquarefreePart(P);
}
GenPolynomialRing cfac = pfac.contract(1);
GenPolynomialRing> rfac = new GenPolynomialRing>(cfac, 1);
GenPolynomial> Pr = PolyUtil. recursive(rfac, P);
GenPolynomial Pc = engine.recursiveContent(Pr);
Pr = PolyUtil. coefficientPseudoDivide(Pr, Pc);
GenPolynomial Ps = squarefreePart(Pc);
if (logger.isInfoEnabled()) {
logger.info("content = " + Pc + ", squarefreePart = " + Ps);
}
GenPolynomial> PP = recursiveUnivariateSquarefreePart(Pr);
GenPolynomial> PS = PP.multiply(Ps);
GenPolynomial D = PolyUtil. distribute(pfac, PS);
if (logger.isInfoEnabled()) {
logger.info("univRec = " + Pr + ", squarefreePart = " + PP);
}
return D;
}
/**
* GenPolynomial test if is squarefree.
* @param P GenPolynomial.
* @return true if P is squarefree, else false.
*/
@Override
public boolean isSquarefree(GenPolynomial P) {
if (P == null) {
throw new IllegalArgumentException(this.getClass().getName() + " P != null");
}
if (P.isZERO()) {
return true;
}
GenPolynomialRing pfac = P.ring;
if (pfac.nvar <= 1) {
return isBaseSquarefree(P);
}
GenPolynomialRing cfac = pfac.contract(1);
GenPolynomialRing> rfac = new GenPolynomialRing>(cfac, 1);
GenPolynomial> Pr = PolyUtil. recursive(rfac, P);
return isRecursiveUnivariateSquarefree(Pr);
}
/**
* GenPolynomial squarefree factorization.
* @param P GenPolynomial.
* @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i}
* and p_i squarefree.
*/
@Override
public SortedMap, Long> squarefreeFactors(GenPolynomial P) {
if (P == null) {
throw new IllegalArgumentException(this.getClass().getName() + " P != null");
}
GenPolynomialRing pfac = P.ring;
if (pfac.nvar <= 1) {
return normalizeFactorization(baseSquarefreeFactors(P));
}
SortedMap, Long> sfactors = new TreeMap, Long>();
if (P.isZERO()) {
return normalizeFactorization(sfactors);
}
GenPolynomialRing cfac = pfac.contract(1);
GenPolynomialRing> rfac = new GenPolynomialRing>(cfac, 1);
GenPolynomial> Pr = PolyUtil. recursive(rfac, P);
SortedMap>, Long> PP = recursiveUnivariateSquarefreeFactors(Pr);
for (Map.Entry>, Long> m : PP.entrySet()) {
Long i = m.getValue();
GenPolynomial> Dr = m.getKey();
GenPolynomial D = PolyUtil. distribute(pfac, Dr);
sfactors.put(D, i);
}
if (logger.isInfoEnabled()) {
logger.info("squarefreeFactors(" + P + ") = " + sfactors);
}
return normalizeFactorization(sfactors);
}
/**
* Coefficients squarefree factorization.
* @param P coefficient.
* @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i}
* and p_i squarefree.
*/
@Override
public SortedMap squarefreeFactors(C P) {
throw new UnsupportedOperationException("method not implemented");
}
}
Ads help maintain this website.