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 }