/*
* $Id$
*/
package edu.jas.gbmod;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import edu.jas.gb.ExtendedGB;
import edu.jas.gb.GroebnerBase;
import edu.jas.gb.Reduction;
import edu.jas.gb.ReductionSeq;
import edu.jas.gbufd.GBFactory;
import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.ModuleList;
import edu.jas.poly.PolynomialList;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingElem;
import edu.jas.vector.BasicLinAlg;
import edu.jas.vector.GenVector;
import edu.jas.vector.GenVectorModul;
/**
* SyzygyAbstract class. Implements Syzygy computations and tests.
* @param coefficient type
* @author Heinz Kredel
*/
public class SyzygyAbstract> implements Syzygy {
private static final Logger logger = Logger.getLogger(SyzygyAbstract.class);
private final boolean debug = logger.isDebugEnabled();
/**
* Reduction engine.
*/
protected Reduction red;
/**
* Linear algebra engine.
*/
protected BasicLinAlg> blas;
/**
* Constructor.
*/
public SyzygyAbstract() {
red = new ReductionSeq();
blas = new BasicLinAlg>();
//gb = new GroebnerBaseSeqPairSeq();
//gb = new GroebnerBaseSeq();
//gb = GBFactory. getImplementation();
}
/**
* Syzygy module from Groebner base. F must be a Groebner base.
* @param F a Groebner base.
* @return syz(F), a basis for the module of syzygies for F.
*/
public List>> zeroRelations(List> F) {
return zeroRelations(0, F);
}
/**
* Syzygy module from Groebner base. F must be a Groebner base.
* @param modv number of module variables.
* @param F a Groebner base.
* @return syz(F), a basis for the module of syzygies for F.
*/
public List>> zeroRelations(int modv, List> F) {
List>> Z = new ArrayList>>();
if (F == null) {
return Z;
}
GenVectorModul> mfac = null;
int i = 0;
while (mfac == null && i < F.size()) {
GenPolynomial p = F.get(i);
if (p != null) {
mfac = new GenVectorModul>(p.ring, F.size());
}
}
if (mfac == null) {
return Z;
}
GenVector> v = mfac.fromList(F);
//System.out.println("F = " + F + " v = " + v);
return zeroRelations(modv, v);
}
/**
* Syzygy module from Groebner base. v must be a Groebner base.
* @param modv number of module variables.
* @param v a Groebner base.
* @return syz(v), a basis for the module of syzygies for v.
*/
public List>> zeroRelations(int modv, GenVector> v) {
List>> Z = new ArrayList>>();
GenVectorModul> mfac = v.modul;
List> F = v.val;
GenVector> S = mfac.getZERO();
GenPolynomial pi, pj, s, h;
//zero = mfac.coFac.getZERO();
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);
//logger.info("p"+i+", p"+j+" = " + pi + ", " +pj);
if (!red.moduleCriterion(modv, pi, pj)) {
continue;
}
// if ( ! red.criterion4( pi, pj ) ) { continue; }
List> row = S.copy().val;
s = red.SPolynomial(row, i, pi, j, pj);
if (s.isZERO()) {
Z.add(row);
continue;
}
h = red.normalform(row, F, s);
if (!h.isZERO()) {
throw new RuntimeException("Syzygy no GB");
}
if (debug) {
logger.info("row = " + row.size());
}
Z.add(row);
}
}
return Z;
}
/**
* Syzygy module from module Groebner base. M must be a module Groebner
* base.
* @param M a module Groebner base.
* @return syz(M), a basis for the module of syzygies for M.
*/
public ModuleList zeroRelations(ModuleList M) {
ModuleList N = M;
if (M == null || M.list == null) {
return N;
}
if (M.rows == 0 || M.cols == 0) {
return N;
}
GenPolynomial zero = M.ring.getZERO();
//System.out.println("zero = " + zero);
//ModuleList Np = null;
PolynomialList F = M.getPolynomialList();
int modv = M.cols; // > 0
//System.out.println("modv = " + modv);
List>> G = zeroRelations(modv, F.list);
//if (G == null) {
// return N;
//}
List>> Z = new ArrayList>>();
for (int i = 0; i < G.size(); i++) {
//F = new PolynomialList(F.ring,(List)G.get(i));
List> Gi = G.get(i);
List> Zi = new ArrayList>();
// System.out.println("\nG("+i+") = " + G.get(i));
for (int j = 0; j < Gi.size(); j++) {
//System.out.println("\nG("+i+","+j+") = " + Gi.get(j));
GenPolynomial p = Gi.get(j);
if (p != null) {
Map> r = p.contract(M.ring);
int s = 0;
for (GenPolynomial vi : r.values()) {
Zi.add(vi);
s++;
}
if (s == 0) {
Zi.add(zero);
} else if (s > 1) { // will not happen
System.out.println("p = " + p);
System.out.println("map(" + i + "," + j + ") = " + r + ", size = " + r.size());
throw new RuntimeException("Map.size() > 1 = " + r.size());
}
}
}
//System.out.println("\nZ("+i+") = " + Zi);
Z.add(Zi);
}
N = new ModuleList(M.ring, Z);
//System.out.println("\n\nN = " + N);
return N;
}
/**
* Test if sysygy.
* @param Z list of sysygies.
* @param F a polynomial list.
* @return true, if Z is a list of syzygies for F, else false.
*/
public boolean isZeroRelation(List>> Z, List> F) {
for (List> row : Z) {
GenPolynomial p = blas.scalarProduct(row, F);
if (p == null) {
continue;
}
if (!p.isZERO()) {
logger.info("is not ZeroRelation = " + p.toString(p.ring.getVars()));
logger.info("row = " + row);
//logger.info("F = " + F);
return false;
}
}
return true;
}
/**
* Test if sysygy of modules.
* @param Z list of sysygies.
* @param F a module list.
* @return true, if Z is a list of syzygies for F, else false.
*/
public boolean isZeroRelation(ModuleList Z, ModuleList F) {
if (Z == null || Z.list == null) {
return true;
}
for (List> row : Z.list) {
List> zr = blas.leftScalarProduct(row, F.list);
if (!blas.isZero(zr)) {
logger.info("is not ZeroRelation (" + zr.size() + ") = " + zr);
return false;
}
}
return true;
}
/**
* Resolution of a module. Only with direct GBs.
* @param M a module list of a Groebner basis.
* @return a resolution of M.
*/
public List> resolution(ModuleList M) {
List> R = new ArrayList>();
ModuleList MM = M;
ModuleList GM;
ModuleList Z;
ModGroebnerBase mbb = new ModGroebnerBaseAbstract(M.ring.coFac);
while (true) {
GM = mbb.GB(MM);
Z = zeroRelations(GM);
R.add(new ResPart(MM, GM, Z));
if (Z == null || Z.list == null || Z.list.size() == 0) {
break;
}
MM = Z;
}
return R;
}
/**
* Resolution of a polynomial list. Only with direct GBs.
* @param F a polynomial list of a Groebner basis.
* @return a resolution of F.
*/
@SuppressWarnings("unchecked")
public List // |ResPolPart>
resolution(PolynomialList F) {
List>> Z;
ModuleList Zm;
List> G;
PolynomialList Gl;
GroebnerBase gb = GBFactory.getImplementation(F.ring.coFac);
G = gb.GB(F.list);
Z = zeroRelations(G);
Gl = new PolynomialList(F.ring, G);
Zm = new ModuleList(F.ring, Z);
List R = resolution(Zm); //// |ResPolPart>
R.add(0, new ResPolPart(F, Gl, Zm));
return R;
}
/**
* Resolution of a polynomial list.
* @param F a polynomial list of an arbitrary basis.
* @return a resolution of F.
*/
@SuppressWarnings("unchecked")
public List // |ResPolPart>
resolutionArbitrary(PolynomialList F) {
List>> Z;
ModuleList Zm;
//List> G;
PolynomialList Gl = null;
//G = (new GroebnerBaseSeq()).GB( F.list );
Z = zeroRelationsArbitrary(F.list);
//Gl = new PolynomialList(F.ring, F.list);
Zm = new ModuleList(F.ring, Z);
List R = resolutionArbitrary(Zm); //// |ResPolPart>
R.add(0, new ResPolPart(F, Gl, Zm));
return R;
}
/**
* Resolution of a module.
* @param M a module list of an arbitrary basis.
* @return a resolution of M.
*/
public List> resolutionArbitrary(ModuleList M) {
List> R = new ArrayList>();
ModuleList MM = M;
ModuleList GM = null;
ModuleList Z;
//ModGroebnerBase mbb = new ModGroebnerBaseAbstract(M.ring.coFac);
while (true) {
//GM = mbb.GB(MM);
Z = zeroRelationsArbitrary(MM);
R.add(new ResPart(MM, GM, Z));
if (Z == null || Z.list == null || Z.list.size() == 0) {
break;
}
MM = Z;
}
return R;
}
/**
* Syzygy module from arbitrary base.
* @param F a polynomial list.
* @return syz(F), a basis for the module of syzygies for F.
*/
public List>> zeroRelationsArbitrary(List> F) {
return zeroRelationsArbitrary(0, F);
}
/**
* Syzygy module from arbitrary base.
* @param modv number of module variables.
* @param F a polynomial list.
* @return syz(F), a basis for the module of syzygies for F.
*/
public List>> zeroRelationsArbitrary(int modv, List> F) {
if (F == null) {
return new ArrayList>>();
//return zeroRelations(modv, F);
}
if (F.size() <= 1) {
return zeroRelations(modv, F);
}
GroebnerBase gb = GBFactory.getImplementation(F.get(0).ring.coFac);
final int lenf = F.size();
ExtendedGB exgb = gb.extGB(F);
if (debug) {
logger.debug("exgb = " + exgb);
if (!gb.isReductionMatrix(exgb)) {
logger.error("is reduction matrix ? false");
}
}
List> G = exgb.G;
List>> G2F = exgb.G2F;
List>> F2G = exgb.F2G;
List>> sg = zeroRelations(modv, G);
GenPolynomialRing ring = G.get(0).ring;
ModuleList S = new ModuleList(ring, sg);
if (debug) {
logger.debug("syz = " + S);
if (!isZeroRelation(sg, G)) {
logger.error("is syzygy ? false");
}
}
List>> sf;
sf = new ArrayList>>(sg.size());
//List> row;
for (List> r : sg) {
Iterator> it = r.iterator();
Iterator>> jt = G2F.iterator();
List> rf;
rf = new ArrayList>(lenf);
for (int m = 0; m < lenf; m++) {
rf.add(ring.getZERO());
}
while (it.hasNext() && jt.hasNext()) {
GenPolynomial si = it.next();
List> ai = jt.next();
//System.out.println("si = " + si);
//System.out.println("ai = " + ai);
if (si == null || ai == null) {
continue;
}
List> pi = blas.scalarProduct(si, ai);
//System.out.println("pi = " + pi);
rf = blas.vectorAdd(rf, pi);
}
if (it.hasNext() || jt.hasNext()) {
logger.error("zeroRelationsArbitrary wrong sizes");
}
//System.out.println("\nrf = " + rf + "\n");
sf.add(rf);
}
List>> M;
M = new ArrayList>>(lenf);
for (List> r : F2G) {
Iterator> it = r.iterator();
Iterator>> jt = G2F.iterator();
List> rf;
rf = new ArrayList>(lenf);
for (int m = 0; m < lenf; m++) {
rf.add(ring.getZERO());
}
while (it.hasNext() && jt.hasNext()) {
GenPolynomial si = it.next();
List> ai = jt.next();
//System.out.println("si = " + si);
//System.out.println("ai = " + ai);
if (si == null || ai == null) {
continue;
}
List> pi = blas.scalarProduct(ai, si);
//System.out.println("pi = " + pi);
rf = blas.vectorAdd(rf, pi);
}
if (it.hasNext() || jt.hasNext()) {
logger.error("zeroRelationsArbitrary wrong sizes");
}
//System.out.println("\nMg Mf = " + rf + "\n");
M.add(rf);
}
//ModuleList ML = new ModuleList( ring, M );
//System.out.println("syz ML = " + ML);
// debug only:
/* not true in general
List> F2 = new ArrayList>( F.size() );
for ( List> rr: M ) {
GenPolynomial rrg = blas.scalarProduct( F, rr );
F2.add( rrg );
}
PolynomialList pF = new PolynomialList( ring, F );
PolynomialList pF2 = new PolynomialList( ring, F2 );
if ( ! pF.equals( pF2 ) ) {
logger.error("is FAB = F ? false");
}
*/
int sflen = sf.size();
List>> M2;
M2 = new ArrayList>>(lenf);
int i = 0;
for (List> ri : M) {
List> r2i;
r2i = new ArrayList>(ri.size());
int j = 0;
for (GenPolynomial rij : ri) {
GenPolynomial p = null;
if (i == j) {
p = ring.getONE().subtract(rij);
} else {
if (rij != null) {
p = rij.negate();
}
}
r2i.add(p);
j++;
}
M2.add(r2i);
if (!blas.isZero(r2i)) {
sf.add(r2i);
}
i++;
}
if (debug) {
ModuleList M2L = new ModuleList(ring, M2);
logger.debug("syz M2L = " + M2L);
ModuleList SF = new ModuleList(ring, sf);
logger.debug("syz sf = " + SF);
logger.debug("#syz " + sflen + ", " + sf.size());
if (!isZeroRelation(sf, F)) {
logger.error("is syz sf ? false");
}
}
return sf;
}
/**
* Syzygy module from arbitrary module base.
* @param M an arbitrary module base.
* @return syz(M), a basis for the module of syzygies for M.
*/
public ModuleList zeroRelationsArbitrary(ModuleList M) {
ModuleList N = M;
if (M == null || M.list == null) {
return N;
}
if (M.rows == 0 || M.cols == 0) {
return N;
}
GenPolynomial zero = M.ring.getZERO();
//System.out.println("zero = " + zero);
//ModuleList Np = null;
PolynomialList F = M.getPolynomialList();
int modv = M.cols; // > 0
//System.out.println("modv = " + modv);
List>> G = zeroRelationsArbitrary(modv, F.list);
//if (G == null) {
// return N;
//}
List>> Z = new ArrayList>>();
for (int i = 0; i < G.size(); i++) {
//F = new PolynomialList(F.ring,(List)G.get(i));
List> Gi = G.get(i);
List> Zi = new ArrayList>();
// System.out.println("\nG("+i+") = " + G.get(i));
for (int j = 0; j < Gi.size(); j++) {
//System.out.println("\nG("+i+","+j+") = " + Gi.get(j));
GenPolynomial p = Gi.get(j);
if (p != null) {
Map> r = p.contract(M.ring);
int s = 0;
for (GenPolynomial vi : r.values()) {
Zi.add(vi);
s++;
}
if (s == 0) {
Zi.add(zero);
} else if (s > 1) { // will not happen
System.out.println("p = " + p);
System.out.println("map(" + i + "," + j + ") = " + r + ", size = " + r.size());
throw new RuntimeException("Map.size() > 1 = " + r.size());
}
}
}
//System.out.println("\nZ("+i+") = " + Zi);
Z.add(Zi);
}
N = new ModuleList(M.ring, Z);
//System.out.println("\n\nN = " + N);
return N;
}
}
/**
* Container for module resolution components.
* @param coefficient type
*/
class ResPart> implements Serializable {
public final ModuleList module;
public final ModuleList GB;
public final ModuleList syzygy;
/**
* ResPart.
* @param m a module list.
* @param g a module list GB.
* @param z a syzygy module list.
*/
public ResPart(ModuleList m, ModuleList g, ModuleList z) {
module = m;
GB = g;
syzygy = z;
}
/**
* toString.
*/
@Override
public String toString() {
StringBuffer s = new StringBuffer("ResPart(\n");
s.append("module = " + module);
s.append("\n GB = " + GB);
s.append("\n syzygy = " + syzygy);
s.append(")");
return s.toString();
}
}
/**
* Container for polynomial resolution components.
*/
class ResPolPart> implements Serializable {
public final PolynomialList ideal;
public final PolynomialList GB;
public final ModuleList syzygy;
/**
* ResPolPart.
* @param m a polynomial list.
* @param g a polynomial list GB.
* @param z a syzygy module list.
*/
public ResPolPart(PolynomialList m, PolynomialList g, ModuleList z) {
ideal = m;
GB = g;
syzygy = z;
}
/**
* toString.
*/
@Override
public String toString() {
StringBuffer s = new StringBuffer("ResPolPart(\n");
s.append("ideal = " + ideal);
s.append("\n GB = " + GB);
s.append("\n syzygy = " + syzygy);
s.append(")");
return s.toString();
}
}
Ads help maintain this website.