001/* 002 * $Id: ComplexAlgebraicRing.java 4961 2014-10-17 18:59:39Z kredel $ 003 */ 004 005package edu.jas.root; 006 007 008import java.io.Reader; 009import java.util.ArrayList; 010import java.util.List; 011import java.util.Random; 012 013import edu.jas.arith.BigRational; 014import edu.jas.arith.Rational; 015import edu.jas.poly.AlgebraicNumber; 016import edu.jas.poly.AlgebraicNumberRing; 017import edu.jas.poly.Complex; 018import edu.jas.poly.ComplexRing; 019import edu.jas.poly.GenPolynomial; 020import edu.jas.structure.GcdRingElem; 021import edu.jas.structure.Power; 022import edu.jas.structure.RingFactory; 023 024 025/** 026 * Complex algebraic number factory class based on AlgebraicNumberRing with 027 * RingFactory interface. Objects of this class are immutable with the exception 028 * of the isolating intervals. 029 * @author Heinz Kredel 030 */ 031 032public class ComplexAlgebraicRing<C extends GcdRingElem<C> & Rational> 033/*extends AlgebraicNumberRing<C>*/ 034implements RingFactory<ComplexAlgebraicNumber<C>> { 035 036 037 /** 038 * Representing AlgebraicNumberRing. 039 */ 040 public final AlgebraicNumberRing<Complex<C>> algebraic; 041 042 043 /** 044 * Isolating rectangle for a complex root. <b>Note: </b> interval may shrink 045 * eventually. 046 */ 047 /*package*/Rectangle<C> root; 048 049 050 /** 051 * Epsilon of the isolating rectangle for a complex root. 052 */ 053 protected C eps; 054 055 056 /** 057 * Precision of the isolating rectangle for a complex root. 058 */ 059 public static final int PRECISION = 9; //BigDecimal.DEFAULT_PRECISION; 060 061 062 /** 063 * Complex root computation engine. 064 */ 065 public final ComplexRootsSturm<C> engine; 066 067 068 /** 069 * The constructor creates a ComplexAlgebraicNumber factory object from a 070 * GenPolynomial objects module. 071 * @param m module GenPolynomial<C>. 072 * @param root isolating rectangle for a complex root. 073 */ 074 public ComplexAlgebraicRing(GenPolynomial<Complex<C>> m, Rectangle<C> root) { 075 algebraic = new AlgebraicNumberRing<Complex<C>>(m); 076 this.root = root; 077 engine = new ComplexRootsSturm<C>(m.ring.coFac); 078 if (m.ring.characteristic().signum() > 0) { 079 throw new IllegalArgumentException("characteristic not zero"); 080 } 081 C e = m.ring.coFac.fromInteger(10L).getRe(); 082 e = e.inverse(); 083 e = Power.positivePower(e, PRECISION); 084 eps = e; 085 } 086 087 088 /** 089 * The constructor creates a ComplexAlgebraicNumber factory object from a 090 * GenPolynomial objects module. 091 * @param m module GenPolynomial<C>. 092 * @param root isolating rectangle for a complex root. 093 * @param isField indicator if m is prime. 094 */ 095 public ComplexAlgebraicRing(GenPolynomial<Complex<C>> m, Rectangle<C> root, boolean isField) { 096 algebraic = new AlgebraicNumberRing<Complex<C>>(m, isField); 097 this.root = root; 098 engine = new ComplexRootsSturm<C>(m.ring.coFac); 099 if (m.ring.characteristic().signum() > 0) { 100 throw new IllegalArgumentException("characteristic not zero"); 101 } 102 C e = m.ring.coFac.fromInteger(10L).getRe(); 103 e = e.inverse(); 104 e = Power.positivePower(e, PRECISION); 105 eps = e; 106 } 107 108 109 /* 110 * Get the module part. 111 * @return modul. public GenPolynomial<C> getModul() { return 112 * algebraic.modul; } 113 */ 114 115 116 /** 117 * Set a refined rectangle for the complex root. <b>Note: </b> rectangle may 118 * shrink eventually. 119 * @param v rectangle. 120 */ 121 public synchronized void setRoot(Rectangle<C> v) { 122 // assert v is contained in root 123 this.root = v; 124 } 125 126 127 /** 128 * Get rectangle for the complex root. 129 * @return v rectangle. 130 */ 131 public synchronized Rectangle<C> getRoot() { 132 return this.root; 133 } 134 135 136 /** 137 * Get epsilon. 138 * @return epsilon. 139 */ 140 public synchronized C getEps() { 141 return this.eps; 142 } 143 144 145 /** 146 * Set a new epsilon. 147 * @param e epsilon. 148 */ 149 public synchronized void setEps(C e) { 150 this.eps = e; 151 } 152 153 154 /** 155 * Set a new epsilon. 156 * @param e epsilon. 157 */ 158 public synchronized void setEps(BigRational e) { 159 this.eps = algebraic.ring.coFac.parse(e.toString()).getRe(); 160 } 161 162 163 /** 164 * Is this structure finite or infinite. 165 * @return true if this structure is finite, else false. 166 * @see edu.jas.structure.ElemFactory#isFinite() 167 */ 168 public boolean isFinite() { 169 return algebraic.isFinite(); 170 } 171 172 173 /** 174 * Copy ComplexAlgebraicNumber element c. 175 * @param c 176 * @return a copy of c. 177 */ 178 public ComplexAlgebraicNumber<C> copy(ComplexAlgebraicNumber<C> c) { 179 return new ComplexAlgebraicNumber<C>(this, c.number); 180 } 181 182 183 /** 184 * Get the zero element. 185 * @return 0 as ComplexAlgebraicNumber. 186 */ 187 public ComplexAlgebraicNumber<C> getZERO() { 188 return new ComplexAlgebraicNumber<C>(this, algebraic.getZERO()); 189 } 190 191 192 /** 193 * Get the one element. 194 * @return 1 as ComplexAlgebraicNumber. 195 */ 196 public ComplexAlgebraicNumber<C> getONE() { 197 return new ComplexAlgebraicNumber<C>(this, algebraic.getONE()); 198 } 199 200 201 /** 202 * Get the i element. 203 * @return i as ComplexAlgebraicNumber. 204 */ 205 public ComplexAlgebraicNumber<C> getIMAG() { 206 ComplexRing<C> cr = (ComplexRing<C>) algebraic.ring.coFac; 207 Complex<C> I = cr.getIMAG(); 208 return new ComplexAlgebraicNumber<C>(this, algebraic.getZERO().sum(I)); 209 } 210 211 212 /** 213 * Get the generating element. 214 * @return alpha as ComplexAlgebraicNumber. 215 */ 216 public ComplexAlgebraicNumber<C> getGenerator() { 217 return new ComplexAlgebraicNumber<C>(this, algebraic.getGenerator()); 218 } 219 220 221 /** 222 * Get a list of the generating elements. 223 * @return list of generators for the algebraic structure. 224 * @see edu.jas.structure.ElemFactory#generators() 225 */ 226 public List<ComplexAlgebraicNumber<C>> generators() { 227 List<AlgebraicNumber<Complex<C>>> agens = algebraic.generators(); 228 List<ComplexAlgebraicNumber<C>> gens = new ArrayList<ComplexAlgebraicNumber<C>>(agens.size()); 229 for (AlgebraicNumber<Complex<C>> a : agens) { 230 gens.add(getZERO().sum(a.getVal())); 231 } 232 return gens; 233 } 234 235 236 /** 237 * Query if this ring is commutative. 238 * @return true if this ring is commutative, else false. 239 */ 240 public boolean isCommutative() { 241 return algebraic.isCommutative(); 242 } 243 244 245 /** 246 * Query if this ring is associative. 247 * @return true if this ring is associative, else false. 248 */ 249 public boolean isAssociative() { 250 return algebraic.isAssociative(); 251 } 252 253 254 /** 255 * Query if this ring is a field. 256 * @return true if algebraic is prime, else false. 257 */ 258 public boolean isField() { 259 return algebraic.isField(); 260 } 261 262 263 /** 264 * Characteristic of this ring. 265 * @return characteristic of this ring. 266 */ 267 public java.math.BigInteger characteristic() { 268 return algebraic.characteristic(); 269 } 270 271 272 /** 273 * Get a ComplexAlgebraicNumber element from a BigInteger value. 274 * @param a BigInteger. 275 * @return a ComplexAlgebraicNumber. 276 */ 277 public ComplexAlgebraicNumber<C> fromInteger(java.math.BigInteger a) { 278 return new ComplexAlgebraicNumber<C>(this, algebraic.fromInteger(a)); 279 } 280 281 282 /** 283 * Get a ComplexAlgebraicNumber element from a long value. 284 * @param a long. 285 * @return a ComplexAlgebraicNumber. 286 */ 287 public ComplexAlgebraicNumber<C> fromInteger(long a) { 288 return new ComplexAlgebraicNumber<C>(this, algebraic.fromInteger(a)); 289 } 290 291 292 /** 293 * Get the String representation as RingFactory. 294 * @see java.lang.Object#toString() 295 */ 296 @Override 297 public String toString() { 298 return "ComplexAlgebraicRing[ " + algebraic.modul.toString() + " in " + root + " | isField=" 299 + algebraic.isField() + " :: " + algebraic.ring.toString() + " ]"; 300 } 301 302 303 /** 304 * Get a scripting compatible string representation. 305 * @return script compatible representation for this ElemFactory. 306 * @see edu.jas.structure.ElemFactory#toScript() 307 */ 308 @Override 309 public String toScript() { 310 // Python case 311 return "ComplexN( " + algebraic.modul.toScript() + ", " + root.toScript() 312 //+ ", " + algebraic.isField() 313 //+ ", " + algebraic.ring.toScript() 314 + " )"; 315 } 316 317 318 /** 319 * Comparison with any other object. 320 * @see java.lang.Object#equals(java.lang.Object) 321 */ 322 @Override 323 @SuppressWarnings("unchecked") 324 public boolean equals(Object b) { 325 if (b == null) { 326 return false; 327 } 328 if (!(b instanceof ComplexAlgebraicRing)) { 329 return false; 330 } 331 ComplexAlgebraicRing<C> a = (ComplexAlgebraicRing<C>) b; 332 return algebraic.equals(a.algebraic) && root.equals(a.root); 333 } 334 335 336 /** 337 * Hash code for this ComplexAlgebraicNumber. 338 * @see java.lang.Object#hashCode() 339 */ 340 @Override 341 public int hashCode() { 342 return 37 * algebraic.hashCode() + root.hashCode(); 343 } 344 345 346 /** 347 * ComplexAlgebraicNumber random. 348 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 349 * @return a random integer mod modul. 350 */ 351 public ComplexAlgebraicNumber<C> random(int n) { 352 return new ComplexAlgebraicNumber<C>(this, algebraic.random(n)); 353 } 354 355 356 /** 357 * ComplexAlgebraicNumber random. 358 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 359 * @param rnd is a source for random bits. 360 * @return a random integer mod modul. 361 */ 362 public ComplexAlgebraicNumber<C> random(int n, Random rnd) { 363 return new ComplexAlgebraicNumber<C>(this, algebraic.random(n, rnd)); 364 } 365 366 367 /** 368 * Parse ComplexAlgebraicNumber from String. 369 * @param s String. 370 * @return ComplexAlgebraicNumber from s. 371 */ 372 public ComplexAlgebraicNumber<C> parse(String s) { 373 return new ComplexAlgebraicNumber<C>(this, algebraic.parse(s)); 374 } 375 376 377 /** 378 * Parse ComplexAlgebraicNumber from Reader. 379 * @param r Reader. 380 * @return next ComplexAlgebraicNumber from r. 381 */ 382 public ComplexAlgebraicNumber<C> parse(Reader r) { 383 return new ComplexAlgebraicNumber<C>(this, algebraic.parse(r)); 384 } 385 386}