/*
* $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.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.Monomial;
import edu.jas.poly.PolyUtil;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.Power;
import edu.jas.structure.RingFactory;
/**
* Squarefree decomposition for infinite coefficient fields of characteristic p.
* @author Heinz Kredel
*/
public class SquarefreeInfiniteFieldCharP> extends SquarefreeFieldCharP> {
private static final Logger logger = Logger.getLogger(SquarefreeInfiniteFieldCharP.class);
//private final boolean debug = logger.isDebugEnabled();
/**
* Squarefree engine for infinite ring of characteristic p base coefficients.
*/
protected final SquarefreeAbstract qengine;
/**
* Constructor.
*/
public SquarefreeInfiniteFieldCharP(RingFactory> fac) {
super(fac);
// isFinite() predicate now present
if (fac.isFinite()) {
throw new IllegalArgumentException("fac must be in-finite");
}
QuotientRing qfac = (QuotientRing) fac;
GenPolynomialRing rfac = qfac.ring;
qengine = (SquarefreeAbstract) SquarefreeFactory. getImplementation(rfac);
//qengine = new SquarefreeFiniteFieldCharP(rfac.coFac);
//qengine = new SquarefreeInfiniteRingCharP( rfac.coFac );
}
/* --------- quotient char-th roots --------------------- */
/**
* Squarefree factors of a Quotient.
* @param P Quotient.
* @return [p_1 -> e_1,...,p_k - > e_k] with P = prod_{i=1, ..., k}
* p_i**e_k.
*/
@Override
public SortedMap, Long> squarefreeFactors(Quotient P) {
if (P == null) {
throw new IllegalArgumentException(this.getClass().getName() + " P == null");
}
SortedMap, Long> factors = new TreeMap, Long>();
if (P.isZERO()) {
return factors;
}
if (P.isONE()) {
factors.put(P, 1L);
return factors;
}
GenPolynomial num = P.num;
GenPolynomial den = P.den;
QuotientRing pfac = P.ring;
GenPolynomial one = pfac.ring.getONE();
if (!num.isONE()) {
SortedMap, Long> nfac = qengine.squarefreeFactors(num);
//System.out.println("nfac = " + nfac);
for (Map.Entry, Long> me : nfac.entrySet()) {
GenPolynomial nfp = me.getKey();
Quotient nf = new Quotient(pfac, nfp);
factors.put(nf, me.getValue()); //nfac.get(nfp));
}
}
if (den.isONE()) {
if (factors.size() == 0) {
factors.put(P, 1L);
}
return factors;
}
SortedMap, Long> dfac = qengine.squarefreeFactors(den);
//System.out.println("dfac = " + dfac);
for (Map.Entry, Long> me : dfac.entrySet()) {
GenPolynomial dfp = me.getKey();
Quotient df = new Quotient(pfac, one, dfp);
factors.put(df, me.getValue()); //dfac.get(dfp));
}
if (factors.size() == 0) {
factors.put(P, 1L);
}
return factors;
}
/**
* Characteristics root of a Quotient.
* @param P Quotient.
* @return [p -> k] if exists k with e=charactristic(P)*k and P = p**e,
* else null.
*/
public SortedMap, Long> rootCharacteristic(Quotient P) {
if (P == null) {
throw new IllegalArgumentException(this.getClass().getName() + " P == null");
}
java.math.BigInteger c = P.ring.characteristic();
if (c.signum() == 0) {
return null;
}
SortedMap, Long> root = new TreeMap, Long>();
if (P.isZERO()) {
return root;
}
if (P.isONE()) {
root.put(P, 1L);
return root;
}
SortedMap, Long> sf = squarefreeFactors(P);
if (sf.size() == 0) {
return null;
}
if (logger.isInfoEnabled()) {
logger.info("sf,quot = " + sf);
}
// better: test if sf.size() == 2 // no, since num and den factors
Long k = null;
Long cl = c.longValue();
for (Map.Entry, Long> me : sf.entrySet()) {
Quotient p = me.getKey();
//System.out.println("p = " + p);
if (p.isConstant()) { // todo: check for non-constants in coefficients
continue;
}
Long e = me.getValue(); //sf.get(p);
long E = e.longValue();
long r = E % cl;
if (r != 0) {
//System.out.println("r = " + r);
return null;
}
if (k == null) {
k = e;
} else if (k >= e) {
k = e;
}
}
if (k == null) {
k = 1L; //return null;
}
// now c divides all exponents of non constant elements
for (Map.Entry, Long> me : sf.entrySet()) {
Quotient q = me.getKey();
Long e = me.getValue(); //sf.get(q);
//System.out.println("q = " + q + ", e = " + e);
if (e >= k) {
e = e / cl;
//q = Power.> positivePower(q, e);
root.put(q, e);
} else { // constant case
root.put(q, e);
}
}
//System.out.println("root = " + root);
return root;
}
/**
* GenPolynomial char-th root main variable.
* @param P univariate GenPolynomial with Quotient coefficients.
* @return char-th_rootOf(P), or null, if P is no char-th root.
*/
public GenPolynomial> rootCharacteristic(GenPolynomial> P) {
if (P == null || P.isZERO()) {
return P;
}
GenPolynomialRing> pfac = P.ring;
if (pfac.nvar > 1) {
// go to recursion
GenPolynomialRing> cfac = pfac.contract(1);
GenPolynomialRing>> rfac = new GenPolynomialRing>>(
cfac, 1);
GenPolynomial>> Pr = PolyUtil.> recursive(rfac, P);
GenPolynomial>> Prc = recursiveUnivariateRootCharacteristic(Pr);
if (Prc == null) {
return null;
}
GenPolynomial> D = PolyUtil.> distribute(pfac, Prc);
return D;
}
RingFactory> rf = pfac.coFac;
if (rf.characteristic().signum() != 1) {
// basePthRoot not possible
throw new IllegalArgumentException(P.getClass().getName() + " only for ModInteger polynomials "
+ rf);
}
long mp = rf.characteristic().longValue();
GenPolynomial> d = pfac.getZERO().copy();
for (Monomial> m : P) {
ExpVector f = m.e;
long fl = f.getVal(0);
if (fl % mp != 0) {
return null;
}
fl = fl / mp;
SortedMap, Long> sm = rootCharacteristic(m.c);
if (sm == null) {
return null;
}
if (logger.isInfoEnabled()) {
logger.info("sm,root = " + sm);
}
Quotient r = rf.getONE();
for (Map.Entry, Long> me : sm.entrySet()) {
Quotient rp = me.getKey();
long gl = me.getValue(); // sm.get(rp);
if (gl > 1) {
rp = Power.> positivePower(rp, gl);
}
r = r.multiply(rp);
}
ExpVector e = ExpVector.create(1, 0, fl);
d.doPutToMap(e, r);
}
logger.info("sm,root,d = " + d);
return d;
}
/**
* GenPolynomial char-th root univariate polynomial.
* @param P GenPolynomial.
* @return char-th_rootOf(P).
*/
@Override
public GenPolynomial> baseRootCharacteristic(GenPolynomial> P) {
if (P == null || P.isZERO()) {
return P;
}
GenPolynomialRing> pfac = P.ring;
if (pfac.nvar > 1) {
// basePthRoot not possible by return type
throw new IllegalArgumentException(P.getClass().getName() + " only for univariate polynomials");
}
RingFactory> rf = pfac.coFac;
if (rf.characteristic().signum() != 1) {
// basePthRoot not possible
throw new IllegalArgumentException(P.getClass().getName() + " only for char p > 0 " + rf);
}
long mp = rf.characteristic().longValue();
GenPolynomial> d = pfac.getZERO().copy();
for (Monomial> m : P) {
//System.out.println("m = " + m);
ExpVector f = m.e;
long fl = f.getVal(0);
if (fl % mp != 0) {
return null;
}
fl = fl / mp;
SortedMap, Long> sm = rootCharacteristic(m.c);
if (sm == null) {
return null;
}
if (logger.isInfoEnabled()) {
logger.info("sm,base,root = " + sm);
}
Quotient r = rf.getONE();
for (Map.Entry, Long> me : sm.entrySet()) {
Quotient rp = me.getKey();
//System.out.println("rp = " + rp);
long gl = me.getValue(); //sm.get(rp);
//System.out.println("gl = " + gl);
Quotient re = rp;
if (gl > 1) {
re = Power.> positivePower(rp, gl);
}
//System.out.println("re = " + re);
r = r.multiply(re);
}
ExpVector e = ExpVector.create(1, 0, fl);
d.doPutToMap(e, r);
}
if (logger.isInfoEnabled()) {
logger.info("sm,base,d = " + d);
}
return d;
}
/**
* GenPolynomial char-th root univariate polynomial with polynomial
* coefficients.
* @param P recursive univariate GenPolynomial.
* @return char-th_rootOf(P), or null if P is no char-th root.
*/
@Override
public GenPolynomial>> recursiveUnivariateRootCharacteristic(
GenPolynomial>> P) {
if (P == null || P.isZERO()) {
return P;
}
GenPolynomialRing>> pfac = P.ring;
if (pfac.nvar > 1) {
// basePthRoot not possible by return type
throw new IllegalArgumentException(P.getClass().getName()
+ " only for univariate recursive polynomials");
}
RingFactory>> rf = pfac.coFac;
if (rf.characteristic().signum() != 1) {
// basePthRoot not possible
throw new IllegalArgumentException(P.getClass().getName() + " only for char p > 0 " + rf);
}
long mp = rf.characteristic().longValue();
GenPolynomial>> d = pfac.getZERO().copy();
for (Monomial>> m : P) {
ExpVector f = m.e;
long fl = f.getVal(0);
if (fl % mp != 0) {
return null;
}
fl = fl / mp;
GenPolynomial> r = rootCharacteristic(m.c);
if (r == null) {
return null;
}
ExpVector e = ExpVector.create(1, 0, fl);
d.doPutToMap(e, r);
}
return d;
}
}
Ads help maintain this website.