
edu.jas.gb.SolvableGroebnerBaseAbstract Maven / Gradle / Ivy
The newest version!
/*
* $Id: SolvableGroebnerBaseAbstract.java 4385 2013-04-27 13:34:38Z kredel $
*/
package edu.jas.gb;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.apache.log4j.Logger;
import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.GenSolvablePolynomial;
import edu.jas.poly.GenSolvablePolynomialRing;
import edu.jas.poly.PolyUtil;
import edu.jas.poly.PolynomialList;
import edu.jas.poly.TermOrder;
import edu.jas.structure.RingElem;
import edu.jas.structure.RingFactory;
import edu.jas.vector.BasicLinAlg;
/**
* Solvable Groebner Bases abstract class. Implements common left, right and
* twosided Groebner bases and left, right and twosided GB tests.
* @param coefficient type
* @author Heinz Kredel.
*/
public abstract class SolvableGroebnerBaseAbstract> implements SolvableGroebnerBase {
private static final Logger logger = Logger.getLogger(SolvableGroebnerBaseAbstract.class);
private final boolean debug = logger.isDebugEnabled();
/**
* Solvable reduction engine.
*/
public SolvableReduction sred;
/**
* Reduction engine.
*/
public final Reduction red;
/**
* Strategy for pair selection.
*/
public final PairList strategy;
/**
* Linear algebra engine.
*/
protected final BasicLinAlg> blas;
/**
* Commutative Groebner bases engine.
*/
public final GroebnerBaseAbstract cbb;
/**
* Constructor.
*/
public SolvableGroebnerBaseAbstract() {
this(new SolvableReductionSeq());
}
/**
* Constructor.
* @param sred Solvable reduction engine
*/
public SolvableGroebnerBaseAbstract(SolvableReduction sred) {
this(sred, new OrderedPairlist());
}
/**
* Constructor.
* @param sred Solvable reduction engine
* @param pl pair selection strategy
*/
public SolvableGroebnerBaseAbstract(SolvableReduction sred, PairList pl) {
this.red = new ReductionSeq();
this.sred = sred;
this.strategy = pl;
blas = new BasicLinAlg>();
cbb = new GroebnerBaseSeq();
}
/**
* Left Groebner base test.
* @param F solvable polynomial list.
* @return true, if F is a left Groebner base, else false.
*/
public boolean isLeftGB(List> F) {
return isLeftGB(0, F, true);
}
/**
* Left Groebner base test.
* @param F solvable polynomial list.
* @param b true for simple test, false for GB test.
* @return true, if F is a Groebner base, else false.
*/
public boolean isLeftGB(List> F, boolean b) {
return isLeftGB(0, F, b);
}
/**
* Left Groebner base test.
* @param modv module variable number.
* @param F solvable polynomial list.
* @return true, if F is a Groebner base, else false.
*/
public boolean isLeftGB(int modv, List> F) {
return isLeftGB(modv, F, true);
}
/**
* Left Groebner base test.
* @param modv module variable number.
* @param F solvable polynomial list.
* @param b true for simple test, false for GB test.
* @return true, if F is a Groebner base, else false.
*/
public boolean isLeftGB(int modv, List> F, boolean b) {
if (b) {
return isLeftGBsimple(modv, F);
}
return isLeftGBidem(modv, F);
}
/**
* Left Groebner base test.
* @param modv number of module variables.
* @param F solvable polynomial list.
* @return true, if F is a left Groebner base, else false.
*/
public boolean isLeftGBsimple(int modv, List> F) {
GenSolvablePolynomial pi, pj, s, h;
for (int i = 0; i < F.size(); i++) {
pi = F.get(i);
for (int j = i + 1; j < F.size(); j++) {
pj = F.get(j);
if (!red.moduleCriterion(modv, pi, pj)) {
continue;
}
// if ( ! red.criterion4( pi, pj ) ) { continue; }
s = sred.leftSPolynomial(pi, pj);
if (s.isZERO()) {
continue;
}
h = sred.leftNormalform(F, s);
if (!h.isZERO()) {
return false;
}
}
}
return true;
}
/**
* Left Groebner base idempotence test.
* @param modv module variable number.
* @param F solvable polynomial list.
* @return true, if F is equal to GB(F), else false.
*/
public boolean isLeftGBidem(int modv, List> F) {
if (F == null || F.isEmpty()) {
return true;
}
GenSolvablePolynomialRing pring = F.get(0).ring;
List> G = leftGB(modv, F);
PolynomialList Fp = new PolynomialList(pring, F);
PolynomialList Gp = new PolynomialList(pring, G);
return Fp.compareTo(Gp) == 0;
}
/**
* Twosided Groebner base test.
* @param Fp solvable polynomial list.
* @return true, if Fp is a two-sided Groebner base, else false.
*/
public boolean isTwosidedGB(List> Fp) {
return isTwosidedGB(0, Fp);
}
/**
* Twosided Groebner base test.
* @param modv number of module variables.
* @param Fp solvable polynomial list.
* @return true, if Fp is a two-sided Groebner base, else false.
*/
public boolean isTwosidedGB(int modv, List> Fp) {
if (Fp == null || Fp.size() == 0) { // 0 not 1
return true;
}
GenSolvablePolynomialRing fac = Fp.get(0).ring; // assert != null
//List> X = generateUnivar( modv, Fp );
List> X = fac.univariateList(modv);
List> F = new ArrayList>(Fp.size() * (1 + X.size()));
F.addAll(Fp);
GenSolvablePolynomial p, x, pi, pj, s, h;
for (int i = 0; i < Fp.size(); i++) {
p = Fp.get(i);
for (int j = 0; j < X.size(); j++) {
x = X.get(j);
p = p.multiply(x);
p = sred.leftNormalform(F, p);
if (!p.isZERO()) {
F.add(p);
}
}
}
//System.out.println("F to check = " + F);
for (int i = 0; i < F.size(); i++) {
pi = F.get(i);
for (int j = i + 1; j < F.size(); j++) {
pj = F.get(j);
if (!red.moduleCriterion(modv, pi, pj)) {
continue;
}
// if ( ! red.criterion4( pi, pj ) ) { continue; }
s = sred.leftSPolynomial(pi, pj);
if (s.isZERO()) {
continue;
}
h = sred.leftNormalform(F, s);
if (!h.isZERO()) {
logger.info("is not TwosidedGB: " + h);
return false;
}
}
}
return true;
}
/**
* Twosided Groebner base idempotence test.
* @param F solvable polynomial list.
* @return true, if F is equal to GB(F), else false.
*/
public boolean isTwosidedGBidem(List> F) {
return isTwosidedGBidem(0, F);
}
/**
* Twosided Groebner base idempotence test.
* @param modv module variable number.
* @param F solvable polynomial list.
* @return true, if F is equal to GB(F), else false.
*/
public boolean isTwosidedGBidem(int modv, List> F) {
if (F == null || F.isEmpty()) {
return true;
}
GenSolvablePolynomialRing pring = F.get(0).ring;
List> G = twosidedGB(modv, F);
PolynomialList Fp = new PolynomialList(pring, F);
PolynomialList Gp = new PolynomialList(pring, G);
return Fp.compareTo(Gp) == 0;
}
/**
* Right Groebner base test.
* @param F solvable polynomial list.
* @return true, if F is a right Groebner base, else false.
*/
public boolean isRightGB(List> F) {
return isRightGB(0, F);
}
/**
* Right Groebner base test.
* @param modv number of module variables.
* @param F solvable polynomial list.
* @return true, if F is a right Groebner base, else false.
*/
public boolean isRightGB(int modv, List> F) {
GenSolvablePolynomial pi, pj, s, h;
for (int i = 0; i < F.size(); i++) {
pi = F.get(i);
//System.out.println("pi right = " + pi);
for (int j = i + 1; j < F.size(); j++) {
pj = F.get(j);
//System.out.println("pj right = " + pj);
if (!red.moduleCriterion(modv, pi, pj)) {
continue;
}
// if ( ! red.criterion4( pi, pj ) ) { continue; }
s = sred.rightSPolynomial(pi, pj);
if (s.isZERO()) {
continue;
}
//System.out.println("s right = " + s);
h = sred.rightNormalform(F, s);
if (!h.isZERO()) {
logger.info("isRightGB non zero h = " + h + " :: " + h.ring);
logger.info("p" + i + " = " + pi + ", p" + j + " = " + pj);
return false;
} else {
//logger.info("isRightGB zero h = " + h);
}
}
}
return true;
}
/**
* Right Groebner base idempotence test.
* @param F solvable polynomial list.
* @return true, if F is equal to GB(F), else false.
*/
public boolean isRightGBidem(List> F) {
return isRightGBidem(0, F);
}
/**
* Right Groebner base idempotence test.
* @param modv module variable number.
* @param F solvable polynomial list.
* @return true, if F is equal to GB(F), else false.
*/
public boolean isRightGBidem(int modv, List> F) {
if (F == null || F.isEmpty()) {
return true;
}
GenSolvablePolynomialRing pring = F.get(0).ring;
List> G = rightGB(modv, F);
PolynomialList Fp = new PolynomialList(pring, F);
PolynomialList Gp = new PolynomialList(pring, G);
return Fp.compareTo(Gp) == 0;
}
/**
* Left Groebner base using pairlist class.
* @param F solvable polynomial list.
* @return leftGB(F) a left Groebner base of F.
*/
public List> leftGB(List> F) {
return leftGB(0, F);
}
/**
* Solvable Extended Groebner base using critical pair class.
* @param F solvable polynomial list.
* @return a container for an extended left Groebner base of F.
*/
public SolvableExtendedGB extLeftGB(List> F) {
return extLeftGB(0, F);
}
/**
* Left minimal ordered groebner basis.
* @param Gp a left Groebner base.
* @return leftGBmi(F) a minimal left Groebner base of Gp.
*/
public List> leftMinimalGB(List> Gp) {
ArrayList> G = new ArrayList>();
ListIterator> it = Gp.listIterator();
for (GenSolvablePolynomial a : Gp) {
// a = (SolvablePolynomial) it.next();
if (a.length() != 0) { // always true
// already monic a = a.monic();
G.add(a);
}
}
if (G.size() <= 1) {
return G;
}
ExpVector e;
ExpVector f;
GenSolvablePolynomial a, p;
ArrayList> F = new ArrayList>();
boolean mt;
while (G.size() > 0) {
a = G.remove(0);
e = a.leadingExpVector();
it = G.listIterator();
mt = false;
while (it.hasNext() && !mt) {
p = it.next();
f = p.leadingExpVector();
mt = e.multipleOf(f);
}
it = F.listIterator();
while (it.hasNext() && !mt) {
p = it.next();
f = p.leadingExpVector();
mt = e.multipleOf(f);
}
if (!mt) {
F.add(a);
} else {
// System.out.println("dropped " + a.length());
}
}
G = F;
if (G.size() <= 1) {
return G;
}
F = new ArrayList>();
while (G.size() > 0) {
a = G.remove(0);
// System.out.println("doing " + a.length());
a = sred.leftNormalform(G, a);
a = sred.leftNormalform(F, a);
F.add(a);
}
return F;
}
/**
* Twosided Groebner base using pairlist class.
* @param Fp solvable polynomial list.
* @return tsGB(Fp) a twosided Groebner base of Fp.
*/
public List> twosidedGB(List> Fp) {
return twosidedGB(0, Fp);
}
/**
* Right Groebner base using opposite ring left GB.
* @param F solvable polynomial list.
* @return rightGB(F) a right Groebner base of F.
*/
public List> rightGB(List> F) {
return rightGB(0, F);
}
/**
* Right Groebner base using opposite ring left GB.
* @param modv number of module variables.
* @param F solvable polynomial list.
* @return rightGB(F) a right Groebner base of F.
*/
@SuppressWarnings("unchecked")
public List> rightGB(int modv, List> F) {
GenSolvablePolynomialRing ring = null;
for (GenSolvablePolynomial p : F) {
if (p != null) {
ring = p.ring;
break;
}
}
if (ring == null) {
return F;
}
GenSolvablePolynomialRing rring = ring.reverse(true); //true
//System.out.println("reversed ring = " + rring);
//ring = rring.reverse(true); // true
GenSolvablePolynomial q;
List> rF;
rF = new ArrayList>(F.size());
for (GenSolvablePolynomial p : F) {
if (p != null) {
q = (GenSolvablePolynomial) p.reverse(rring);
rF.add(q);
}
}
if (true || debug) {
PolynomialList pl = new PolynomialList(rring, rF);
logger.info("reversed problem = " + pl);
}
//System.out.println("reversed problem = " + rF);
List> rG = leftGB(modv, rF);
if (true || debug) {
//PolynomialList pl = new PolynomialList(rring,rG);
//logger.info("reversed GB = " + pl);
long t = System.currentTimeMillis();
boolean isit = isLeftGB(rG);
t = System.currentTimeMillis() - t;
logger.info("is left GB = " + isit + ", in " + t + " milliseconds");
}
//System.out.println("reversed left GB = " + rG);
ring = rring.reverse(true); // true
List> G = new ArrayList>(rG.size());
for (GenSolvablePolynomial p : rG) {
if (p != null) {
q = (GenSolvablePolynomial) p.reverse(ring);
G.add(q);
}
}
if (true || debug) {
//PolynomialList pl = new PolynomialList(ring,G);
//logger.info("GB = " + pl);
long t = System.currentTimeMillis();
boolean isit = isRightGB(G);
t = System.currentTimeMillis() - t;
logger.info("is right GB = " + isit + ", in " + t + " milliseconds");
}
return G;
}
/**
* Test if left reduction matrix.
* @param exgb an SolvableExtendedGB container.
* @return true, if exgb contains a left reduction matrix, else false.
*/
public boolean isLeftReductionMatrix(SolvableExtendedGB exgb) {
if (exgb == null) {
return true;
}
return isLeftReductionMatrix(exgb.F, exgb.G, exgb.F2G, exgb.G2F);
}
/**
* Test if left reduction matrix.
* @param F a solvable polynomial list.
* @param G a left Groebner base.
* @param Mf a possible left reduction matrix.
* @param Mg a possible left reduction matrix.
* @return true, if Mg and Mf are left reduction matrices, else false.
*/
public boolean isLeftReductionMatrix(List> F, List> G,
List>> Mf, List>> Mg) {
// no more check G and Mg: G * Mg[i] == 0
// check F and Mg: F * Mg[i] == G[i]
int k = 0;
for (List> row : Mg) {
boolean t = sred.isLeftReductionNF(row, F, G.get(k), null);
if (!t) {
System.out.println("row = " + row);
System.out.println("F = " + F);
System.out.println("Gk = " + G.get(k));
logger.info("F isLeftReductionMatrix s, k = " + F.size() + ", " + k);
return false;
}
k++;
}
// check G and Mf: G * Mf[i] == F[i]
k = 0;
for (List> row : Mf) {
boolean t = sred.isLeftReductionNF(row, G, F.get(k), null);
if (!t) {
logger.error("G isLeftReductionMatrix s, k = " + G.size() + ", " + k);
return false;
}
k++;
}
return true;
}
/**
* Ideal common zero test.
* @return -1, 0 or 1 if dimension(this) &eq; -1, 0 or ≥ 1.
*/
public int commonZeroTest(List> A) {
List> cA = PolynomialList. castToList(A);
return cbb.commonZeroTest(cA);
}
/**
* Univariate head term degrees.
* @param A list of solvable polynomials.
* @return a list of the degrees of univariate head terms.
*/
public List univariateDegrees(List> A) {
List> cA = PolynomialList. castToList(A);
return cbb.univariateDegrees(cA);
}
/**
* Construct univariate solvable polynomial of minimal degree in variable i
* of a zero dimensional ideal(G).
* @param i variable index.
* @param G list of solvable polynomials, a monic reduced left Gröbner
* base of a zero dimensional ideal.
* @return univariate solvable polynomial of minimal degree in variable i in
* ideal_left(G)
*/
public GenSolvablePolynomial constructUnivariate(int i, List> G) {
if (G == null || G.size() == 0) {
throw new IllegalArgumentException("G may not be null or empty");
}
List ud = univariateDegrees(G);
if (ud.size() <= i) {
//logger.info("univ pol, ud = " + ud);
throw new IllegalArgumentException("ideal(G) not zero dimensional " + ud);
}
int ll = 0;
Long di = ud.get(i);
if (di != null) {
ll = (int) (long) di;
} else {
throw new IllegalArgumentException("ideal(G) not zero dimensional");
}
long vsdim = 1;
for (Long d : ud) {
if (d != null) {
vsdim *= d;
}
}
logger.info("univariate construction, deg = " + ll + ", vsdim = " + vsdim);
GenSolvablePolynomialRing pfac = G.get(0).ring;
RingFactory cfac = pfac.coFac;
GenPolynomialRing cpfac = new GenPolynomialRing(cfac, ll, new TermOrder(TermOrder.INVLEX));
GenSolvablePolynomialRing> rfac = new GenSolvablePolynomialRing>(
cpfac, pfac); // relations
GenSolvablePolynomial> P = rfac.getZERO();
for (int k = 0; k < ll; k++) {
GenSolvablePolynomial> Pp = rfac.univariate(i, k);
GenPolynomial cp = cpfac.univariate(cpfac.nvar - 1 - k);
Pp = Pp.multiply(cp);
P = (GenSolvablePolynomial>) P.sum(Pp);
}
if (debug) {
logger.info("univariate construction, P = " + P);
logger.info("univariate construction, deg_*(G) = " + ud);
//throw new RuntimeException("check");
}
GroebnerBaseAbstract bbc = new GroebnerBaseSeq();
GenSolvablePolynomial X;
GenSolvablePolynomial XP;
// solve system of linear equations for the coefficients of the univariate polynomial
List> ls;
int z = -1;
do {
//System.out.println("ll = " + ll);
GenSolvablePolynomial> Pp = rfac.univariate(i, ll);
GenPolynomial cp = cpfac.univariate(cpfac.nvar - 1 - ll);
Pp = Pp.multiply(cp);
P = (GenSolvablePolynomial>) P.sum(Pp);
X = pfac.univariate(i, ll);
XP = sred.leftNormalform(G, X);
//System.out.println("XP = " + XP);
GenSolvablePolynomial> XPp = PolyUtil. toRecursive(rfac, XP);
GenSolvablePolynomial> XPs = (GenSolvablePolynomial>) XPp
.sum(P);
ls = new ArrayList>(XPs.getMap().values());
//System.out.println("ls,1 = " + ls);
ls = red.irreducibleSet(ls);
z = bbc.commonZeroTest(ls);
if (z != 0) {
ll++;
if (ll > vsdim) {
logger.info("univariate construction, P = " + P);
logger.info("univariate construction, nf(P) = " + XP);
logger.info("G = " + G);
throw new ArithmeticException(
"univariate polynomial degree greater than vector space dimansion");
}
cpfac = cpfac.extend(1);
rfac = new GenSolvablePolynomialRing>(cpfac, pfac);
P = PolyUtil. extendCoefficients(rfac, P, 0, 0L);
XPp = PolyUtil. extendCoefficients(rfac, XPp, 0, 1L);
P = (GenSolvablePolynomial>) P.sum(XPp);
}
} while (z != 0); // && ll <= 5 && !XP.isZERO()
// construct result polynomial
String var = pfac.getVars()[pfac.nvar - 1 - i];
GenSolvablePolynomialRing ufac = new GenSolvablePolynomialRing(cfac, 1, new TermOrder(
TermOrder.INVLEX), new String[] { var });
GenSolvablePolynomial pol = ufac.univariate(0, ll);
for (GenPolynomial pc : ls) {
ExpVector e = pc.leadingExpVector();
if (e == null) {
continue;
}
int[] v = e.dependencyOnVariables();
if (v == null || v.length == 0) {
continue;
}
int vi = v[0];
C tc = pc.trailingBaseCoefficient();
tc = tc.negate();
GenSolvablePolynomial pi = ufac.univariate(0, ll - 1 - vi);
pi = pi.multiply(tc);
pol = (GenSolvablePolynomial) pol.sum(pi);
}
if (logger.isInfoEnabled()) {
logger.info("univariate construction, pol = " + pol);
}
return pol;
}
/**
* Construct univariate solvable polynomials of minimal degree in all
* variables in zero dimensional left ideal(G).
* @return list of univariate polynomial of minimal degree in each variable
* in ideal_left(G)
*/
public List> constructUnivariate(List> G) {
List> univs = new ArrayList>();
if (G == null || G.isEmpty()) {
return univs;
}
for (int i = G.get(0).ring.nvar - 1; i >= 0; i--) {
GenSolvablePolynomial u = constructUnivariate(i, G);
univs.add(u);
}
return univs;
}
/**
* Cleanup and terminate ThreadPool.
*/
public void terminate() {
logger.info("terminate not implemented");
//throw new RuntimeException("get a stack trace");
}
/**
* Cancel ThreadPool.
*/
public int cancel() {
logger.info("cancel not implemented");
return 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy