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