001/* 002 * $Id$ 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.logging.log4j.LogManager; 015import org.apache.logging.log4j.Logger; 016 017import edu.jas.kern.StringUtil; 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 = LogManager.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. not jet possible. 073 */ 074 public AlgebraicNumberRing<C> algebraicRing() { 075 GenPolynomialRing<C> pfac = new GenPolynomialRing<C>(ring, TermOrderByName.INVLEX, new String[] { "I" }); 076 GenPolynomial<C> I = pfac.univariate(0, 2L).sum(pfac.getONE()); 077 AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(I, ring.isField()); // must indicate field 078 return afac; 079 } 080 081 082 /** 083 * Is this structure finite or infinite. 084 * @return true if this structure is finite, else false. 085 * @see edu.jas.structure.ElemFactory#isFinite() 086 */ 087 public boolean isFinite() { 088 return ring.isFinite(); 089 } 090 091 092 /** 093 * Copy Complex element c. 094 * @param c Complex<C>. 095 * @return a copy of c. 096 */ 097 public Complex<C> copy(Complex<C> c) { 098 return new Complex<C>(this, c.re, c.im); 099 } 100 101 102 /** 103 * Get the zero element. 104 * @return 0 as Complex<C>. 105 */ 106 public Complex<C> getZERO() { 107 return new Complex<C>(this); 108 } 109 110 111 /** 112 * Get the one element. 113 * @return 1 as Complex<C>. 114 */ 115 public Complex<C> getONE() { 116 return new Complex<C>(this, ring.getONE()); 117 } 118 119 120 /** 121 * Get the i element. 122 * @return i as Complex<C>. 123 */ 124 public Complex<C> getIMAG() { 125 return new Complex<C>(this, ring.getZERO(), ring.getONE()); 126 } 127 128 129 /** 130 * Query if this ring is commutative. 131 * @return true. 132 */ 133 public boolean isCommutative() { 134 return ring.isCommutative(); 135 } 136 137 138 /** 139 * Query if this ring is associative. 140 * @return true. 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 ring.isField(); 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 Complex element from a BigInteger. 167 * @param a BigInteger. 168 * @return a Complex<C>. 169 */ 170 public Complex<C> fromInteger(BigInteger a) { 171 return new Complex<C>(this, ring.fromInteger(a)); 172 } 173 174 175 /** 176 * Get a Complex element from a long. 177 * @param a long. 178 * @return a Complex<C>. 179 */ 180 public Complex<C> fromInteger(long a) { 181 return new Complex<C>(this, ring.fromInteger(a)); 182 } 183 184 185 /** 186 * Get the String representation. 187 */ 188 @Override 189 public String toString() { 190 StringBuffer sb = new StringBuffer(); 191 sb.append("Complex["); 192 if (ring instanceof RingElem) { 193 RingElem ri = (RingElem) ring; 194 sb.append(ri.toScriptFactory()); 195 } else { 196 sb.append(ring.toString()); 197 } 198 sb.append("]"); 199 return sb.toString(); 200 } 201 202 203 /** 204 * Get a scripting compatible string representation. 205 * @return script compatible representation for this Element. 206 * @see edu.jas.structure.Element#toScript() 207 */ 208 @Override 209 public String toScript() { 210 // Python case 211 StringBuffer s = new StringBuffer(); 212 s.append("CR("); 213 if (ring instanceof RingElem) { 214 RingElem ri = (RingElem) ring; 215 s.append(ri.toScriptFactory()); 216 } else { 217 s.append(ring.toScript()); 218 } 219 s.append(")"); 220 return s.toString(); 221 } 222 223 224 /** 225 * Comparison with any other object. 226 * @see java.lang.Object#equals(java.lang.Object) 227 */ 228 @Override 229 @SuppressWarnings("unchecked") 230 public boolean equals(Object b) { 231 if (b == null) { 232 return false; 233 } 234 if (!(b instanceof ComplexRing)) { 235 return false; 236 } 237 ComplexRing<C> a = (ComplexRing<C>) b; 238 if (!ring.equals(a.ring)) { 239 return false; 240 } 241 return true; 242 } 243 244 245 /** 246 * Hash code for this ComplexRing<C>. 247 * @see java.lang.Object#hashCode() 248 */ 249 @Override 250 public int hashCode() { 251 return ring.hashCode(); 252 } 253 254 255 /** 256 * Complex number random. Random base numbers A and B are generated using 257 * random(n). Then R is the complex number with real part A and imaginary 258 * part B. 259 * @param n such that 0 ≤ A, B ≤ (2<sup>n</sup>-1). 260 * @return R. 261 */ 262 public Complex<C> random(int n) { 263 return random(n, random); 264 // C r = ring.random( n ).abs(); 265 // C i = ring.random( n ).abs(); 266 // return new Complex<C>(this, r, i ); 267 } 268 269 270 /** 271 * Complex number random. Random base numbers A and B are generated using 272 * random(n). Then R is the complex number with real part A and imaginary 273 * part B. 274 * @param n such that 0 ≤ A, B ≤ (2<sup>n</sup>-1). 275 * @param rnd is a source for random bits. 276 * @return R. 277 */ 278 public Complex<C> random(int n, Random rnd) { 279 C r = ring.random(n, rnd); 280 C i = ring.random(n, rnd); 281 return new Complex<C>(this, r, i); 282 } 283 284 285 /** 286 * Parse complex number from string. 287 * @param s String. 288 * @return Complex<C> from s. 289 */ 290 public Complex<C> parse(String s) { 291 return new Complex<C>(this, s); 292 } 293 294 295 /** 296 * Parse complex number from Reader. 297 * @param r Reader. 298 * @return next Complex<C> from r. 299 */ 300 public Complex<C> parse(Reader r) { 301 return parse(StringUtil.nextString(r)); 302 } 303 304}