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 ≤ v ≤ (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 ≤ v ≤ (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 }