/*
* $Id$
*/
package edu.jas.application;
// todo: move to edu.jas.poly
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.log4j.Logger;
import edu.jas.kern.PrettyPrint;
import edu.jas.kern.Scripting;
import edu.jas.poly.ExpVector;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.GenPolynomialTokenizer;
import edu.jas.poly.GenSolvablePolynomial;
import edu.jas.poly.GenSolvablePolynomialRing;
import edu.jas.poly.RecSolvablePolynomial;
import edu.jas.poly.RecSolvablePolynomialRing;
import edu.jas.poly.RelationTable;
import edu.jas.poly.TermOrder;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingElem;
import edu.jas.structure.RingFactory;
import edu.jas.structure.QuotPair;
import edu.jas.structure.QuotPairFactory;
/**
* QLRSolvablePolynomialRing generic recursive solvable polynomial
* factory implementing RingFactory and extending
* GenSolvablePolynomialRing factory. Factory for n-variate ordered
* solvable polynomials over solvable quotient, local and
* local-residue coefficients. The non-commutative multiplication
* relations are maintained in a relation table and the
* non-commutative multiplication relations between the coefficients
* and the main variables are maintained in a coefficient relation
* table. Almost immutable object, except variable names and relation
* table contents.
* @param polynomial coefficient type
* @param quotient coefficient type
* @author Heinz Kredel
*/
public class QLRSolvablePolynomialRing & QuotPair>,
D extends GcdRingElem >
extends GenSolvablePolynomialRing {
private static final Logger logger = Logger.getLogger(QLRSolvablePolynomialRing.class);
//private final boolean debug = logger.isDebugEnabled();
/**
* Recursive solvable polynomial ring with polynomial coefficients.
*/
public final RecSolvablePolynomialRing polCoeff;
/**
* The constant polynomial 0 for this ring. Hides super ZERO.
*/
public final QLRSolvablePolynomial ZERO;
/**
* The constant polynomial 1 for this ring. Hides super ONE.
*/
public final QLRSolvablePolynomial ONE;
/**
* Factory to create coefficients.
*/
public final QuotPairFactory,C> qpfac;
/**
* The constructor creates a solvable polynomial factory object with the
* default term order and commutative relations.
* @param cf factory for coefficients of type C.
* @param n number of variables.
*/
public QLRSolvablePolynomialRing(RingFactory cf, int n) {
this(cf, n, new TermOrder(), null, null);
}
/**
* The constructor creates a solvable polynomial factory object with the
* default term order.
* @param cf factory for coefficients of type C.
* @param n number of variables.
* @param rt solvable multiplication relations.
*/
public QLRSolvablePolynomialRing(RingFactory cf, int n,
RelationTable rt) {
this(cf, n, new TermOrder(), null, rt);
}
/**
* The constructor creates a solvable polynomial factory object with the
* given term order and commutative relations.
* @param cf factory for coefficients of type C.
* @param n number of variables.
* @param t a term order.
*/
public QLRSolvablePolynomialRing(RingFactory cf, int n, TermOrder t) {
this(cf, n, t, null, null);
}
/**
* The constructor creates a solvable polynomial factory object with the
* given term order.
* @param cf factory for coefficients of type C.
* @param n number of variables.
* @param t a term order.
* @param rt solvable multiplication relations.
*/
public QLRSolvablePolynomialRing(RingFactory cf, int n, TermOrder t,
RelationTable rt) {
this(cf, n, t, null, rt);
}
/**
* The constructor creates a solvable polynomial factory object with the
* given term order and commutative relations.
* @param cf factory for coefficients of type C.
* @param n number of variables.
* @param t a term order.
* @param v names for the variables.
*/
public QLRSolvablePolynomialRing(RingFactory cf, int n, TermOrder t, String[] v) {
this(cf, n, t, v, null);
}
/**
* The constructor creates a solvable polynomial factory object with the
* given term order and commutative relations.
* @param cf factory for coefficients of type C.
* @param t a term order.
* @param v names for the variables.
*/
public QLRSolvablePolynomialRing(RingFactory cf, TermOrder t, String[] v) {
this(cf, v.length, t, v, null);
}
/**
* The constructor creates a solvable polynomial factory object with the
* default term order.
* @param cf factory for coefficients of type C.
* @param v names for the variables.
*/
public QLRSolvablePolynomialRing(RingFactory cf, String[] v) {
this(cf, v.length, new TermOrder(), v, null);
}
/**
* The constructor creates a solvable polynomial factory object with the the
* same term order, number of variables and variable names as the given
* polynomial factory, only the coefficient factories differ and the
* solvable multiplication relations are empty.
* @param cf factory for coefficients of type C.
* @param o other solvable polynomial ring.
*/
public QLRSolvablePolynomialRing(RingFactory cf, GenSolvablePolynomialRing o) {
this(cf, o.nvar, o.tord, o.getVars(), null);
}
/**
* The constructor creates a solvable polynomial factory object with the the
* same term order, number of variables and variable names as the given
* polynomial factory, only the coefficient factories differ and the
* solvable multiplication relations are empty.
* @param cf factory for coefficients of type C.
* @param o other solvable polynomial ring.
*/
public QLRSolvablePolynomialRing(RingFactory cf, QLRSolvablePolynomialRing o) {
this(cf, (GenSolvablePolynomialRing) o);
}
/**
* The constructor creates a solvable polynomial factory object with the
* given term order.
* @param cf factory for coefficients of type C.
* @param n number of variables.
* @param t a term order.
* @param v names for the variables.
* @param rt solvable multiplication relations.
*/
public QLRSolvablePolynomialRing(RingFactory cf, int n, TermOrder t, String[] v,
RelationTable rt) {
super(cf, n, t, v, rt);
//if (rt == null) { // handled in super }
qpfac = (QuotPairFactory,C>) cf; // crucial part of type
RingFactory> cfring = qpfac.pairFactory(); // == coFac.ring
polCoeff = new RecSolvablePolynomialRing(cfring, n, t, v);
if (table.size() > 0) { // TODO
ExpVector e = null;
ExpVector f = null;
GenSolvablePolynomial> p = null;
polCoeff.table.update(e, f, p); // from rt
}
ZERO = new QLRSolvablePolynomial(this);
C coeff = coFac.getONE();
ONE = new QLRSolvablePolynomial(this, coeff, evzero);
}
/**
* Get the String representation.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String res = super.toString();
if (PrettyPrint.isTrue()) {
res += "\n" + polCoeff.coeffTable.toString(vars);
} else {
res += ", #rel = " + table.size() + " + " + polCoeff.coeffTable.size();
}
return res;
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this Element.
* @see edu.jas.structure.Element#toScript()
*/
@Override
public String toScript() {
StringBuffer s = new StringBuffer();
switch (Scripting.getLang()) {
case Ruby:
s.append("SolvPolyRing.new(");
break;
case Python:
default:
s.append("SolvPolyRing(");
}
if (coFac instanceof RingElem) {
s.append(((RingElem) coFac).toScriptFactory());
} else {
s.append(coFac.toScript().trim());
}
s.append(",\"" + varsToString() + "\",");
String to = tord.toString();
if (tord.getEvord() == TermOrder.INVLEX) {
to = "PolyRing.lex";
}
if (tord.getEvord() == TermOrder.IGRLEX) {
to = "PolyRing.grad";
}
s.append(to);
if (table.size() > 0) {
String rel = table.toScript();
s.append(",rel=");
s.append(rel);
}
if (polCoeff.coeffTable.size() > 0) {
String rel = polCoeff.coeffTable.toScript();
s.append(",coeffrel=");
s.append(rel);
}
s.append(")");
return s.toString();
}
/**
* Comparison with any other object.
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public boolean equals(Object other) {
if (!(other instanceof QLRSolvablePolynomialRing)) {
return false;
}
QLRSolvablePolynomialRing oring = null;
try {
oring = (QLRSolvablePolynomialRing) other;
} catch (ClassCastException ignored) {
}
if (oring == null) {
return false;
}
// do a super.equals( )
if (!super.equals(other)) {
return false;
}
// check same base relations
//if ( ! table.equals(oring.table) ) { // done in super
// return false;
//}
if (!polCoeff.coeffTable.equals(oring.polCoeff.coeffTable)) {
return false;
}
return true;
}
/**
* Hash code for this polynomial ring.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int h;
h = super.hashCode();
h = 37 * h + table.hashCode(); // may be different after some computations
h = 37 * h + polCoeff.coeffTable.hashCode(); // may be different
return h;
}
/**
* Get the zero element.
* @return 0 as QLRSolvablePolynomial.
*/
@Override
public QLRSolvablePolynomial getZERO() {
return ZERO;
}
/**
* Get the one element.
* @return 1 as QLRSolvablePolynomial.
*/
@Override
public QLRSolvablePolynomial getONE() {
return ONE;
}
/**
* Query if this ring is commutative.
* @return true if this ring is commutative, else false.
*/
@Override
public boolean isCommutative() {
if (polCoeff.isCommutative()) {
return super.isCommutative();
}
return false;
}
/**
* Query if this ring is associative. Test if the relations between the mian
* variables and the coefficient generators define an associative solvable
* ring.
* @return true, if this ring is associative, else false.
*/
@Override
@SuppressWarnings("unchecked")
public boolean isAssociative() {
if (!coFac.isAssociative()) {
return false;
}
//if (!polCoeff.isAssociative()) { // done via generators
// return false;
//}
QLRSolvablePolynomial Xi, Xj, Xk, p, q;
List> gens = generators();
int ngen = gens.size();
for (int i = 0; i < ngen; i++) {
Xi = (QLRSolvablePolynomial) gens.get(i);
for (int j = i + 1; j < ngen; j++) {
Xj = (QLRSolvablePolynomial) gens.get(j);
for (int k = j + 1; k < ngen; k++) {
Xk = (QLRSolvablePolynomial) gens.get(k);
try {
p = Xk.multiply(Xj).multiply(Xi);
q = Xk.multiply(Xj.multiply(Xi));
} catch (IllegalArgumentException e) {
//e.printStackTrace();
continue;
}
if (!p.equals(q)) {
if (logger.isInfoEnabled()) {
logger.info("Xk = " + Xk + ", Xj = " + Xj + ", Xi = " + Xi);
logger.info("p = ( Xk * Xj ) * Xi = " + p);
logger.info("q = Xk * ( Xj * Xi ) = " + q);
logger.info("q-p = " + p.subtract(q));
}
return false;
}
}
}
}
return true;
}
/**
* Get a (constant) QLRSolvablePolynomial<C> element from a long
* value.
* @param a long.
* @return a QLRSolvablePolynomial<C>.
*/
@Override
public QLRSolvablePolynomial fromInteger(long a) {
return new QLRSolvablePolynomial(this, coFac.fromInteger(a), evzero);
}
/**
* Get a (constant) QLRSolvablePolynomial<C> element from a
* BigInteger value.
* @param a BigInteger.
* @return a QLRSolvablePolynomial<C>.
*/
@Override
public QLRSolvablePolynomial fromInteger(BigInteger a) {
return new QLRSolvablePolynomial(this, coFac.fromInteger(a), evzero);
}
/**
* Random solvable polynomial. Generates a random solvable polynomial with k
* = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
* @param n number of terms.
* @return a random solvable polynomial.
*/
@Override
public QLRSolvablePolynomial random(int n) {
return random(n, random);
}
/**
* Random solvable polynomial. Generates a random solvable polynomial with k
* = 5, l = n, d = (nvar == 1) ? n : 3, q = (nvar == 1) ? 0.7 : 0.3.
* @param n number of terms.
* @param rnd is a source for random bits.
* @return a random solvable polynomial.
*/
@Override
public QLRSolvablePolynomial random(int n, Random rnd) {
if (nvar == 1) {
return random(5, n, n, 0.7f, rnd);
}
return random(5, n, 3, 0.3f, rnd);
}
/**
* Generate a random solvable polynomial.
* @param k bitsize of random coefficients.
* @param l number of terms.
* @param d maximal degree in each variable.
* @param q density of nozero exponents.
* @return a random solvable polynomial.
*/
@Override
public QLRSolvablePolynomial random(int k, int l, int d, float q) {
return random(k, l, d, q, random);
}
/**
* Random solvable polynomial.
* @param k size of random coefficients.
* @param l number of terms.
* @param d maximal degree in each variable.
* @param q density of nozero exponents.
* @param rnd is a source for random bits.
* @return a random solvable polynomial.
*/
@Override
@SuppressWarnings("unchecked")
public QLRSolvablePolynomial random(int k, int l, int d, float q, Random rnd) {
QLRSolvablePolynomial r = getZERO(); // copy( ZERO );
ExpVector e;
C a;
// add random coeffs and exponents
for (int i = 0; i < l; i++) {
e = ExpVector.EVRAND(nvar, d, q, rnd);
a = coFac.random(k, rnd);
r = (QLRSolvablePolynomial) r.sum(a, e);
// somewhat inefficient but clean
}
return r;
}
/**
* Copy polynomial c.
* @param c
* @return a copy of c.
*/
public QLRSolvablePolynomial copy(QLRSolvablePolynomial c) {
return new QLRSolvablePolynomial(this, c.getMap());
}
/**
* Parse a solvable polynomial with the use of GenPolynomialTokenizer
* @param s String.
* @return QLRSolvablePolynomial from s.
*/
@Override
public QLRSolvablePolynomial parse(String s) {
return parse(new StringReader(s));
}
/**
* Parse a solvable polynomial with the use of GenPolynomialTokenizer
* @param r Reader.
* @return next QLRSolvablePolynomial from r.
*/
@Override
@SuppressWarnings("unchecked")
public QLRSolvablePolynomial parse(Reader r) {
GenPolynomialTokenizer pt = new GenPolynomialTokenizer(this, r);
QLRSolvablePolynomial p = null;
try {
GenSolvablePolynomial s = pt.nextSolvablePolynomial();
p = new QLRSolvablePolynomial(this, s);
} catch (IOException e) {
logger.error(e.toString() + " parse " + this);
p = ZERO;
}
return p;
}
/**
* Generate univariate solvable polynomial in a given variable.
* @param i the index of the variable.
* @return X_i as solvable univariate polynomial.
*/
@Override
@SuppressWarnings("unchecked")
public QLRSolvablePolynomial univariate(int i) {
return (QLRSolvablePolynomial) super.univariate(i);
}
/**
* Generate univariate solvable polynomial in a given variable with given
* exponent.
* @param i the index of the variable.
* @param e the exponent of the variable.
* @return X_i^e as solvable univariate polynomial.
*/
@Override
@SuppressWarnings("unchecked")
public QLRSolvablePolynomial univariate(int i, long e) {
return (QLRSolvablePolynomial) super.univariate(i, e);
}
/**
* Generate univariate solvable polynomial in a given variable with given
* exponent.
* @param modv number of module variables.
* @param i the index of the variable.
* @param e the exponent of the variable.
* @return X_i^e as solvable univariate polynomial.
*/
@Override
@SuppressWarnings("unchecked")
public QLRSolvablePolynomial univariate(int modv, int i, long e) {
return (QLRSolvablePolynomial) super.univariate(modv, i, e);
}
/**
* Generate list of univariate polynomials in all variables.
* @return List(X_1,...,X_n) a list of univariate polynomials.
*/
//todo Override
@SuppressWarnings("unchecked")
public List> recUnivariateList() {
//return castToSolvableList( super.univariateList() );
return (List>) (Object) univariateList(0, 1L);
}
/**
* Generate list of univariate polynomials in all variables.
* @param modv number of module variables.
* @return List(X_1,...,X_n) a list of univariate polynomials.
*/
//todo Override
@SuppressWarnings("unchecked")
public List> recUnivariateList(int modv) {
return (List>) (Object) univariateList(modv, 1L);
}
/**
* Generate list of univariate polynomials in all variables with given
* exponent.
* @param modv number of module variables.
* @param e the exponent of the variables.
* @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
*/
//todo Override
public List> recUnivariateList(int modv, long e) {
List> pols = new ArrayList>(nvar);
int nm = nvar - modv;
for (int i = 0; i < nm; i++) {
QLRSolvablePolynomial p = univariate(modv, nm - 1 - i, e);
pols.add(p);
}
return pols;
}
/*
* Generate list of univariate polynomials in all variables with given exponent.
* @param modv number of module variables.
* @param e the exponent of the variables.
* @return List(X_1^e,...,X_n^e) a list of univariate polynomials.
@Override
public List> univariateList(int modv, long e) {
List> pol = super.univariateList(modv,e);
UnaryFunctor,QLRSolvablePolynomial> fc
= new UnaryFunctor,QLRSolvablePolynomial>() {
public QLRSolvablePolynomial eval(GenPolynomial p) {
if ( ! (p instanceof QLRSolvablePolynomial) ) {
throw new RuntimeException("no solvable polynomial "+p);
}
return (QLRSolvablePolynomial) p;
}
};
List> pols
= ListUtil.,QLRSolvablePolynomial>map(this,pol,fc);
return pols;
}
*/
/**
* Extend variables. Used e.g. in module embedding. Extend number of
* variables by i.
* @param i number of variables to extend.
* @return extended solvable polynomial ring factory.
*/
@Override
public QLRSolvablePolynomialRing extend(int i) {
GenPolynomialRing pfac = super.extend(i);
QLRSolvablePolynomialRing spfac = new QLRSolvablePolynomialRing(pfac.coFac, pfac.nvar,
pfac.tord, pfac.getVars());
spfac.table.extend(this.table);
spfac.polCoeff.coeffTable.extend(this.polCoeff.coeffTable);
return spfac;
}
/**
* Contract variables. Used e.g. in module embedding. Contract number of
* variables by i.
* @param i number of variables to remove.
* @return contracted solvable polynomial ring factory.
*/
@Override
public QLRSolvablePolynomialRing contract(int i) {
GenPolynomialRing pfac = super.contract(i);
QLRSolvablePolynomialRing spfac = new QLRSolvablePolynomialRing(pfac.coFac, pfac.nvar,
pfac.tord, pfac.getVars());
spfac.table.contract(this.table);
spfac.polCoeff.coeffTable.contract(this.polCoeff.coeffTable);
return spfac;
}
/**
* Reverse variables. Used e.g. in opposite rings.
* @return solvable polynomial ring factory with reversed variables.
*/
@Override
public QLRSolvablePolynomialRing reverse() {
return reverse(false);
}
/**
* Reverse variables. Used e.g. in opposite rings.
* @param partial true for partialy reversed term orders.
* @return solvable polynomial ring factory with reversed variables.
*/
@Override
public QLRSolvablePolynomialRing reverse(boolean partial) {
GenPolynomialRing pfac = super.reverse(partial);
QLRSolvablePolynomialRing spfac = new QLRSolvablePolynomialRing(pfac.coFac, pfac.nvar,
pfac.tord, pfac.getVars());
spfac.partial = partial;
spfac.table.reverse(this.table);
spfac.polCoeff.coeffTable.reverse(this.polCoeff.coeffTable);
return spfac;
}
/**
* Rational function from integral polynomial coefficients. Represent as
* polynomial with type C coefficients.
* @param A polynomial with integral polynomial coefficients to be
* converted.
* @return polynomial with type C coefficients.
*/
public QLRSolvablePolynomial fromPolyCoefficients(GenSolvablePolynomial> A) {
QLRSolvablePolynomial B = getZERO().copy();
if (A == null || A.isZERO()) {
return B;
}
for (Map.Entry> y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
GenSolvablePolynomial a = (GenSolvablePolynomial) y.getValue();
//C p = new C(qfac, a);
C p = qpfac.create(a);
if (!p.isZERO()) {
B.doPutToMap(e, p);
}
}
return B;
}
/**
* Integral function from rational polynomial coefficients. Represent as
* polynomial with type GenSolvablePolynomial coefficients.
* @param A polynomial with rational polynomial coefficients to be
* converted.
* @return polynomial with type GenSolvablePolynomial coefficients.
*/
public RecSolvablePolynomial toPolyCoefficients(QLRSolvablePolynomial A) {
RecSolvablePolynomial B = polCoeff.getZERO().copy();
if (A == null || A.isZERO()) {
return B;
}
for (Map.Entry y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
C a = y.getValue();
if (!a.denominator().isONE()) {
throw new IllegalArgumentException("den != 1 not supported: " + a);
}
GenPolynomial p = a.numerator(); // can not be zero
if (!p.isZERO()) {
B.doPutToMap(e, p);
}
}
return B;
}
/**
* Integral function from rational polynomial coefficients. Represent as
* polynomial with type GenSolvablePolynomial coefficients.
* @param A polynomial with rational polynomial coefficients to be
* converted.
* @return polynomial with type GenSolvablePolynomial coefficients.
*/
public RecSolvablePolynomial toPolyCoefficients(GenPolynomial A) {
RecSolvablePolynomial B = polCoeff.getZERO().copy();
if (A == null || A.isZERO()) {
return B;
}
for (Map.Entry y : A.getMap().entrySet()) {
ExpVector e = y.getKey();
C a = y.getValue();
if (!a.denominator().isONE()) {
throw new IllegalArgumentException("den != 1 not supported: " + a);
}
GenPolynomial p = a.numerator(); // can not be zero
if (!p.isZERO()) {
B.doPutToMap(e, p);
}
}
return B;
}
}
Ads help maintain this website.