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