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