001/* 002 * $Id: RealAlgebraicRing.java 5589 2016-08-17 21:15:16Z 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.BigDecimal; 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 long value. 305 * @param a long. 306 * @return a RealAlgebraicNumber. 307 */ 308 public RealAlgebraicNumber<C> fromInteger(long a) { 309 return new RealAlgebraicNumber<C>(this, algebraic.fromInteger(a)); 310 } 311 312 313 /** 314 * Get the String representation as RingFactory. 315 * @see java.lang.Object#toString() 316 */ 317 @Override 318 public String toString() { 319 return "RealAlgebraicRing[ " + algebraic.modul.toString() + " in " + root + " | isField=" 320 + algebraic.isField() + " :: " + algebraic.ring.toString() + " ]"; 321 } 322 323 324 /** 325 * Get a scripting compatible string representation. 326 * @return script compatible representation for this ElemFactory. 327 * @see edu.jas.structure.ElemFactory#toScript() 328 */ 329 @Override 330 public String toScript() { 331 // Python case 332 return "RealN( " + algebraic.modul.toScript() + ", " + root.toScript() 333 //+ ", " + algebraic.isField() 334 //+ ", " + algebraic.ring.toScript() 335 + " )"; 336 } 337 338 339 /** 340 * Comparison with any other object. 341 * @see java.lang.Object#equals(java.lang.Object) 342 */ 343 @Override 344 @SuppressWarnings("unchecked") 345 public boolean equals(Object b) { 346 if (b == null) { 347 return false; 348 } 349 if (!(b instanceof RealAlgebraicRing)) { 350 return false; 351 } 352 RealAlgebraicRing<C> a = (RealAlgebraicRing<C>) b; 353 return algebraic.equals(a.algebraic) && root.equals(a.root); 354 } 355 356 357 /** 358 * Hash code for this RealAlgebraicNumber. 359 * @see java.lang.Object#hashCode() 360 */ 361 @Override 362 public int hashCode() { 363 return 37 * algebraic.hashCode() + root.hashCode(); 364 } 365 366 367 /** 368 * RealAlgebraicNumber random. 369 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 370 * @return a random integer mod modul. 371 */ 372 public RealAlgebraicNumber<C> random(int n) { 373 return new RealAlgebraicNumber<C>(this, algebraic.random(n)); 374 } 375 376 377 /** 378 * RealAlgebraicNumber random. 379 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 380 * @param rnd is a source for random bits. 381 * @return a random integer mod modul. 382 */ 383 public RealAlgebraicNumber<C> random(int n, Random rnd) { 384 return new RealAlgebraicNumber<C>(this, algebraic.random(n, rnd)); 385 } 386 387 388 /** 389 * Parse RealAlgebraicNumber from String. 390 * @param s String. 391 * @return RealAlgebraicNumber from s. 392 */ 393 public RealAlgebraicNumber<C> parse(String s) { 394 return new RealAlgebraicNumber<C>(this, algebraic.parse(s)); 395 } 396 397 398 /** 399 * Parse RealAlgebraicNumber from Reader. 400 * @param r Reader. 401 * @return next RealAlgebraicNumber from r. 402 */ 403 public RealAlgebraicNumber<C> parse(Reader r) { 404 return new RealAlgebraicNumber<C>(this, algebraic.parse(r)); 405 } 406 407}