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