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