001/*
002 * $Id: QuotientRing.java 4958 2014-10-16 23:05:31Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.io.Reader;
009import java.util.ArrayList;
010import java.util.List;
011import java.util.Random;
012
013import org.apache.log4j.Logger;
014
015// import edu.jas.structure.GcdRingElem;
016import edu.jas.structure.QuotPairFactory;
017import edu.jas.structure.RingElem;
018import edu.jas.structure.RingFactory;
019
020
021/**
022 * Quotient ring factory using RingElem and RingFactory. Objects of this class
023 * are immutable.
024 * @author Heinz Kredel
025 */
026public class QuotientRing<C extends RingElem<C>> implements RingFactory<Quotient<C>>,
027                QuotPairFactory<C, Quotient<C>> {
028
029
030    private static final Logger logger = Logger.getLogger(QuotientRing.class);
031
032
033    private final boolean debug = logger.isDebugEnabled();
034
035
036    /**
037     * Ring factory of this factory.
038     */
039    public final RingFactory<C> ring;
040
041
042    /**
043     * The constructor creates a QuotientRing object from a RingFactory.
044     * @param r ring factory.
045     */
046    public QuotientRing(RingFactory<C> r) {
047        ring = r;
048    }
049
050
051    /**
052     * Factory for base elements.
053     */
054    public RingFactory<C> pairFactory() {
055        return ring;
056    }
057
058
059    /**
060     * Create from numerator.
061     */
062    public Quotient<C> create(C n) {
063        return new Quotient<C>(this, n);
064    }
065
066
067    /**
068     * Create from numerator, denominator pair.
069     */
070    public Quotient<C> create(C n, C d) {
071        return new Quotient<C>(this, n, d);
072    }
073
074
075    /**
076     * Is this structure finite or infinite.
077     * @return true if this structure is finite, else false.
078     * @see edu.jas.structure.ElemFactory#isFinite()
079     */
080    public boolean isFinite() {
081        return ring.isFinite();
082    }
083
084
085    /**
086     * Copy Quotient element c.
087     * @param c
088     * @return a copy of c.
089     */
090    public Quotient<C> copy(Quotient<C> c) {
091        return new Quotient<C>(c.ring, c.num, c.den, true);
092    }
093
094
095    /**
096     * Get the zero element.
097     * @return 0 as Quotient.
098     */
099    public Quotient<C> getZERO() {
100        return new Quotient<C>(this, ring.getZERO());
101    }
102
103
104    /**
105     * Get the one element.
106     * @return 1 as Quotient.
107     */
108    public Quotient<C> getONE() {
109        return new Quotient<C>(this, ring.getONE());
110    }
111
112
113    /**
114     * Get a list of the generating elements.
115     * @return list of generators for the algebraic structure.
116     * @see edu.jas.structure.ElemFactory#generators()
117     */
118    public List<Quotient<C>> generators() {
119        List<? extends C> rgens = ring.generators();
120        List<Quotient<C>> gens = new ArrayList<Quotient<C>>(rgens.size());
121        for (C c : rgens) {
122            gens.add(new Quotient<C>(this, c));
123        }
124        return gens;
125    }
126
127
128    /**
129     * Query if this ring is commutative.
130     * @return true if this ring is commutative, else false.
131     */
132    public boolean isCommutative() {
133        return ring.isCommutative();
134    }
135
136
137    /**
138     * Query if this ring is associative.
139     * @return true if this ring is associative, else false.
140     */
141    public boolean isAssociative() {
142        return ring.isAssociative();
143    }
144
145
146    /**
147     * Query if this ring is a field.
148     * @return true.
149     */
150    public boolean isField() {
151        return true;
152    }
153
154
155    /**
156     * Characteristic of this ring.
157     * @return characteristic of this ring.
158     */
159    public java.math.BigInteger characteristic() {
160        return ring.characteristic();
161    }
162
163
164    /**
165     * Get a Quotient element from a BigInteger value.
166     * @param a BigInteger.
167     * @return a Quotient.
168     */
169    public Quotient<C> fromInteger(java.math.BigInteger a) {
170        return new Quotient<C>(this, ring.fromInteger(a));
171    }
172
173
174    /**
175     * Get a Quotient element from a long value.
176     * @param a long.
177     * @return a Quotient.
178     */
179    public Quotient<C> fromInteger(long a) {
180        return new Quotient<C>(this, ring.fromInteger(a));
181    }
182
183
184    /**
185     * Get the String representation as RingFactory.
186     * @see java.lang.Object#toString()
187     */
188    @Override
189    public String toString() {
190        return "Quotient[ " + ring.toString() + " ]";
191    }
192
193
194    /**
195     * Get a scripting compatible string representation.
196     * @return script compatible representation for this ElemFactory.
197     * @see edu.jas.structure.ElemFactory#toScript()
198     */
199    @Override
200    public String toScript() {
201        // Python case
202        return "QuotientRing(" + ring.toScript() + ")";
203    }
204
205
206    /**
207     * Comparison with any other object.
208     * @see java.lang.Object#equals(java.lang.Object)
209     */
210    @Override
211    @SuppressWarnings("unchecked")
212    public boolean equals(Object b) {
213        if (b == null) {
214            return false;
215        }
216        if (!(b instanceof QuotientRing)) {
217            return false;
218        }
219        QuotientRing<C> a = (QuotientRing<C>) b;
220        return ring.equals(a.ring);
221    }
222
223
224    /**
225     * Hash code for this quotient ring.
226     * @see java.lang.Object#hashCode()
227     */
228    @Override
229    public int hashCode() {
230        int h;
231        h = ring.hashCode();
232        return h;
233    }
234
235
236    /**
237     * Quotient random.
238     * @param n such that 0 &le; v &le; (2<sup>n</sup>-1).
239     * @return a random residue element.
240     */
241    public Quotient<C> random(int n) {
242        C r = ring.random(n);
243        C s = ring.random(n);
244        while (s.isZERO()) {
245            s = ring.random(n);
246        }
247        return new Quotient<C>(this, r, s, false);
248    }
249
250
251    /**
252     * Quotient random.
253     * @param n such that 0 &le; v &le; (2<sup>n</sup>-1).
254     * @param rnd is a source for random bits.
255     * @return a random residue element.
256     */
257    public Quotient<C> random(int n, Random rnd) {
258        C r = ring.random(n, rnd);
259        C s = ring.random(n, rnd);
260        while (s.isZERO()) {
261            s = ring.random(n, rnd);
262        }
263        return new Quotient<C>(this, r, s, false);
264    }
265
266
267    /**
268     * Parse Quotient from String.
269     * @param s String.
270     * @return Quotient from s.
271     */
272    public Quotient<C> parse(String s) {
273        C x = ring.parse(s);
274        return new Quotient<C>(this, x);
275    }
276
277
278    /**
279     * Parse Quotient from Reader.
280     * @param r Reader.
281     * @return next Quotient from r.
282     */
283    public Quotient<C> parse(Reader r) {
284        C x = ring.parse(r);
285        if (debug) {
286            logger.debug("x = " + x);
287        }
288        return new Quotient<C>(this, x);
289    }
290
291}