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