
edu.jas.ufd.QuotientRing Maven / Gradle / Ivy
The newest version!
/*
* $Id: QuotientRing.java 4406 2013-04-30 10:07:39Z kredel $
*/
package edu.jas.ufd;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;
import edu.jas.kern.StringUtil;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.PolyUtil;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingFactory;
/**
* Quotient ring factory based on GenPolynomial with RingElem interface. Objects
* of this class are immutable.
* @author Heinz Kredel
*/
public class QuotientRing> implements RingFactory> {
private static final Logger logger = Logger.getLogger(QuotientRing.class);
//private boolean debug = logger.isDebugEnabled();
/**
* Polynomial ring of the factory.
*/
public final GenPolynomialRing ring;
/**
* GCD engine of the factory.
*/
public final GreatestCommonDivisor engine;
/**
* Use GCD of package edu.jas.ufd.
*/
public final boolean ufdGCD;
/**
* The constructor creates a QuotientRing object from a GenPolynomialRing.
* @param r polynomial ring.
*/
public QuotientRing(GenPolynomialRing r) {
this(r, true);
}
/**
* The constructor creates a QuotientRing object from a GenPolynomialRing.
* @param r polynomial ring.
* @param ufdGCD flag, if syzygy or gcd based algorithm used for engine.
*/
public QuotientRing(GenPolynomialRing r, boolean ufdGCD) {
ring = r;
this.ufdGCD = ufdGCD;
// if (!ufdGCD) {
// engine = null;
// return;
// }
engine = GCDFactory. getProxy(ring.coFac);
logger.debug("quotient ring constructed");
}
/**
* Divide.
* @param n first polynomial.
* @param d second polynomial.
* @return divide(n,d)
*/
protected GenPolynomial divide(GenPolynomial n, GenPolynomial d) {
return PolyUtil. basePseudoDivide(n, d);
}
/**
* Greatest common divisor.
* @param n first polynomial.
* @param d second polynomial.
* @return gcd(n,d)
*/
protected GenPolynomial gcd(GenPolynomial n, GenPolynomial d) {
if (ufdGCD) {
return engine.gcd(n, d);
}
return engine.gcd(n, d);
//return syzGcd(n, d);
}
/*
* Least common multiple. Just for fun, is not efficient.
* @param n first polynomial.
* @param d second polynomial.
* @return lcm(n,d)
*/
// protected GenPolynomial syzLcm(GenPolynomial n, GenPolynomial d) {
// List> list = new ArrayList>(1);
// list.add(n);
// Ideal N = new Ideal(n.ring, list, true);
// list = new ArrayList>(1);
// list.add(d);
// Ideal D = new Ideal(n.ring, list, true);
// Ideal L = N.intersect(D);
// if (L.getList().size() != 1) {
// throw new RuntimeException("lcm not uniqe");
// }
// GenPolynomial lcm = L.getList().get(0);
// return lcm;
// }
/*
* Greatest common divisor. Just for fun, is not efficient.
* @param n first polynomial.
* @param d second polynomial.
* @return gcd(n,d)
*/
// protected GenPolynomial syzGcd(GenPolynomial n, GenPolynomial d) {
// if (n.isZERO()) {
// return d;
// }
// if (d.isZERO()) {
// return n;
// }
// if (n.isONE()) {
// return n;
// }
// if (d.isONE()) {
// return d;
// }
// GenPolynomial p = n.multiply(d);
// GenPolynomial lcm = syzLcm(n, d);
// GenPolynomial gcd = divide(p, lcm);
// return gcd;
// }
/**
* Is this structure finite or infinite.
* @return true if this structure is finite, else false.
* @see edu.jas.structure.ElemFactory#isFinite()
*/
public boolean isFinite() {
return false;
}
/**
* Copy Quotient element c.
* @param c
* @return a copy of c.
*/
public Quotient copy(Quotient c) {
return new Quotient(c.ring, c.num, c.den, true);
}
/**
* Get the zero element.
* @return 0 as Quotient.
*/
public Quotient getZERO() {
return new Quotient(this, ring.getZERO());
}
/**
* Get the one element.
* @return 1 as Quotient.
*/
public Quotient getONE() {
return new Quotient(this, ring.getONE());
}
/**
* Get a list of the generating elements.
* @return list of generators for the algebraic structure.
* @see edu.jas.structure.ElemFactory#generators()
*/
public List> generators() {
List> pgens = ring.generators();
List> gens = new ArrayList>(pgens.size());
for (GenPolynomial p : pgens) {
Quotient q = new Quotient(this, p);
gens.add(q);
}
return gens;
}
/**
* Query if this ring is commutative.
* @return true if this ring is commutative, else false.
*/
public boolean isCommutative() {
return ring.isCommutative();
}
/**
* Query if this ring is associative.
* @return true if this ring is associative, else false.
*/
public boolean isAssociative() {
return ring.isAssociative();
}
/**
* Query if this ring is a field.
* @return true.
*/
public boolean isField() {
return true;
}
/**
* Characteristic of this ring.
* @return characteristic of this ring.
*/
public java.math.BigInteger characteristic() {
return ring.characteristic();
}
/**
* Get a Quotient element from a BigInteger value.
* @param a BigInteger.
* @return a Quotient.
*/
public Quotient fromInteger(java.math.BigInteger a) {
return new Quotient(this, ring.fromInteger(a));
}
/**
* Get a Quotient element from a long value.
* @param a long.
* @return a Quotient.
*/
public Quotient fromInteger(long a) {
return new Quotient(this, ring.fromInteger(a));
}
/**
* Get the String representation as RingFactory.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String s = null;
if (ring.coFac.characteristic().signum() == 0) {
s = "RatFunc";
} else {
s = "ModFunc";
}
return s + "( " + ring.toString() + " )";
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this ElemFactory.
* @see edu.jas.structure.ElemFactory#toScript()
*/
//JAVA6only: @Override
public String toScript() {
// Python case
return "RF(" + ring.toScript() + ")";
}
/**
* Comparison with any other object.
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
// not jet working
public boolean equals(Object b) {
if (!(b instanceof QuotientRing)) {
return false;
}
QuotientRing a = null;
try {
a = (QuotientRing) b;
} catch (ClassCastException e) {
}
if (a == null) {
return false;
}
return ring.equals(a.ring);
}
/**
* Hash code for this quotient ring.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int h;
h = ring.hashCode();
return h;
}
/**
* Quotient random.
* @param n such that 0 ≤ v ≤ (2n-1).
* @return a random residue element.
*/
public Quotient random(int n) {
GenPolynomial r = ring.random(n).monic();
GenPolynomial s = ring.random(n).monic();
while (s.isZERO()) {
s = ring.random(n).monic();
}
return new Quotient(this, r, s, false);
}
/**
* Generate a random quotient 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 quotient polynomial.
*/
public Quotient random(int k, int l, int d, float q) {
GenPolynomial r = ring.random(k, l, d, q).monic();
GenPolynomial s = ring.random(k, l, d, q).monic();
while (s.isZERO()) {
s = ring.random(k, l, d, q).monic();
}
return new Quotient(this, r, s, false);
}
/**
* Quotient random.
* @param n such that 0 ≤ v ≤ (2n-1).
* @param rnd is a source for random bits.
* @return a random quotient element.
*/
public Quotient random(int n, Random rnd) {
GenPolynomial r = ring.random(n, rnd).monic();
GenPolynomial s = ring.random(n, rnd).monic();
while (s.isZERO()) {
s = ring.random(n, rnd).monic();
}
return new Quotient(this, r, s, false);
}
/**
* Parse Quotient from String. Syntax: "{ polynomial | polynomial }" or
* "{ polynomial }" or " polynomial | polynomial " or " polynomial "
* @param s String.
* @return Quotient from s.
*/
public Quotient parse(String s) {
int i = s.indexOf("{");
if (i >= 0) {
s = s.substring(i + 1);
}
i = s.lastIndexOf("}");
if (i >= 0) {
s = s.substring(0, i);
}
i = s.indexOf("|");
if (i < 0) {
GenPolynomial n = ring.parse(s);
return new Quotient(this, n);
}
String s1 = s.substring(0, i);
String s2 = s.substring(i + 1);
GenPolynomial n = ring.parse(s1);
GenPolynomial d = ring.parse(s2);
return new Quotient(this, n, d);
}
/**
* Parse Quotient from Reader.
* @param r Reader.
* @return next Quotient from r.
*/
public Quotient parse(Reader r) {
String s = StringUtil.nextPairedString(r, '{', '}');
return parse(s);
}
/**
* Degree of extension field.
* @return degree of this extension field, -1 for transcendental extension.
*/
public long extensionDegree() {
long degree = -1L;
if (ring.nvar <= 0) {
degree = 0L;
}
return degree;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy