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