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