001    /*
002     * $Id: ModIntegerRing.java 3355 2010-10-23 16:01:52Z kredel $
003     */
004    
005    package edu.jas.arith;
006    
007    import java.util.Random;
008    import java.io.Reader;
009    import java.util.List;
010    import java.util.ArrayList;
011    import java.util.Iterator;
012    
013    //import edu.jas.structure.GcdRingElem;
014    import edu.jas.kern.StringUtil;
015    import edu.jas.structure.RingFactory;
016    
017    
018    
019    /**
020     * ModIntegerRing factory with RingFactory interface.
021     * Effectively immutable.
022     * @author Heinz Kredel
023     */
024    
025    public final class ModIntegerRing implements ModularRingFactory<ModInteger>, Iterable<ModInteger> {
026    
027    
028        /** Module part of the factory data structure. 
029         */
030        public final java.math.BigInteger modul;
031    
032    
033        private final static Random random = new Random();
034    
035    
036        /** Indicator if this ring is a field.
037         */
038        protected int isField = -1; // initially unknown
039    
040    
041        /** Certainty if module is probable prime.
042         */
043        protected int certainty = 10;
044    
045    
046        /** The constructor creates a ModIntegerRing object 
047         * from a BigInteger object as module part. 
048         * @param m math.BigInteger.
049         */
050        public ModIntegerRing(java.math.BigInteger m) {
051            modul = m;
052        }
053    
054    
055        /** The constructor creates a ModIntegerRing object 
056         * from a BigInteger object as module part. 
057         * @param m math.BigInteger.
058         * @param isField indicator if m is prime.
059         */
060        public ModIntegerRing(java.math.BigInteger m, boolean isField) {
061            modul = m;
062            this.isField = ( isField ? 1 :  0 );
063        }
064    
065    
066        /** The constructor creates a ModIntegerRing object 
067         * from a long as module part. 
068         * @param m long.
069         */
070        public ModIntegerRing(long m) {
071            this( new java.math.BigInteger( String.valueOf(m) ) );
072        }
073    
074    
075        /** The constructor creates a ModIntegerRing object 
076         * from a long as module part. 
077         * @param m long.
078         * @param isField indicator if m is prime.
079         */
080        public ModIntegerRing(long m, boolean isField) {
081            this( 
082                 new java.math.BigInteger( String.valueOf(m) ),
083                 isField
084                 );
085        }
086    
087    
088        /** The constructor creates a ModIntegerRing object 
089         * from a String object as module part. 
090         * @param m String.
091         */
092        public ModIntegerRing(String m) {
093            this( new java.math.BigInteger( m.trim() ) );
094        }
095    
096    
097        /** The constructor creates a ModIntegerRing object 
098         * from a String object as module part. 
099         * @param m String.
100         * @param isField indicator if m is prime.
101         */
102        public ModIntegerRing(String m, boolean isField) {
103            this( new java.math.BigInteger( m.trim() ), isField );
104        }
105    
106    
107        /** Get the module part. 
108         * @return modul.
109         */
110        public java.math.BigInteger getModul() {
111            return modul;
112        }
113    
114    
115        /** Get the module part as BigInteger.  
116         * @return modul.
117         */
118        public BigInteger getIntegerModul() {
119            return new BigInteger(modul);
120        }
121    
122    
123        /** Create ModInteger element c.
124         * @param c
125         * @return a ModInteger of c.
126         */
127        public ModInteger create(java.math.BigInteger c) {
128            return new ModInteger( this, c );
129        }
130    
131    
132        /** Create ModInteger element c.
133         * @param c
134         * @return a ModInteger of c.
135         */
136        public ModInteger create(long c) {
137            return new ModInteger( this, c );
138        }
139    
140    
141        /** Create ModInteger element c.
142         * @param c
143         * @return a ModInteger of c.
144         */
145        public ModInteger create(String c) {
146            return parse(c);
147        }
148    
149    
150        /** Copy ModInteger element c.
151         * @param c
152         * @return a copy of c.
153         */
154        public ModInteger copy(ModInteger c) {
155            return new ModInteger( this, c.val );
156        }
157    
158    
159        /** Get the zero element.
160         * @return 0 as ModInteger.
161         */
162        public ModInteger getZERO() {
163            return new ModInteger( this, java.math.BigInteger.ZERO );
164        }
165    
166    
167        /**  Get the one element.
168         * @return 1 as ModInteger.
169         */
170        public ModInteger getONE() {
171            return new ModInteger( this, java.math.BigInteger.ONE );
172        }
173    
174    
175        /**
176         * Get a list of the generating elements.
177         * @return list of generators for the algebraic structure.
178         * @see edu.jas.structure.ElemFactory#generators()
179         */
180        public List<ModInteger> generators() {
181            List<ModInteger> g = new ArrayList<ModInteger>(1);
182            g.add( getONE() );
183            return g;
184        }
185    
186    
187        /**
188         * Is this structure finite or infinite.
189         * @return true if this structure is finite, else false.
190         * @see edu.jas.structure.ElemFactory#isFinite()
191         */
192        public boolean isFinite() {
193            return true;
194        }
195    
196    
197        /**
198         * Query if this ring is commutative.
199         * @return true.
200         */
201        public boolean isCommutative() {
202            return true;
203        }
204    
205    
206        /**
207         * Query if this ring is associative.
208         * @return true.
209         */
210        public boolean isAssociative() {
211            return true;
212        }
213    
214    
215        /**
216         * Query if this ring is a field.
217         * @return true if module is prime, else false.
218         */
219        public boolean isField() {
220            if ( isField > 0 ) { 
221               return true;
222            }
223            if ( isField == 0 ) { 
224               return false;
225            }
226            //System.out.println("isProbablePrime " + modul + " = " + modul.isProbablePrime(certainty));
227            // if ( modul.isProbablePrime(certainty) ) {
228            if ( modul.isProbablePrime(modul.bitLength()) ) {
229               isField = 1;
230               return true;
231            }
232            isField = 0;
233            return false;
234        }
235    
236    
237        /**
238         * Characteristic of this ring.
239         * @return characteristic of this ring.
240         */
241        public java.math.BigInteger characteristic() {
242            return modul;
243        }
244    
245    
246        /** Get a ModInteger element from a BigInteger value.
247         * @param a BigInteger.
248         * @return a ModInteger.
249         */
250        public ModInteger fromInteger(java.math.BigInteger a) {
251            return new ModInteger(this,a);
252        }
253    
254    
255        /** Get a ModInteger element from a long value.
256         * @param a long.
257         * @return a ModInteger.
258         */
259        public ModInteger fromInteger(long a) {
260            return new ModInteger(this, a );
261        }
262    
263    
264        /**  Get the String representation.
265         * @see java.lang.Object#toString()
266         */
267        @Override
268        public String toString() {
269            return " bigMod(" + modul.toString() + ")";
270        }
271    
272    
273        /** Get a scripting compatible string representation.
274         * @return script compatible representation for this ElemFactory.
275         * @see edu.jas.structure.ElemFactory#toScript()
276         */
277        //JAVA6only: @Override
278        public String toScript() {
279            // Python case
280            return "ZM(" + modul.toString() + ")";
281        }
282    
283    
284        /** Comparison with any other object.
285         * @see java.lang.Object#equals(java.lang.Object)
286         */
287        @Override
288        public boolean equals(Object b) {
289            if ( ! ( b instanceof ModIntegerRing ) ) {
290                return false;
291            }
292            ModIntegerRing m = (ModIntegerRing)b;
293            return ( 0 == modul.compareTo( m.modul ) );
294        }
295    
296    
297        /** Hash code for this ModIntegerRing.
298         * @see java.lang.Object#hashCode()
299         */
300        @Override
301        public int hashCode() {
302            return modul.hashCode();
303        }
304    
305    
306        /** ModInteger random.
307         * @param n such that 0 &le; v &le; (2<sup>n</sup>-1).
308         * @return a random integer mod modul.
309         */
310        public ModInteger random(int n) {
311            return random( n, random );
312        }
313    
314    
315        /** ModInteger random.
316         * @param n such that 0 &le; v &le; (2<sup>n</sup>-1).
317         * @param rnd is a source for random bits.
318         * @return a random integer mod modul.
319         */
320        public ModInteger random(int n, Random rnd) {
321            java.math.BigInteger v = new java.math.BigInteger( n, rnd );
322            return new ModInteger( this, v );
323        }
324    
325    
326        /** Parse ModInteger from String.
327         * @param s String.
328         * @return ModInteger from s.
329         */
330        public ModInteger parse(String s) {
331            return new ModInteger(this,s);
332        }
333    
334    
335        /** Parse ModInteger from Reader.
336         * @param r Reader.
337         * @return next ModInteger from r.
338         */
339        public ModInteger parse(Reader r) {
340            return parse( StringUtil.nextString(r) );
341        }
342    
343    
344        /** ModInteger chinese remainder algorithm.  
345         * This is a factory method.
346         * Assert c.modul >= a.modul and c.modul * a.modul = this.modul.
347         * @param c ModInteger.
348         * @param ci inverse of c.modul in ring of a.
349         * @param a other ModInteger.
350         * @return S, with S mod c.modul == c and S mod a.modul == a. 
351         */
352        public ModInteger 
353               chineseRemainder(ModInteger c, 
354                                ModInteger ci, 
355                                ModInteger a) {
356            if ( false ) { // debug
357               if ( c.ring.modul.compareTo( a.ring.modul ) < 1 ) {
358                   System.out.println("ModInteger error " + c + ", " + a);
359               }
360            }
361            ModInteger b = a.ring.fromInteger( c.val ); // c mod a.modul
362            ModInteger d = a.subtract( b ); // a-c mod a.modul
363            if ( d.isZERO() ) {
364               return fromInteger( c.val );
365            }
366            b = d.multiply( ci ); // b = (a-c)*ci mod a.modul
367            // (c.modul*b)+c mod this.modul = c mod c.modul = 
368            // (c.modul*ci*(a-c)+c) mod a.modul = a mod a.modul
369            java.math.BigInteger s = c.ring.modul.multiply( b.val );
370            s = s.add( c.val );
371            return fromInteger( s );
372        }
373    
374    
375        /** Get a ModInteger iterator.
376         * @return a iterator over all modular integers in this ring.
377         */
378        public Iterator<ModInteger> iterator() {
379            return new ModIntegerIterator(this);
380        }
381    
382    }
383    
384    
385    /**
386     * Modular integer iterator.
387     * @author Heinz Kredel
388     */
389    class ModIntegerIterator implements Iterator<ModInteger> {
390    
391    
392        /**
393         * data structure.
394         */
395        java.math.BigInteger curr;
396    
397    
398        final ModIntegerRing ring;
399    
400    
401        /**
402         * ModInteger iterator constructor.
403         * @param fac modular integer factory;
404         */
405        public ModIntegerIterator(ModIntegerRing fac) {
406            curr = java.math.BigInteger.ZERO;
407            ring = fac;
408        }
409    
410    
411        /**
412         * Test for availability of a next element.
413         * @return true if the iteration has more elements, else false.
414         */
415        public synchronized boolean hasNext() {
416            return curr.compareTo(ring.modul) < 0; 
417        }
418    
419    
420        /**
421         * Get next integer.
422         * @return next integer.
423         */
424        public synchronized ModInteger next() {
425            ModInteger i = new ModInteger(ring,curr);
426            curr = curr.add( java.math.BigInteger.ONE );
427            return i;
428        }
429    
430    
431        /**
432         * Remove an element if allowed.
433         */
434        public void remove() {
435            throw new UnsupportedOperationException("cannnot remove elements");
436        }
437    }