001    /*
002     * $Id: QuotientRing.java 3365 2010-10-24 12:59:34Z kredel $
003     */
004    
005    package edu.jas.poly;
006    
007    import java.util.Random;
008    import java.util.List;
009    import java.util.ArrayList;
010    import java.io.Reader;
011    
012    import org.apache.log4j.Logger;
013    
014    import edu.jas.structure.ElemFactory;
015    import edu.jas.structure.RingElem;
016    import 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     */
025    public 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    }