/*
* $Id$
*/
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.GenSolvablePolynomial;
import edu.jas.poly.GenSolvablePolynomialRing;
import edu.jas.poly.PolynomialList;
import edu.jas.structure.RingElem;
/**
* Solvable Groebner bases sequential algorithms. Implements common left, right
* and twosided Groebner bases and left, right and twosided GB tests.
* @param coefficient type
* @author Heinz Kredel.
*/
public class SolvableGroebnerBaseSeq> extends SolvableGroebnerBaseAbstract {
private static final Logger logger = Logger.getLogger(SolvableGroebnerBaseSeq.class);
private final boolean debug = logger.isDebugEnabled();
/**
* Constructor.
*/
public SolvableGroebnerBaseSeq() {
super();
}
/**
* Constructor.
* @param sred Solvable reduction engine
* @param pl pair selection strategy
*/
public SolvableGroebnerBaseSeq(SolvableReduction sred, PairList pl) {
super(sred, pl);
}
/**
* Left Groebner base using pairlist class.
* @param modv number of module variables.
* @param F solvable polynomial list.
* @return leftGB(F) a left Groebner base of F.
*/
@SuppressWarnings("unchecked")
public List> leftGB(int modv, List> F) {
List> G = new ArrayList>();
PairList pairlist = null;
int l = F.size();
// ListIterator it = F.listIterator();
for (GenSolvablePolynomial p : F) {
// p = (SolvablePolynomial) it.next();
if (p.length() > 0) {
p = (GenSolvablePolynomial) p.monic();
if (p.isONE()) {
G.clear();
G.add(p);
return G; // since no threads are activated
}
G.add(p);
if (pairlist == null) {
//pairlist = new OrderedPairlist( modv, p.ring );
pairlist = strategy.create(modv, p.ring);
}
// putOne not required
pairlist.put(p);
} else {
l--;
}
}
if (l <= 1) {
return G; // since no threads are activated
}
GenSolvablePolynomial pi, pj, S, H;
Pair pair;
while (pairlist.hasNext()) {
pair = pairlist.removeNext();
if (pair == null) {
continue;
}
pi = (GenSolvablePolynomial) pair.pi;
pj = (GenSolvablePolynomial) pair.pj;
if (debug) {
logger.info("pi = " + pi);
logger.info("pj = " + pj);
}
S = sred.leftSPolynomial(pi, pj);
if (S.isZERO()) {
pair.setZero();
continue;
}
if (debug) {
logger.info("ht(S) = " + S.leadingExpVector());
}
H = sred.leftNormalform(G, S);
if (H.isZERO()) {
pair.setZero();
continue;
}
if (debug) {
logger.info("ht(H) = " + H.leadingExpVector());
}
H = (GenSolvablePolynomial) H.monic();
if (H.isONE()) {
G.clear();
G.add(H);
return G; // since no threads are activated
}
if (debug) {
logger.info("H = " + H);
}
if (H.length() > 0) {
l++;
G.add(H);
pairlist.put(H);
}
}
logger.debug("#sequential list = " + G.size());
G = leftMinimalGB(G);
logger.info("" + pairlist);
return G;
}
/**
* Solvable Extended Groebner base using critical pair class.
* @param modv module variable number.
* @param F solvable polynomial list.
* @return a container for an extended left Groebner base of F.
*/
@SuppressWarnings("unchecked")
public SolvableExtendedGB extLeftGB(int modv, List> F) {
List> G = new ArrayList>();
List>> F2G = new ArrayList>>();
List>> G2F = new ArrayList>>();
PairList pairlist = null;
boolean oneInGB = false;
int len = F.size();
List> row = null;
List> rows = null;
List> rowh = null;
GenSolvablePolynomialRing ring = null;
GenSolvablePolynomial H;
GenSolvablePolynomial p;
int nzlen = 0;
for (GenSolvablePolynomial f : F) {
if (f.length() > 0) {
nzlen++;
}
if (ring == null) {
ring = f.ring;
}
}
GenSolvablePolynomial mone = ring.getONE(); //.negate();
int k = 0;
ListIterator> it = F.listIterator();
while (it.hasNext()) {
p = it.next();
if (p.length() > 0) {
row = new ArrayList>(nzlen);
for (int j = 0; j < nzlen; j++) {
row.add(null);
}
//C c = p.leadingBaseCoefficient();
//c = c.inverse();
//p = p.multiply( c );
row.set(k, mone); //.multiply(c) );
k++;
if (p.isUnit()) {
G.clear();
G.add(p);
G2F.clear();
G2F.add(row);
oneInGB = true;
break;
}
G.add(p);
G2F.add(row);
if (pairlist == null) {
//pairlist = new CriticalPairList( modv, p.ring );
pairlist = strategy.create(modv, p.ring);
}
// putOne not required
pairlist.put(p);
} else {
len--;
}
}
SolvableExtendedGB exgb;
if (len <= 1 || oneInGB) {
// adjust F2G
for (GenSolvablePolynomial f : F) {
row = new ArrayList>(G.size());
for (int j = 0; j < G.size(); j++) {
row.add(null);
}
H = sred.leftNormalform(row, G, f);
if (!H.isZERO()) {
logger.error("nonzero H = " + H);
}
F2G.add(row);
}
exgb = new SolvableExtendedGB(F, G, F2G, G2F);
//System.out.println("exgb 1 = " + exgb);
return exgb;
}
Pair pair;
int i, j;
GenSolvablePolynomial pi;
GenSolvablePolynomial pj;
GenSolvablePolynomial S;
GenSolvablePolynomial x;
GenSolvablePolynomial y;
//GenPolynomial z;
while (pairlist.hasNext() && !oneInGB) {
pair = pairlist.removeNext();
if (pair == null) {
//pairlist.update(); // ?
continue;
}
i = pair.i;
j = pair.j;
pi = (GenSolvablePolynomial) pair.pi;
pj = (GenSolvablePolynomial) pair.pj;
if (debug) {
logger.info("i, pi = " + i + ", " + pi);
logger.info("j, pj = " + j + ", " + pj);
}
rows = new ArrayList>(G.size());
for (int m = 0; m < G.size(); m++) {
rows.add(null);
}
S = sred.leftSPolynomial(rows, i, pi, j, pj);
if (debug) {
logger.debug("is reduction S = " + sred.isLeftReductionNF(rows, G, ring.getZERO(), S));
}
if (S.isZERO()) {
pair.setZero();
//pairlist.update( pair, S );
// do not add to G2F
continue;
}
if (debug) {
logger.debug("ht(S) = " + S.leadingExpVector());
}
rowh = new ArrayList>(G.size());
for (int m = 0; m < G.size(); m++) {
rowh.add(null);
}
H = sred.leftNormalform(rowh, G, S);
if (debug) {
//System.out.println("H = " + H);
logger.debug("is reduction H = " + sred.isLeftReductionNF(rowh, G, S, H));
}
if (H.isZERO()) {
pair.setZero();
//pairlist.update( pair, H );
// do not add to G2F
continue;
}
if (debug) {
logger.debug("ht(H) = " + H.leadingExpVector());
}
row = new ArrayList>(G.size() + 1);
for (int m = 0; m < G.size(); m++) {
x = rows.get(m);
if (x != null) {
//System.out.println("ms = " + m + " " + x);
x = (GenSolvablePolynomial) x.negate();
}
y = rowh.get(m);
if (y != null) {
y = (GenSolvablePolynomial) y.negate();
//System.out.println("mh = " + m + " " + y);
}
if (x == null) {
x = y;
} else {
x = (GenSolvablePolynomial) x.sum(y);
}
//System.out.println("mx = " + m + " " + x);
row.add(x);
}
if (debug) {
logger.debug("is reduction 0+sum(row,G) == H : "
+ sred.isLeftReductionNF(row, G, H, ring.getZERO()));
}
row.add(null);
// H = H.monic();
C c = H.leadingBaseCoefficient();
c = c.inverse();
H = H.multiply(c);
// 1*c*row, leads to wrong method dispatch:
row = PolynomialList. castToSolvableList(blas.scalarProduct(mone.multiply(c),
PolynomialList. castToList(row)));
row.set(G.size(), mone);
if (H.isONE()) {
// pairlist.record( pair, H );
// G.clear();
G.add(H);
G2F.add(row);
oneInGB = true;
break;
}
if (debug) {
logger.debug("H = " + H);
}
G.add(H);
//pairlist.update( pair, H );
pairlist.put(H);
G2F.add(row);
}
if (debug) {
exgb = new SolvableExtendedGB(F, G, F2G, G2F);
logger.info("exgb unnorm = " + exgb);
}
G2F = normalizeMatrix(F.size(), G2F);
if (debug) {
exgb = new SolvableExtendedGB(F, G, F2G, G2F);
logger.info("exgb nonmin = " + exgb);
boolean t2 = isLeftReductionMatrix(exgb);
logger.debug("exgb t2 = " + t2);
}
exgb = minimalSolvableExtendedGB(F.size(), G, G2F);
G = exgb.G;
G2F = exgb.G2F;
logger.debug("#sequential list = " + G.size());
logger.info("" + pairlist);
// setup matrices F and F2G
for (GenSolvablePolynomial f : F) {
row = new ArrayList>(G.size());
for (int m = 0; m < G.size(); m++) {
row.add(null);
}
H = sred.leftNormalform(row, G, f);
if (!H.isZERO()) {
logger.error("nonzero H = " + H);
}
F2G.add(row);
}
return new SolvableExtendedGB(F, G, F2G, G2F);
}
/**
* Twosided Groebner base using pairlist class.
* @param modv number of module variables.
* @param Fp solvable polynomial list.
* @return tsGB(Fp) a twosided Groebner base of Fp.
*/
@SuppressWarnings("unchecked")
public List> twosidedGB(int modv, List> Fp) {
if (Fp == null || Fp.size() == 0) { // 0 not 1
return new ArrayList>();
}
GenSolvablePolynomialRing fac = Fp.get(0).ring; // assert != null
//List> X = generateUnivar( modv, Fp );
List> X = fac.univariateList(modv);
//System.out.println("X univ = " + X);
List> F = new ArrayList>(Fp.size() * (1 + X.size()));
F.addAll(Fp);
GenSolvablePolynomial p, x, q;
for (int i = 0; i < Fp.size(); i++) {
p = Fp.get(i);
for (int j = 0; j < X.size(); j++) {
x = X.get(j);
q = p.multiply(x);
q = sred.leftNormalform(F, q);
if (!q.isZERO()) {
F.add(q);
}
}
}
//System.out.println("F generated = " + F);
List> G = new ArrayList>();
PairList pairlist = null;
int l = F.size();
ListIterator> it = F.listIterator();
while (it.hasNext()) {
p = it.next();
if (p.length() > 0) {
p = (GenSolvablePolynomial) p.monic();
if (p.isONE()) {
G.clear();
G.add(p);
return G; // since no threads are activated
}
G.add(p);
if (pairlist == null) {
// pairlist = new OrderedPairlist( modv, p.ring );
pairlist = strategy.create(modv, p.ring);
if ( ! p.ring.coFac.isField() ) {
//throw new IllegalArgumentException("coefficients not from a field");
logger.warn("coefficients not from a field " + p.ring.coFac);
}
}
// putOne not required
pairlist.put(p);
} else {
l--;
}
}
//System.out.println("G to check = " + G);
if (l <= 1) { // 1 ok
return G; // since no threads are activated
}
Pair pair;
GenSolvablePolynomial pi, pj, S, H;
while (pairlist.hasNext()) {
pair = pairlist.removeNext();
if (pair == null) {
continue;
}
pi = (GenSolvablePolynomial) pair.pi;
pj = (GenSolvablePolynomial) pair.pj;
if (debug) {
logger.debug("pi = " + pi);
logger.debug("pj = " + pj);
}
S = sred.leftSPolynomial(pi, pj);
if (S.isZERO()) {
pair.setZero();
continue;
}
if (debug) {
logger.debug("ht(S) = " + S.leadingExpVector());
}
H = sred.leftNormalform(G, S);
if (H.isZERO()) {
pair.setZero();
continue;
}
if (debug) {
logger.debug("ht(H) = " + H.leadingExpVector());
}
H = (GenSolvablePolynomial) H.monic();
if (H.isONE()) {
G.clear();
G.add(H);
return G; // since no threads are activated
}
if (debug) {
logger.debug("H = " + H);
}
if (H.length() > 0) {
l++;
G.add(H);
pairlist.put(H);
for (int j = 0; j < X.size(); j++) {
l++;
x = X.get(j);
p = H.multiply(x);
p = sred.leftNormalform(G, p);
if (!p.isZERO()) {
p = (GenSolvablePolynomial) p.monic();
if (p.isONE()) {
G.clear();
G.add(p);
return G; // since no threads are activated
}
G.add(p);
pairlist.put(p);
}
}
}
}
logger.debug("#sequential list = " + G.size());
G = leftMinimalGB(G);
logger.info("" + pairlist);
return G;
}
/**
* Normalize M. Make all rows the same size and make certain column elements
* zero.
* @param M a reduction matrix.
* @return normalized M.
*/
public List>> normalizeMatrix(int flen,
List>> M) {
if (M == null) {
return M;
}
if (M.size() == 0) {
return M;
}
List>> N = new ArrayList>>();
List>> K = new ArrayList>>();
int len = M.get(M.size() - 1).size(); // longest row
// pad / extend rows
for (List> row : M) {
List> nrow = new ArrayList>(row);
for (int i = row.size(); i < len; i++) {
nrow.add(null);
}
N.add(nrow);
}
// System.out.println("norm N fill = " + N);
// make zero columns
int k = flen;
for (int i = 0; i < N.size(); i++) { // 0
List> row = N.get(i);
if (debug) {
logger.info("row = " + row);
}
K.add(row);
if (i < flen) { // skip identity part
continue;
}
List> xrow;
GenSolvablePolynomial a;
//System.out.println("norm i = " + i);
for (int j = i + 1; j < N.size(); j++) {
List> nrow = N.get(j);
//System.out.println("nrow j = " +j + ", " + nrow);
if (k < nrow.size()) { // always true
a = nrow.get(k);
//System.out.println("k, a = " + k + ", " + a);
if (a != null && !a.isZERO()) { // a*row + nrow, leads to wrong method dispatch
List> yrow = blas.scalarProduct(a,
PolynomialList. castToList(row));
yrow = blas.vectorAdd(yrow, PolynomialList. castToList(nrow));
xrow = PolynomialList. castToSolvableList(yrow);
N.set(j, xrow);
}
}
}
k++;
}
//System.out.println("norm K reduc = " + K);
// truncate
N.clear();
for (List> row : K) {
List> tr = new ArrayList>();
for (int i = 0; i < flen; i++) {
tr.add(row.get(i));
}
N.add(tr);
}
K = N;
//System.out.println("norm K trunc = " + K);
return K;
}
/**
* Test if M is a left reduction matrix.
* @param exgb an SolvableExtendedGB container.
* @return true, if exgb contains a left reduction matrix, else false.
*/
@Override
public boolean isLeftReductionMatrix(SolvableExtendedGB exgb) {
if (exgb == null) {
return true;
}
return isLeftReductionMatrix(exgb.F, exgb.G, exgb.F2G, exgb.G2F);
}
/**
* Minimal solvable extended groebner basis.
* @param Gp a left Groebner base.
* @param M a left reduction matrix, is modified.
* @return a (partially) reduced left Groebner base of Gp in a container.
*/
public SolvableExtendedGB minimalSolvableExtendedGB(int flen, List> Gp,
List>> M) {
if (Gp == null) {
return null; //new SolvableExtendedGB(null,Gp,null,M);
}
if (Gp.size() <= 1) {
return new SolvableExtendedGB(null, Gp, null, M);
}
List> G;
List> F;
G = new ArrayList>(Gp);
F = new ArrayList>(Gp.size());
List>> Mg;
List>> Mf;
Mg = new ArrayList>>(M.size());
Mf = new ArrayList>>(M.size());
List> row;
for (List> r : M) {
// must be copied also
row = new ArrayList>(r);
Mg.add(row);
}
row = null;
GenSolvablePolynomial a;
ExpVector e;
ExpVector f;
GenSolvablePolynomial p;
boolean mt;
ListIterator> it;
ArrayList ix = new ArrayList();
ArrayList jx = new ArrayList();
int k = 0;
//System.out.println("flen, Gp, M = " + flen + ", " + Gp.size() + ", " + M.size() );
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);
}
//System.out.println("k, mt = " + k + ", " + mt);
if (!mt) {
F.add(a);
ix.add(k);
} else { // drop polynomial and corresponding row and column
// F.add( a.ring.getZERO() );
jx.add(k);
}
k++;
}
if (debug) {
logger.debug("ix, #M, jx = " + ix + ", " + Mg.size() + ", " + jx);
}
int fix = -1; // copied polys
// copy Mg to Mf as indicated by ix
for (int i = 0; i < ix.size(); i++) {
int u = ix.get(i);
if (u >= flen && fix == -1) {
fix = Mf.size();
}
//System.out.println("copy u, fix = " + u + ", " + fix);
if (u >= 0) {
row = Mg.get(u);
Mf.add(row);
}
}
if (F.size() <= 1 || fix == -1) {
return new SolvableExtendedGB(null, F, null, Mf);
}
// must return, since extended normalform has not correct order of polys
/*
G = F;
F = new ArrayList>( G.size() );
List> temp;
k = 0;
final int len = G.size();
while ( G.size() > 0 ) {
a = G.remove(0);
if ( k >= fix ) { // dont touch copied polys
row = Mf.get( k );
//System.out.println("doing k = " + k + ", " + a);
// must keep order, but removed polys missing
temp = new ArrayList>( len );
temp.addAll( F );
temp.add( a.ring.getZERO() ); // ??
temp.addAll( G );
//System.out.println("row before = " + row);
a = sred.leftNormalform( row, temp, a );
//System.out.println("row after = " + row);
}
F.add( a );
k++;
}
// does Mf need renormalization?
*/
return new SolvableExtendedGB(null, F, null, Mf);
}
}
Ads help maintain this website.