/*
* $Id$
*/
package edu.jas.arith;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.log4j.Logger;
import edu.jas.structure.RingElem;
import edu.jas.structure.RingFactory;
/**
* Direct product ring factory based on RingElem and RingFactory module. Objects
* of this class are mutable.
* @author Heinz Kredel
*/
public class ProductRing> implements RingFactory> {
private static final Logger logger = Logger.getLogger(ProductRing.class);
//private boolean debug = logger.isDebugEnabled();
/**
* Ring factory is n copies.
*/
protected int nCopies;
/**
* One Ring factory.
*/
protected final RingFactory ring;
/**
* Ring factory list.
*/
protected final List> ringList;
/**
* A default random sequence generator.
*/
protected final static Random random = new Random();
/**
* The constructor creates a ProductRing object from an ring factory and a
* modul.
* @param r ring factory.
* @param n number of copies.
*/
public ProductRing(RingFactory r, int n) {
ring = r;
nCopies = n;
ringList = null;
}
/**
* The constructor creates a ProductRing object from an ring factory and a
* modul.
* @param l list of ring factories.
*/
public ProductRing(List> l) {
ringList = l;
ring = null;
nCopies = 0;
}
/**
* Get ring factory at index i.
* @param i index.
* @return RingFactory_i.
*/
public RingFactory getFactory(int i) {
if (nCopies != 0) {
if (0 <= i && i < nCopies) {
return ring;
}
logger.info("index: " + i);
throw new IllegalArgumentException("index out of bound " + this);
}
return ringList.get(i);
}
/**
* Add a ring factory.
* @param rf new ring factory.
*/
public synchronized void addFactory(RingFactory rf) {
if (nCopies != 0) {
if (ring.equals(rf)) {
nCopies++;
}
throw new IllegalArgumentException("wrong RingFactory: " + rf);
}
ringList.add(rf);
}
/**
* Contains a ring factory.
* @param rf ring factory.
* @return true, if rf is contained in this, else false.
*/
public boolean containsFactory(RingFactory rf) {
if (nCopies != 0) {
if (ring.equals(rf)) {
return true;
}
return false; // misleading
}
return ringList.contains(rf);
}
/**
* Is this structure finite or infinite.
* @return true if this structure is finite, else false.
* @see edu.jas.structure.ElemFactory#isFinite()
*/
public boolean isFinite() {
if (nCopies != 0) {
return ring.isFinite();
}
for (RingFactory f : ringList) {
boolean b = f.isFinite();
if (!b) {
return false;
}
}
return true;
}
/**
* Copy Product element c.
* @param c
* @return a copy of c.
*/
public Product copy(Product c) {
return new Product(c.ring, c.val, c.isunit);
}
/**
* Get the zero element.
* @return 0 as Product.
*/
public Product getZERO() {
return new Product(this);
}
/**
* Get the one element.
* @return 1 as Product.
*/
public Product getONE() {
SortedMap elem = new TreeMap();
if (nCopies != 0) {
for (int i = 0; i < nCopies; i++) {
elem.put(i, ring.getONE());
}
} else {
int i = 0;
for (RingFactory f : ringList) {
elem.put(i, f.getONE());
i++;
}
}
return new Product(this, elem, 1);
}
/**
* 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> gens = new ArrayList>(/*nCopies*ring.generators.size()*/);
int n = nCopies;
if (n == 0) {
n = ringList.size();
}
for (int i = 0; i < n; i++) {
//System.out.println("i = " + i + ", n = " + n);
RingFactory f = getFactory(i);
List extends C> rgens = f.generators();
for (C c : rgens) {
SortedMap elem = new TreeMap();
elem.put(i, c);
Product g = new Product(this, elem);
//g = g.fillOne();
gens.add(g);
}
}
return gens;
}
/**
* Get an atomic element.
* @param i index.
* @return e_i as Product.
*/
public Product getAtomic(int i) {
if (i < 0 || i >= length()) {
throw new IllegalArgumentException("index out of bounds " + i);
}
SortedMap elem = new TreeMap();
if (nCopies != 0) {
elem.put(i, ring.getONE());
} else {
RingFactory f = ringList.get(i);
elem.put(i, f.getONE());
}
return new Product(this, elem, 1);
}
/**
* Get the number of factors of this ring.
* @return nCopies or ringList.size().
*/
public int length() {
if (nCopies != 0) {
return nCopies;
}
return ringList.size();
}
/**
* Query if this ring is commutative.
* @return true if this ring is commutative, else false.
*/
public boolean isCommutative() {
if (nCopies != 0) {
return ring.isCommutative();
}
for (RingFactory f : ringList) {
if (!f.isCommutative()) {
return false;
}
}
return true;
}
/**
* Query if this ring is associative.
* @return true if this ring is associative, else false.
*/
public boolean isAssociative() {
if (nCopies != 0) {
return ring.isAssociative();
}
for (RingFactory f : ringList) {
if (!f.isAssociative()) {
return false;
}
}
return true;
}
/**
* Query if this ring is a field.
* @return true or false.
*/
public boolean isField() {
if (nCopies != 0) {
if (nCopies == 1) {
return ring.isField();
}
} else {
if (ringList.size() == 1) {
return ringList.get(0).isField();
}
}
return false;
}
/**
* Query if this ring consists only of fields.
* @return true or false.
*/
public boolean onlyFields() {
if (nCopies != 0) {
return ring.isField();
}
for (RingFactory f : ringList) {
if (!f.isField()) {
return false;
}
}
return true;
}
/**
* Characteristic of this ring.
* @return minimal characteristic of ring component.
*/
public java.math.BigInteger characteristic() {
if (nCopies != 0) {
return ring.characteristic();
}
java.math.BigInteger c = null;
java.math.BigInteger d;
for (RingFactory f : ringList) {
if (c == null) {
c = f.characteristic();
} else {
d = f.characteristic();
if (c.compareTo(d) > 0) { // c > d
c = d;
}
}
}
return c;
}
/**
* Get a Product element from a BigInteger value.
* @param a BigInteger.
* @return a Product.
*/
public Product fromInteger(java.math.BigInteger a) {
SortedMap elem = new TreeMap();
if (nCopies != 0) {
C c = ring.fromInteger(a);
for (int i = 0; i < nCopies; i++) {
elem.put(i, c);
}
} else {
int i = 0;
for (RingFactory f : ringList) {
elem.put(i, f.fromInteger(a));
i++;
}
}
return new Product(this, elem);
}
/**
* Get a Product element from a long value.
* @param a long.
* @return a Product.
*/
public Product fromInteger(long a) {
return fromInteger(new java.math.BigInteger("" + a));
}
/**
* Get the String representation as RingFactory.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
if (nCopies != 0) {
String cf = ring.toString();
if (cf.matches("[0-9].*")) {
cf = ring.getClass().getSimpleName();
}
return "ProductRing[ " + cf + "^" + nCopies + " ]";
}
StringBuffer sb = new StringBuffer("ProductRing[ ");
int i = 0;
for (RingFactory f : ringList) {
if (i != 0) {
sb.append(", ");
}
String cf = f.toString();
if (cf.matches("[0-9].*")) {
cf = f.getClass().getSimpleName();
}
sb.append(cf);
i++;
}
sb.append(" ]");
return sb.toString();
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this ElemFactory.
* @see edu.jas.structure.ElemFactory#toScript()
*/
@Override
public String toScript() {
// Python case
StringBuffer s = new StringBuffer("RR( [ ");
for (int i = 0; i < length(); i++) {
if (i > 0) {
s.append(", ");
}
RingFactory v = getFactory(i);
String f = null;
try {
f = ((RingElem) v).toScriptFactory(); // sic
} catch (Exception e) {
f = v.toScript();
}
s.append(f);
}
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 b) {
if (!(b instanceof ProductRing)) {
return false;
}
ProductRing a = null;
try {
a = (ProductRing) b;
} catch (ClassCastException e) {
}
if (a == null) {
return false;
}
if (nCopies != 0) {
if (nCopies != a.nCopies || !ring.equals(a.ring)) {
return false;
}
} else {
if (ringList.size() != a.ringList.size()) {
return false;
}
int i = 0;
for (RingFactory f : ringList) {
if (!f.equals(a.ringList.get(i))) {
return false;
}
i++;
}
}
return true;
}
/**
* Hash code for this product ring.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int h = 0;
if (nCopies != 0) {
h = ring.hashCode();
h = 37 * h + nCopies;
} else {
for (RingFactory f : ringList) {
h = 37 * h + f.hashCode();
}
}
return h;
}
/**
* Product random.
* @param n such that 0 ≤ v ≤ (2n-1).
* @return a random product element v.
*/
public Product random(int n) {
return random(n, 0.5f);
}
/**
* Product random.
* @param n such that 0 ≤ v ≤ (2n-1).
* @param q density of nozero entries.
* @return a random product element v.
*/
public Product random(int n, float q) {
return random(n, q, random);
}
/**
* Product random.
* @param n such that 0 ≤ v ≤ (2n-1).
* @param rnd is a source for random bits.
* @return a random product element v.
*/
public Product random(int n, Random rnd) {
return random(n, 0.5f, random);
}
/**
* Product random.
* @param n such that 0 ≤ v ≤ (2n-1).
* @param q density of nozero entries.
* @param rnd is a source for random bits.
* @return a random product element v.
*/
public Product random(int n, float q, Random rnd) {
SortedMap elem = new TreeMap();
float d;
if (nCopies != 0) {
for (int i = 0; i < nCopies; i++) {
d = rnd.nextFloat();
if (d < q) {
C r = ring.random(n, rnd);
if (!r.isZERO()) {
elem.put(i, r);
}
}
}
} else {
int i = 0;
for (RingFactory f : ringList) {
d = rnd.nextFloat();
if (d < q) {
C r = f.random(n, rnd);
if (!r.isZERO()) {
elem.put(i, r);
}
}
i++;
}
}
return new Product(this, elem);
}
/**
* Parse Product from String.
* @param s String.
* @return Product from s.
*/
public Product parse(String s) {
StringReader sr = new StringReader(s);
return parse(sr);
}
/**
* Parse Product from Reader. Syntax: p1 ... pn (no commas)
* @param r Reader.
* @return next Product from r.
*/
public Product parse(Reader r) {
SortedMap elem = new TreeMap();
if (nCopies != 0) {
for (int i = 0; i < nCopies; i++) {
elem.put(i, ring.parse(r));
}
} else {
int i = 0;
for (RingFactory f : ringList) {
elem.put(i, f.parse(r));
i++;
}
}
return new Product(this, elem);
}
}
Ads help maintain this website.