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