001 /* 002 * $Id: QuotientRing.java 3365 2010-10-24 12:59:34Z kredel $ 003 */ 004 005 package edu.jas.poly; 006 007 import java.util.Random; 008 import java.util.List; 009 import java.util.ArrayList; 010 import java.io.Reader; 011 012 import org.apache.log4j.Logger; 013 014 import edu.jas.structure.ElemFactory; 015 import edu.jas.structure.RingElem; 016 import edu.jas.structure.RingFactory; 017 //import edu.jas.structure.GcdRingElem; 018 019 020 /** 021 * Quotient ring factory using RingElem and RingFactory. 022 * Objects of this class are immutable. 023 * @author Heinz Kredel 024 */ 025 public class QuotientRing<C extends RingElem<C> > 026 implements RingFactory< Quotient<C> > { 027 028 private static final Logger logger = Logger.getLogger(QuotientRing.class); 029 private boolean debug = logger.isDebugEnabled(); 030 031 032 /** Ring factory of this factory. 033 */ 034 public final RingFactory< C > ring; 035 036 037 /** The constructor creates a QuotientRing object 038 * from a RingFactory. 039 * @param r ring factory. 040 */ 041 public QuotientRing(RingFactory<C> r) { 042 ring = r; 043 } 044 045 046 /** 047 * Is this structure finite or infinite. 048 * @return true if this structure is finite, else false. 049 * @see edu.jas.structure.ElemFactory#isFinite() 050 */ 051 public boolean isFinite() { 052 return ring.isFinite(); 053 } 054 055 056 /** Copy Quotient element c. 057 * @param c 058 * @return a copy of c. 059 */ 060 public Quotient<C> copy(Quotient<C> c) { 061 return new Quotient<C>( c.ring, c.num, c.den, true ); 062 } 063 064 065 /** Get the zero element. 066 * @return 0 as Quotient. 067 */ 068 public Quotient<C> getZERO() { 069 return new Quotient<C>( this, ring.getZERO() ); 070 } 071 072 073 /** Get the one element. 074 * @return 1 as Quotient. 075 */ 076 public Quotient<C> getONE() { 077 return new Quotient<C>( this, ring.getONE() ); 078 } 079 080 081 /** Get a list of the generating elements. 082 * @return list of generators for the algebraic structure. 083 * @see edu.jas.structure.ElemFactory#generators() 084 */ 085 public List<Quotient<C>> generators() { 086 List<? extends C> rgens = ring.generators(); 087 List<Quotient<C>> gens = new ArrayList<Quotient<C>>( rgens.size() ); 088 for ( C c: rgens ) { 089 gens.add( new Quotient<C>(this,c) ); 090 } 091 return gens; 092 } 093 094 095 /** 096 * Query if this ring is commutative. 097 * @return true if this ring is commutative, else false. 098 */ 099 public boolean isCommutative() { 100 return ring.isCommutative(); 101 } 102 103 104 /** 105 * Query if this ring is associative. 106 * @return true if this ring is associative, else false. 107 */ 108 public boolean isAssociative() { 109 return ring.isAssociative(); 110 } 111 112 113 /** 114 * Query if this ring is a field. 115 * @return true. 116 */ 117 public boolean isField() { 118 return true; 119 } 120 121 122 /** 123 * Characteristic of this ring. 124 * @return characteristic of this ring. 125 */ 126 public java.math.BigInteger characteristic() { 127 return ring.characteristic(); 128 } 129 130 131 /** Get a Quotient element from a BigInteger value. 132 * @param a BigInteger. 133 * @return a Quotient. 134 */ 135 public Quotient<C> fromInteger(java.math.BigInteger a) { 136 return new Quotient<C>( this, ring.fromInteger(a) ); 137 } 138 139 140 /** Get a Quotient element from a long value. 141 * @param a long. 142 * @return a Quotient. 143 */ 144 public Quotient<C> fromInteger(long a) { 145 return new Quotient<C>( this, ring.fromInteger(a) ); 146 } 147 148 149 /** Get the String representation as RingFactory. 150 * @see java.lang.Object#toString() 151 */ 152 @Override 153 public String toString() { 154 return "Quotient[ " 155 + ring.toString() + " ]"; 156 } 157 158 159 /** Get a scripting compatible string representation. 160 * @return script compatible representation for this ElemFactory. 161 * @see edu.jas.structure.ElemFactory#toScript() 162 */ 163 //JAVA6only: @Override 164 public String toScript() { 165 // Python case 166 return "QuotientRing(" + ring.toScript() + ")"; 167 } 168 169 170 /** Comparison with any other object. 171 * @see java.lang.Object#equals(java.lang.Object) 172 */ 173 @Override 174 @SuppressWarnings("unchecked") // not jet working 175 public boolean equals(Object b) { 176 if ( ! ( b instanceof QuotientRing ) ) { 177 return false; 178 } 179 QuotientRing<C> a = null; 180 try { 181 a = (QuotientRing<C>) b; 182 } catch (ClassCastException e) { 183 } 184 if ( a == null ) { 185 return false; 186 } 187 return ring.equals( a.ring ); 188 } 189 190 191 /** Hash code for this quotient ring. 192 * @see java.lang.Object#hashCode() 193 */ 194 @Override 195 public int hashCode() { 196 int h; 197 h = ring.hashCode(); 198 return h; 199 } 200 201 202 /** Quotient random. 203 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 204 * @return a random residue element. 205 */ 206 public Quotient<C> random(int n) { 207 C r = ring.random( n ); 208 C s = ring.random( n ); 209 while ( s.isZERO() ) { 210 s = ring.random( n ); 211 } 212 return new Quotient<C>( this, r, s, false ); 213 } 214 215 216 /** Quotient random. 217 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 218 * @param rnd is a source for random bits. 219 * @return a random residue element. 220 */ 221 public Quotient<C> random(int n, Random rnd) { 222 C r = ring.random( n, rnd ); 223 C s = ring.random( n, rnd ); 224 while ( s.isZERO() ) { 225 s = ring.random( n, rnd ); 226 } 227 return new Quotient<C>( this, r, s, false); 228 } 229 230 231 /** Parse Quotient from String. 232 * @param s String. 233 * @return Quotient from s. 234 */ 235 public Quotient<C> parse(String s) { 236 C x = ring.parse( s ); 237 return new Quotient<C>( this, x ); 238 } 239 240 241 /** Parse Quotient from Reader. 242 * @param r Reader. 243 * @return next Quotient from r. 244 */ 245 public Quotient<C> parse(Reader r) { 246 C x = ring.parse( r ); 247 if ( debug ) { 248 logger.debug("x = " + x); 249 } 250 return new Quotient<C>( this, x ); 251 } 252 253 }