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