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