/*
* $Id$
*/
package edu.jas.poly;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.apache.log4j.Logger;
import edu.jas.kern.PrettyPrint;
import edu.jas.structure.RingElem;
/**
* RelationTable for solvable polynomials. This class maintains the
* non-commutative multiplication relations of solvable polynomial rings. The
* table entries are initialized with relations of the form xj *
* xi = pij. During multiplication the relations are
* updated by relations of the form xjk *
* xil = pijkl. If no relation for
* xj * xi is found in the table, this multiplication is
* assumed to be commutative xi xj. Can also be used for
* relations between coefficients and main variables.
* @author Heinz Kredel
*/
public class RelationTable> implements Serializable {
/**
* The data structure for the relations.
*/
public final Map, List> table;
/**
* The factory for the solvable polynomial ring.
*/
public final GenSolvablePolynomialRing ring;
/**
* Usage indicator: table or coeffTable.
*/
public final boolean coeffTable;
private static final Logger logger = Logger.getLogger(RelationTable.class);
private final boolean debug = logger.isDebugEnabled();
/**
* Constructor for RelationTable requires ring factory. Note: This
* constructor is called within the constructor of the ring factory, so
* methods of this class can only be used after the other constructor has
* terminated.
* @param r solvable polynomial ring factory.
*/
public RelationTable(GenSolvablePolynomialRing r) {
this(r, false);
}
/**
* Constructor for RelationTable requires ring factory. Note: This
* constructor is called within the constructor of the ring factory, so
* methods of this class can only be used after the other constructor has
* terminated.
* @param r solvable polynomial ring factory.
* @param coeffTable indicator for coeffTable.
*/
public RelationTable(GenSolvablePolynomialRing r, boolean coeffTable) {
table = new HashMap, List>();
ring = r;
if (ring == null) {
throw new IllegalArgumentException("RelationTable no ring");
}
this.coeffTable = coeffTable;
}
/**
* RelationTable equals. Tests same keySets only, not relations itself. Will
* be improved in the future.
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object p) {
if (!(p instanceof RelationTable)) {
logger.info("no RelationTable");
return false;
}
RelationTable tab = null;
try {
tab = (RelationTable) p;
} catch (ClassCastException ignored) {
}
if (tab == null) {
return false;
}
// not possible because of infinite recursion:
//if (!ring.equals(tab.ring)) {
// logger.info("not same Ring " + ring.toScript() + ", " + tab.ring.toScript());
// return false;
//}
if (!table.keySet().equals(tab.table.keySet())) {
logger.info("keySet != : a = " + table.keySet() + ", b = " + tab.table.keySet());
return false;
}
for (List k : table.keySet()) {
List a = table.get(k);
List b = tab.table.get(k);
// check contents, but only base relations
Map> t1ex = fromListDeg2(a);
Map> t2ex = fromListDeg2(b);
if (!equalMaps(t1ex, t2ex)) {
//System.out.println("a != b, a = " + t1ex + ", b = " + t2ex);
return false;
}
}
return true;
}
/**
* Convert mixed list to map for base relations.
* @param a mixed list
* @returns a map constructed from the list with deg(key) == 2.
*/
@SuppressWarnings("unchecked")
Map> fromListDeg2(List a) {
Map> tex = new HashMap>();
Iterator ait = a.iterator();
while (ait.hasNext()) {
ExpVectorPair ae = (ExpVectorPair) ait.next();
if (!ait.hasNext()) {
break;
}
GenPolynomial p = (GenPolynomial) ait.next();
if (ae.totalDeg() == 2) { // only base relations
//System.out.println("ae => p: " + ae + " => " + p);
tex.put(ae, p);
}
}
return tex;
}
/**
* Equals for special maps.
* @param m1 first map
* @param m2 second map
* @returns true if both maps are equal
*/
@SuppressWarnings("unchecked")
boolean equalMaps(Map> m1, Map> m2) {
if (!m1.keySet().equals(m2.keySet())) {
return false;
}
for (ExpVectorPair ep : m1.keySet()) {
GenPolynomial p1 = m1.get(ep);
GenPolynomial p2 = m2.get(ep);
if (p1.compareTo(p2) != 0) { // not working: !p1.equals(p2)) { // TODO
logger.info("ep = " + ep + ", p1 = " + p1 + ", p2 = " + p2);
//logger.info("p1.compareTo(p2) = " + p1.compareTo(p2));
//logger.info("p1.equals(p2) = " + p1.equals(p2));
return false;
}
}
return true;
}
/**
* Hash code for this relation table.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int h;
h = ring.hashCode();
h = 31 * h + table.hashCode();
return h;
}
/**
* Test if the table is empty.
* @return true if the table is empty, else false.
*/
public boolean isEmpty() {
return table.isEmpty();
}
/**
* Get the String representation.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
List v;
StringBuffer s = new StringBuffer("RelationTable[");
boolean first = true;
for (List k : table.keySet()) {
if (first) {
first = false;
} else {
s.append(", ");
}
s.append(k.toString());
v = table.get(k);
s.append("=");
s.append(v.toString());
}
s.append("]");
return s.toString();
}
/**
* Get the String representation.
* @param vars names for the variables.
* @see java.lang.Object#toString()
*/
@SuppressWarnings("unchecked")
public String toString(String[] vars) {
if (vars == null) {
return toString();
}
StringBuffer s = new StringBuffer("");
String[] cvars = null;
if (coeffTable) {
if (ring.coFac instanceof GenPolynomialRing) {
cvars = ((GenPolynomialRing) (Object)ring.coFac).getVars();
}
s.append("Coefficient ");
}
s.append("RelationTable\n(");
List v;
if (PrettyPrint.isTrue()) {
boolean first = true;
for (List k : table.keySet()) {
if (first) {
first = false;
s.append("\n");
} else {
s.append(",\n");
}
v = table.get(k);
for (Iterator jt = v.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
if (ep.totalDeg() != 2) { // only base relations
continue;
}
s.append("( " + ep.getFirst().toString(vars) + " ), ");
if (cvars == null) {
s.append("( " + ep.getSecond().toString(vars) + " ), ");
} else {
s.append("( " + ep.getSecond().toString(cvars) + " ), ");
}
s.append("( " + p.toString(vars) + " )");
if (jt.hasNext()) {
s.append(",\n");
}
}
}
} else {
boolean first = true;
for (List k : table.keySet()) {
if (first) {
first = false;
} else {
s.append(",\n");
}
v = table.get(k);
for (Iterator jt = v.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
s.append("( " + ep.getFirst().toString(vars) + " ), ");
if (coeffTable) {
s.append("( " + ep.getSecond().toString(cvars) + " ), ");
} else {
s.append("( " + ep.getSecond().toString(vars) + " ), ");
}
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
//s.append("( " + p.toString(vars) + " )");
s.append(" " + p.toString(vars));
if (jt.hasNext()) {
s.append(",\n");
}
}
}
}
s.append("\n)\n");
return s.toString();
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this relation table.
*/
@SuppressWarnings("unchecked")
public String toScript() {
// Python case
String[] vars = ring.vars;
String[] cvars = null;
if (coeffTable) {
cvars = ((GenPolynomialRing) (Object)ring.coFac).vars;
}
List v;
StringBuffer s = new StringBuffer("[");
boolean first = true;
for (List k : table.keySet()) {
if (first) {
first = false;
s.append("");
} else {
s.append(", ");
}
v = table.get(k);
for (Iterator jt = v.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
GenPolynomial p = (GenPolynomial) jt.next();
if (ep.totalDeg() != 2) { // only base relations
continue;
}
s.append("" + ep.getFirst().toScript(vars) + ", ");
if (coeffTable) {
s.append("" + ep.getSecond().toScript(cvars) + ", ");
} else {
s.append("" + ep.getSecond().toScript(vars) + ", ");
}
//s.append("( " + p.toScript() + " )");
s.append(" " + p.toScript());
if (jt.hasNext()) {
s.append(", ");
}
}
}
s.append("]");
return s.toString();
}
/**
* Update or initialize RelationTable with new relation. relation is e * f =
* p.
* @param e first term.
* @param f second term.
* @param p solvable product polynomial.
*/
@SuppressWarnings("unchecked")
public synchronized void update(ExpVector e, ExpVector f, GenSolvablePolynomial p) {
if (debug) {
//System.out.println("new relation = " + e + " .*. " + f + " = " + p);
if (p != null && p.ring.vars != null) {
logger.info("new relation = " + e.toString(p.ring.vars) + " .*. " + f.toString(p.ring.vars)
+ " = " + p);
//logger.info("existing relations = " + toString(p.ring.vars));
} else {
logger.info("new relation = " + e + " .*. " + f + " = " + p);
}
}
if (p == null || e == null || f == null) {
throw new IllegalArgumentException("RelationTable update e|f|p == null");
}
if (debug) {
if (e.totalDeg() == 1 && f.totalDeg() == 1) {
int[] de = e.dependencyOnVariables();
int[] df = f.dependencyOnVariables();
logger.debug("update e ? f " + de[0] + " " + df[0]);
//int t = ring.tord.getDescendComparator().compare(e,f);
//System.out.println("update compare(e,f) = " + t);
if (de[0] == df[0]) { // error
throw new IllegalArgumentException("RelationTable update e==f");
}
if (de[0] > df[0]) { // invalid update
logger.error("warning: update e > f " + e + " " + f + " changed");
ExpVector tmp = e;
e = f;
f = tmp;
Map.Entry m = p.leadingMonomial();
GenPolynomial r = p.subtract(m.getValue(), m.getKey());
r = r.negate();
p = (GenSolvablePolynomial) r.sum(m.getValue(), m.getKey());
}
}
}
// test equal HTs for left and right side
if (!coeffTable) {
ExpVector ef = e.sum(f);
ExpVector lp = p.leadingExpVector();
if (!ef.equals(lp)) { // check for suitable term order
logger.error("relation term order = " + ring.tord);
throw new IllegalArgumentException("RelationTable update e*f != lt(p): " + ef + ", lp = "
+ lp);
}
} else {
ExpVector lp = p.leadingExpVector();
if (!e.equals(lp)) { // check for suitable term order
logger.error("relation term order = " + ring.tord);
throw new IllegalArgumentException("Coefficient RelationTable update e != lt(p): " + e
+ ", lp = " + lp);
}
if (p.leadingBaseCoefficient() instanceof GenPolynomial) {
lp = ((GenPolynomial) (Object)p.leadingBaseCoefficient()).leadingExpVector();
if (!f.equals(lp)) { // check for suitable term order
logger.error("relation term order = " + ring.tord);
logger.error("Coefficient RelationTable update f != lt(lfcd(p)): " + e + ", f = " + f
+ ", p = " + p);
throw new IllegalArgumentException("Coefficient RelationTable update f != lt(lfcd(p)): "
+ e + ", f = " + f + ", p = " + p);
}
}
}
List key = makeKey(e, f);
ExpVectorPair evp = new ExpVectorPair(e, f);
if (key.size() != 2) {
logger.warn("key = " + key + ", evp = " + evp);
}
List part = table.get(key);
if (part == null) { // initialization only
part = new LinkedList();
part.add(evp);
part.add(p);
table.put(key, part);
return;
}
Object skip;
int index = -1;
synchronized (part) { // with lookup()
for (ListIterator it = part.listIterator(); it.hasNext();) {
ExpVectorPair look = (ExpVectorPair) it.next();
skip = it.next(); // skip poly
if (look.isMultiple(evp)) {
index = it.nextIndex();
// last index of or first index of: break
}
}
if (index < 0) {
index = 0;
}
part.add(index, evp);
part.add(index + 1, p);
}
// table.put( key, part ); // required??
}
/**
* Update or initialize RelationTable with new relation. relation is e * f =
* p.
* @param E first term polynomial.
* @param F second term polynomial.
* @param p solvable product polynomial.
*/
@SuppressWarnings("unchecked")
public void update(GenPolynomial E, GenPolynomial F, GenSolvablePolynomial p) {
if (E.isZERO() || F.isZERO()) {
throw new IllegalArgumentException("polynomials may not be zero: " + E + ", " + F);
}
C ce = E.leadingBaseCoefficient();
C cf = F.leadingBaseCoefficient();
if (!ce.isONE()) {
throw new IllegalArgumentException("lbcf of polynomials must be one: " + ce + ", " + cf
+ ", p = " + p);
}
ExpVector e = E.leadingExpVector();
ExpVector f = F.leadingExpVector();
if (coeffTable && f.isZERO() && cf instanceof GenPolynomial) {
f = ((GenPolynomial) (Object)cf).leadingExpVector();
}
//logger.info("update: " + e + " .*. " + f + " = " + p);
update(e, f, p);
}
/**
* Update or initialize RelationTable with new relation. relation is e * f =
* p.
* @param E first term polynomial.
* @param F second term polynomial.
* @param p product polynomial.
*/
public void update(GenPolynomial E, GenPolynomial F, GenPolynomial p) {
if (p.isZERO()) {
throw new IllegalArgumentException("polynomial may not be zero: " + p);
}
if (p.isONE()) {
throw new IllegalArgumentException("product of polynomials may not be one: " + p);
}
GenSolvablePolynomial sp = new GenSolvablePolynomial(ring, p.val);
update(E, F, sp);
}
/**
* Update or initialize RelationTable with new relation. relation is e * f =
* p.
* @param e first term.
* @param f second term.
* @param p solvable product polynomial.
*/
public void update(ExpVector e, ExpVector f, GenPolynomial p) {
if (p.isZERO()) {
throw new IllegalArgumentException("polynomial may not be zero: " + p);
}
if (p.isONE()) {
throw new IllegalArgumentException("product of polynomials may not be one: " + p);
}
GenSolvablePolynomial sp = new GenSolvablePolynomial(ring, p.val);
update(e, f, sp);
}
/**
* Lookup RelationTable for existing relation. Find p with e * f = p. If no
* relation for e * f is contained in the table then return the symmetric
* product p = 1 e f.
* @param e first term.
* @param f second term.
* @return t table relation container, contains e' and f' with e f = e'
* lt(p) f'.
*/
@SuppressWarnings("unchecked")
public TableRelation lookup(ExpVector e, ExpVector f) {
List key = makeKey(e, f);
List part = table.get(key);
if (part == null) { // symmetric product
GenSolvablePolynomial p = null;
if (!coeffTable) {
ExpVector ef = e.sum(f);
p = new GenSolvablePolynomial(ring, ring.getONECoefficient(), ef);
} else {
if (ring.coFac instanceof GenPolynomialRing) {
GenPolynomialRing cofac = (GenPolynomialRing) (Object)ring.coFac;
//System.out.println("f = " + f + ", e = " + e);
GenPolynomial pc = cofac.getZERO().sum(cofac.getONECoefficient(), f);
C c = (C) (Object)pc;
p = new GenSolvablePolynomial(ring, c, e);
//System.out.println("pc = " + pc + ", p = " + p);
}
}
return new TableRelation(null, null, p);
}
// no distinction between coefficient f or polynomial f
ExpVectorPair evp = new ExpVectorPair(e, f);
ExpVector ep = null;
ExpVector fp = null;
ExpVectorPair look = null;
GenSolvablePolynomial p = null;
synchronized (part) { // with update()
for (Iterator it = part.iterator(); it.hasNext();) {
look = (ExpVectorPair) it.next();
p = (GenSolvablePolynomial) it.next();
if (evp.isMultiple(look)) {
ep = e.subtract(look.getFirst());
fp = f.subtract(look.getSecond());
if (ep.isZERO()) {
ep = null;
}
if (fp.isZERO()) {
fp = null;
}
if (debug) {
if (p != null && p.ring.vars != null) {
logger.info("found relation = " + e.toString(p.ring.vars) + " .*. "
+ f.toString(p.ring.vars) + " = " + p);
} else {
logger.info("found relation = " + e + " .*. " + f + " = " + p);
}
}
return new TableRelation(ep, fp, p);
}
}
}
// unreacheable code!
throw new RuntimeException("no entry found in relation table for " + evp);
}
/**
* Construct a key for (e,f).
* @param e first term.
* @param f second term.
* @return k key for (e,f).
*/
protected List makeKey(ExpVector e, ExpVector f) {
int[] de = e.dependencyOnVariables();
int[] df = f.dependencyOnVariables();
List key = new ArrayList(de.length + df.length);
for (int i = 0; i < de.length; i++) {
key.add(Integer.valueOf(de[i]));
}
for (int i = 0; i < df.length; i++) {
key.add(Integer.valueOf(df[i]));
}
return key;
}
/**
* Size of the table.
* @return n number of non-commutative relations.
*/
public int size() {
int s = 0;
if (table == null) {
return s;
}
for (Iterator it = table.values().iterator(); it.hasNext();) {
List list = it.next();
s += list.size() / 2;
}
return s;
}
/**
* Extend variables. Used e.g. in module embedding. Extend all ExpVectors
* and polynomials of the given relation table by i elements and put the
* relations into this table, i.e. this should be empty.
* @param tab a relation table to be extended and inserted into this.
*/
@SuppressWarnings("unchecked")
public void extend(RelationTable tab) {
if (tab.table.size() == 0) {
return;
}
// assert this.size() == 0
int i = ring.nvar - tab.ring.nvar;
int j = 0;
long k = 0l;
List val;
for (List key : tab.table.keySet()) {
val = tab.table.get(key);
for (Iterator jt = val.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
ExpVector e = ep.getFirst();
ExpVector f = ep.getSecond();
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
ExpVector ex = e.extend(i, j, k);
ExpVector fx;
if (coeffTable) {
fx = f;
} else {
fx = f.extend(i, j, k);
}
GenSolvablePolynomial px = (GenSolvablePolynomial) p.extend(ring, j, k);
this.update(ex, fx, px);
}
}
return;
}
/**
* Contract variables. Used e.g. in module embedding. Contract all
* ExpVectors and polynomials of the given relation table by i elements and
* put the relations into this table, i.e. this should be empty.
* @param tab a relation table to be contracted and inserted into this.
*/
@SuppressWarnings("unchecked")
public void contract(RelationTable tab) {
if (tab.table.size() == 0) {
return;
}
// assert this.size() == 0
int i = tab.ring.nvar - ring.nvar;
List val;
for (List key : tab.table.keySet()) {
val = tab.table.get(key);
//System.out.println("key = " + key + ", val = " + val);
for (Iterator jt = val.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
ExpVector e = ep.getFirst();
ExpVector f = ep.getSecond();
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
ExpVector ec = e.contract(i, e.length() - i);
ExpVector fc;
if (coeffTable) {
fc = f;
} else {
fc = f.contract(i, f.length() - i);
}
//System.out.println("ec = " + ec + ", fc = " + fc);
if (ec.isZERO()) {
continue;
}
Map> mc = p.contract(ring);
if (mc.size() != 1) {
continue;
}
GenPolynomial pc = mc.values().iterator().next();
this.update(ec, fc, pc);
}
}
return;
}
/**
* Recursive representation. Split all ExpVectors and polynomials of the
* given relation table to lower elements and upper elements and put the
* relations into this table or this as coefficient table, i.e. this should
* be empty.
* @param tab a relation table to be contracted and inserted into this.
*/
@SuppressWarnings("unchecked")
public void recursive(RelationTable tab) { //
if (tab.table.size() == 0) {
return;
}
//System.out.println("rel ring = " + ring.toScript());
// assert this.size() == 0
GenPolynomialRing cring = (GenPolynomialRing) (Object)ring.coFac;
//System.out.println("cring = " + cring.toScript());
GenSolvablePolynomial pc;
int i = ring.nvar; // tab.ring.nvar -
for (Object okey : tab.table.keySet()) {
List key = (List) okey;
List val = (List) tab.table.get(key);
//System.out.println("key = " + key + ", val = " + val);
for (Iterator jt = val.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
ExpVector e = ep.getFirst();
ExpVector f = ep.getSecond();
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
ExpVector ec = e.contract(0, i);
ExpVector fc;
if (coeffTable) {
fc = f;
} else {
fc = f.contract(0, i);
}
//System.out.println("ec = " + ec + ", fc = " + fc);
if (ec.isZERO()) {
continue;
}
Map> mc = p.contract(cring);
//System.out.println("mc = " + mc + ", p = " + p);
//System.out.println("mc.ring = " + mc.values().iterator().next().ring.toScript());
if (mc.size() == 1) { // < 1 only for p == 0
pc = (GenSolvablePolynomial) mc.values().iterator().next();
this.update(ec, fc, pc);
} else { // construct recursive polynomial
GenSolvablePolynomial qr = ring.getZERO();
for (Map.Entry> mce : mc.entrySet()) {
ExpVector g = mce.getKey();
GenPolynomial q = mce.getValue();
C cq = (C) (Object)q;
GenSolvablePolynomial qp = new GenSolvablePolynomial(ring, cq, g);
qr = (GenSolvablePolynomial) qr.sum(qp);
}
if (coeffTable) {
fc = ((GenPolynomial) (Object)qr.leadingBaseCoefficient()).leadingExpVector();
}
if (fc.isZERO()) {
continue;
}
//System.out.println("ec = " + ec + ", fc = " + fc + ", qr = " + qr);
if (coeffTable) {
logger.info("coeffTable: adding " + qr);
} else {
logger.info("no coeffTable: adding " + qr);
}
this.update(ec, fc, qr);
}
}
}
return;
}
/**
* Reverse variables and relations. Used e.g. in opposite rings. Reverse all
* ExpVectors and polynomials of the given relation table and put the
* modified relations into this table, i.e. this should be empty.
* @param tab a relation table to be reverted and inserted into this.
*/
@SuppressWarnings("unchecked")
public void reverse(RelationTable tab) {
if (tab.table.size() == 0) {
return;
}
// assert this.size() == 0
if (table.size() != 0) {
logger.error("reverse table not empty");
}
int k = -1;
if (ring.tord.getEvord2() != 0 && ring.partial) {
k = ring.tord.getSplit();
}
logger.debug("k split = " + k);
//System.out.println("k split = " + k );
for (List key : tab.table.keySet()) {
List val = tab.table.get(key);
for (Iterator jt = val.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
ExpVector e = ep.getFirst();
ExpVector f = ep.getSecond();
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
//logger.info("e pre reverse = " + e );
//logger.info("f pre reverse = " + f );
//logger.info("p pre reverse = " + p );
ExpVector ex;
ExpVector fx;
GenSolvablePolynomial px;
boolean change = true; // if relevant vars reversed
if (k >= 0) {
ex = e.reverse(k);
if (coeffTable) {
fx = f;
} else {
fx = f.reverse(k);
}
int[] ed = ex.dependencyOnVariables(); // = e
if (ed.length == 0 || ed[0] >= k) { // k >= 0
change = false;
}
//int[] fd = fx.dependencyOnVariables(); // = f
//if (fd.length == 0 || fd[0] >= k) { // k >= 0
// change = false;
//}
} else {
ex = e.reverse();
if (coeffTable) {
fx = f;
} else {
fx = f.reverse();
}
}
px = (GenSolvablePolynomial) p.reverse(ring);
//System.out.println("change = " + change );
if (!change) {
this.update(e, f, px); // same order
} else {
if (coeffTable) {
this.update(ex, fx, px); // same order
} else {
this.update(fx, ex, px); // opposite order
}
}
}
}
return;
}
/**
* Convert relation table to list of polynomial triples.
* @return rel = (e1,f1,p1, ...) where ei * fi = pi are solvable relations.
*/
@SuppressWarnings("unchecked")
public List> relationList() {
List> rels = new ArrayList>();
C one = ring.getONECoefficient();
GenPolynomialRing cofac = null;
if (coeffTable) {
cofac = (GenPolynomialRing) (Object)ring.coFac; // up cast
}
for (List k : table.keySet()) {
List v = table.get(k);
for (Iterator jt = v.iterator(); jt.hasNext();) {
ExpVectorPair ep = (ExpVectorPair) jt.next();
ExpVector e = ep.getFirst();
GenSolvablePolynomial pe = new GenSolvablePolynomial(ring, one, e);
ExpVector f = ep.getSecond();
GenSolvablePolynomial pf = null;
if (coeffTable) {
GenPolynomial cpf = cofac.getONE().multiply(f);
C cf = (C) (Object)cpf; // down cast
pf = new GenSolvablePolynomial(ring, cf);
} else {
pf = new GenSolvablePolynomial(ring, one, f);
}
GenSolvablePolynomial p = (GenSolvablePolynomial) jt.next();
rels.add(pe);
rels.add(pf);
rels.add(p);
}
}
return rels;
}
/**
* Add list of polynomial triples as relations.
* @param rel = (e1,f1,p1, ...) where ei * fi = pi are solvable relations.
* Note: Only because of type erasure, aequivalent to
* addRelations().
*/
@SuppressWarnings("unchecked")
public void addSolvRelations(List> rel) {
PolynomialList Prel = new PolynomialList(ring, rel);
addRelations(Prel.getList());
}
/**
* Add list of polynomial triples as relations.
* @param rel = (e1,f1,p1, ...) where ei * fi = pi are solvable relations.
*/
@SuppressWarnings("unchecked")
public void addRelations(List> rel) {
if (rel == null || rel.isEmpty()) {
return;
}
Iterator> relit = rel.iterator();
while (relit.hasNext()) {
GenPolynomial E = relit.next();
if (!relit.hasNext()) {
throw new IllegalArgumentException("F and poly part missing");
}
GenPolynomial F = relit.next();
if (!relit.hasNext()) {
throw new IllegalArgumentException("poly part missing");
}
GenPolynomial P = relit.next();
if (coeffTable && F.isConstant()) {
F = (GenPolynomial) (Object)F.leadingBaseCoefficient(); // up cast
}
update(E, F, P);
}
return;
}
}
Ads help maintain this website.