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