001 /* 002 * $Id: ComplexRing.java 3694 2011-07-23 18:03:46Z kredel $ 003 */ 004 005 package edu.jas.poly; 006 007 008 import java.io.Reader; 009 import java.math.BigInteger; 010 import java.util.ArrayList; 011 import java.util.List; 012 import java.util.Random; 013 import java.util.Set; 014 import java.util.TreeSet; 015 016 import org.apache.log4j.Logger; 017 018 import edu.jas.kern.StringUtil; 019 import edu.jas.structure.ElemFactory; 020 import edu.jas.structure.Element; 021 import edu.jas.structure.RingElem; 022 import edu.jas.structure.RingFactory; 023 024 025 /** 026 * Generic Complex ring factory implementing the RingFactory interface. Objects 027 * of this class are immutable. 028 * @param <C> base type. 029 * @author Heinz Kredel 030 */ 031 public class ComplexRing<C extends RingElem<C>> implements RingFactory<Complex<C>> { 032 033 034 private final static Random random = new Random(); 035 036 037 @SuppressWarnings("unused") 038 private static final Logger logger = Logger.getLogger(ComplexRing.class); 039 040 041 /** 042 * Complex class elements factory data structure. 043 */ 044 public final RingFactory<C> ring; 045 046 047 /** 048 * The constructor creates a ComplexRing object. 049 * @param ring factory for Complex real and imaginary parts. 050 */ 051 public ComplexRing(RingFactory<C> ring) { 052 this.ring = ring; 053 } 054 055 056 /** 057 * Get a list of the generating elements. 058 * @return list of generators for the algebraic structure. 059 * @see edu.jas.structure.ElemFactory#generators() 060 */ 061 public List<Complex<C>> generators() { 062 List<C> gens = ring.generators(); 063 List<Complex<C>> g = new ArrayList<Complex<C>>(gens.size()+1); 064 for ( C x : gens ) { 065 Complex<C> cx = new Complex<C>(this,x); 066 g.add(cx); 067 } 068 g.add(getIMAG()); 069 return g; 070 } 071 072 073 /** 074 * Is this structure finite or infinite. 075 * @return true if this structure is finite, else false. 076 * @see edu.jas.structure.ElemFactory#isFinite() 077 */ 078 public boolean isFinite() { 079 return ring.isFinite(); 080 } 081 082 083 /** 084 * Copy Complex element c. 085 * @param c Complex<C>. 086 * @return a copy of c. 087 */ 088 public Complex<C> copy(Complex<C> c) { 089 return new Complex<C>(this, c.re, c.im); 090 } 091 092 093 /** 094 * Get the zero element. 095 * @return 0 as Complex<C>. 096 */ 097 public Complex<C> getZERO() { 098 return new Complex<C>(this); 099 } 100 101 102 /** 103 * Get the one element. 104 * @return 1 as Complex<C>. 105 */ 106 public Complex<C> getONE() { 107 return new Complex<C>(this, ring.getONE()); 108 } 109 110 111 /** 112 * Get the i element. 113 * @return i as Complex<C>. 114 */ 115 public Complex<C> getIMAG() { 116 return new Complex<C>(this, ring.getZERO(), ring.getONE()); 117 } 118 119 120 /** 121 * Query if this ring is commutative. 122 * @return true. 123 */ 124 public boolean isCommutative() { 125 return ring.isCommutative(); 126 } 127 128 129 /** 130 * Query if this ring is associative. 131 * @return true. 132 */ 133 public boolean isAssociative() { 134 return ring.isAssociative(); 135 } 136 137 138 /** 139 * Query if this ring is a field. 140 * @return true. 141 */ 142 public boolean isField() { 143 return ring.isField(); 144 } 145 146 147 /** 148 * Characteristic of this ring. 149 * @return characteristic of this ring. 150 */ 151 public java.math.BigInteger characteristic() { 152 return ring.characteristic(); 153 } 154 155 156 /** 157 * Get a Complex element from a BigInteger. 158 * @param a BigInteger. 159 * @return a Complex<C>. 160 */ 161 public Complex<C> fromInteger(BigInteger a) { 162 return new Complex<C>(this, ring.fromInteger(a)); 163 } 164 165 166 /** 167 * Get a Complex element from a long. 168 * @param a long. 169 * @return a Complex<C>. 170 */ 171 public Complex<C> fromInteger(long a) { 172 return new Complex<C>(this, ring.fromInteger(a)); 173 } 174 175 176 /** 177 * Get the String representation. 178 */ 179 @Override 180 public String toString() { 181 StringBuffer sb = new StringBuffer(); 182 sb.append("Complex["); 183 if (ring instanceof RingElem) { 184 RingElem ri = (RingElem) ring; 185 sb.append(ri.toScriptFactory()); 186 } else { 187 sb.append(ring.toString()); 188 } 189 sb.append("]"); 190 return sb.toString(); 191 } 192 193 194 /** 195 * Get a scripting compatible string representation. 196 * @return script compatible representation for this Element. 197 * @see edu.jas.structure.Element#toScript() 198 */ 199 //JAVA6only: @Override 200 public String toScript() { 201 // Python case 202 StringBuffer s = new StringBuffer(); 203 s.append("CR("); 204 if (ring instanceof RingElem) { 205 RingElem ri = (RingElem) ring; 206 s.append(ri.toScriptFactory()); 207 } else { 208 s.append(ring.toScript()); 209 } 210 s.append(")"); 211 return s.toString(); 212 } 213 214 215 /** 216 * Comparison with any other object. 217 * @see java.lang.Object#equals(java.lang.Object) 218 */ 219 @Override 220 @SuppressWarnings("unchecked") 221 public boolean equals(Object b) { 222 if (!(b instanceof ComplexRing)) { 223 return false; 224 } 225 ComplexRing<C> a = null; 226 try { 227 a = (ComplexRing<C>) b; 228 } catch (ClassCastException e) { 229 } 230 if (a == null) { 231 return false; 232 } 233 if (!ring.equals(a.ring)) { 234 return false; 235 } 236 return true; 237 } 238 239 240 /** 241 * Hash code for this ComplexRing<C>. 242 * @see java.lang.Object#hashCode() 243 */ 244 @Override 245 public int hashCode() { 246 return ring.hashCode(); 247 } 248 249 250 /** 251 * Complex number random. Random base numbers A and B are generated using 252 * random(n). Then R is the complex number with real part A and imaginary 253 * part B. 254 * @param n such that 0 ≤ A, B ≤ (2<sup>n</sup>-1). 255 * @return R. 256 */ 257 public Complex<C> random(int n) { 258 return random(n, random); 259 // C r = ring.random( n ).abs(); 260 // C i = ring.random( n ).abs(); 261 // return new Complex<C>(this, r, i ); 262 } 263 264 265 /** 266 * Complex number random. Random base numbers A and B are generated using 267 * random(n). Then R is the complex number with real part A and imaginary 268 * part B. 269 * @param n such that 0 ≤ A, B ≤ (2<sup>n</sup>-1). 270 * @param rnd is a source for random bits. 271 * @return R. 272 */ 273 public Complex<C> random(int n, Random rnd) { 274 C r = ring.random(n, rnd); 275 C i = ring.random(n, rnd); 276 return new Complex<C>(this, r, i); 277 } 278 279 280 /** 281 * Parse complex number from string. 282 * @param s String. 283 * @return Complex<C> from s. 284 */ 285 public Complex<C> parse(String s) { 286 return new Complex<C>(this, s); 287 } 288 289 290 /** 291 * Parse complex number from Reader. 292 * @param r Reader. 293 * @return next Complex<C> from r. 294 */ 295 public Complex<C> parse(Reader r) { 296 return parse(StringUtil.nextString(r)); 297 } 298 299 }