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 }