001/* 002 * $Id: QuotientRing.java 5872 2018-07-20 16:01:46Z 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.logging.log4j.Logger; 014import org.apache.logging.log4j.LogManager; 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>> implements RingFactory<Quotient<C>>, 028 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 for (C c : rgens) { 123 gens.add(new Quotient<C>(this, c)); 124 } 125 return gens; 126 } 127 128 129 /** 130 * Query if this ring is commutative. 131 * @return true if this ring is commutative, else false. 132 */ 133 public boolean isCommutative() { 134 return ring.isCommutative(); 135 } 136 137 138 /** 139 * Query if this ring is associative. 140 * @return true if this ring is associative, else false. 141 */ 142 public boolean isAssociative() { 143 return ring.isAssociative(); 144 } 145 146 147 /** 148 * Query if this ring is a field. 149 * @return true. 150 */ 151 public boolean isField() { 152 return true; 153 } 154 155 156 /** 157 * Characteristic of this ring. 158 * @return characteristic of this ring. 159 */ 160 public java.math.BigInteger characteristic() { 161 return ring.characteristic(); 162 } 163 164 165 /** 166 * Get a Quotient element from a BigInteger value. 167 * @param a BigInteger. 168 * @return a Quotient. 169 */ 170 public Quotient<C> fromInteger(java.math.BigInteger a) { 171 return new Quotient<C>(this, ring.fromInteger(a)); 172 } 173 174 175 /** 176 * Get a Quotient element from a long value. 177 * @param a long. 178 * @return a Quotient. 179 */ 180 public Quotient<C> fromInteger(long a) { 181 return new Quotient<C>(this, ring.fromInteger(a)); 182 } 183 184 185 /** 186 * Get the String representation as RingFactory. 187 * @see java.lang.Object#toString() 188 */ 189 @Override 190 public String toString() { 191 return "Quotient[ " + ring.toString() + " ]"; 192 } 193 194 195 /** 196 * Get a scripting compatible string representation. 197 * @return script compatible representation for this ElemFactory. 198 * @see edu.jas.structure.ElemFactory#toScript() 199 */ 200 @Override 201 public String toScript() { 202 // Python case 203 return "QuotientRing(" + ring.toScript() + ")"; 204 } 205 206 207 /** 208 * Comparison with any other object. 209 * @see java.lang.Object#equals(java.lang.Object) 210 */ 211 @Override 212 @SuppressWarnings("unchecked") 213 public boolean equals(Object b) { 214 if (b == null) { 215 return false; 216 } 217 if (!(b instanceof QuotientRing)) { 218 return false; 219 } 220 QuotientRing<C> a = (QuotientRing<C>) b; 221 return ring.equals(a.ring); 222 } 223 224 225 /** 226 * Hash code for this quotient ring. 227 * @see java.lang.Object#hashCode() 228 */ 229 @Override 230 public int hashCode() { 231 int h; 232 h = ring.hashCode(); 233 return h; 234 } 235 236 237 /** 238 * Quotient random. 239 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 240 * @return a random residue element. 241 */ 242 public Quotient<C> random(int n) { 243 C r = ring.random(n); 244 C s = ring.random(n); 245 while (s.isZERO()) { 246 s = ring.random(n); 247 } 248 return new Quotient<C>(this, r, s, false); 249 } 250 251 252 /** 253 * Quotient random. 254 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 255 * @param rnd is a source for random bits. 256 * @return a random residue element. 257 */ 258 public Quotient<C> random(int n, Random rnd) { 259 C r = ring.random(n, rnd); 260 C s = ring.random(n, rnd); 261 while (s.isZERO()) { 262 s = ring.random(n, rnd); 263 } 264 return new Quotient<C>(this, r, s, false); 265 } 266 267 268 /** 269 * Parse Quotient from String. 270 * @param s String. 271 * @return Quotient from s. 272 */ 273 public Quotient<C> parse(String s) { 274 C x = ring.parse(s); 275 return new Quotient<C>(this, x); 276 } 277 278 279 /** 280 * Parse Quotient from Reader. 281 * @param r Reader. 282 * @return next Quotient from r. 283 */ 284 public Quotient<C> parse(Reader r) { 285 C x = ring.parse(r); 286 if (debug) { 287 logger.debug("x = " + x); 288 } 289 return new Quotient<C>(this, x); 290 } 291 292}