001/* 002 * $Id: RealAlgebraicRing.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.GenPolynomial; 018import edu.jas.structure.GcdRingElem; 019import edu.jas.structure.Power; 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>*/ 032implements 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 = 9; //BigDecimal.DEFAULT_PRECISION; 052 053 054 /** 055 * Precision of the isolating interval for a real root. 056 */ 057 protected C 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 C e = m.ring.coFac.fromInteger(10L); 080 e = e.inverse(); 081 //C x = Power.positivePower(e, BigDecimal.DEFAULT_PRECISION); 082 e = Power.positivePower(e, PRECISION); // better not too much for speed 083 eps = e; 084 } 085 086 087 /** 088 * The constructor creates a RealAlgebraicNumber factory object from a 089 * GenPolynomial objects module. 090 * @param m module GenPolynomial<C>. 091 * @param root isolating interval for a real root. 092 * @param isField indicator if m is prime. 093 */ 094 public RealAlgebraicRing(GenPolynomial<C> m, Interval<C> root, boolean isField) { 095 algebraic = new AlgebraicNumberRing<C>(m, isField); 096 this.root = root; 097 engine = new RealRootsSturm<C>(); 098 if (m.ring.characteristic().signum() > 0) { 099 throw new RuntimeException("characteristic not zero"); 100 } 101 C e = m.ring.coFac.fromInteger(10L); 102 e = e.inverse(); 103 e = Power.positivePower(e, PRECISION); //BigDecimal.DEFAULT_PRECISION); 104 eps = e; 105 } 106 107 108 /** 109 * Get the module part. 110 * @return modul. public GenPolynomial<C> getModul() { return 111 * algebraic.modul; } 112 */ 113 114 115 /** 116 * Get the interval for the real root. <b>Note: </b> interval may shrink 117 * later. 118 * @return real root isolating interval 119 */ 120 public synchronized Interval<C> getRoot() { 121 return root; 122 } 123 124 125 /** 126 * Set a refined interval for the real root. <b>Note: </b> interval may 127 * shrink eventually. 128 * @param v interval. 129 */ 130 public synchronized void setRoot(Interval<C> v) { 131 // assert v is contained in root 132 this.root = v; 133 } 134 135 136 /** 137 * Get the epsilon. 138 * @return eps. 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()); 160 } 161 162 163 /** 164 * RealAlgebraicRing half interval. 165 */ 166 public void halfInterval() { 167 Interval<C> v = engine.halfInterval(root, algebraic.modul); 168 //System.out.println("old v = " + ring.root + ", new v = " + v); 169 setRoot(v); 170 } 171 172 173 /** 174 * Is this structure finite or infinite. 175 * @return true if this structure is finite, else false. 176 * @see edu.jas.structure.ElemFactory#isFinite() 177 */ 178 public boolean isFinite() { 179 return algebraic.isFinite(); 180 } 181 182 183 /** 184 * Copy RealAlgebraicNumber element c. 185 * @param c 186 * @return a copy of c. 187 */ 188 public RealAlgebraicNumber<C> copy(RealAlgebraicNumber<C> c) { 189 return new RealAlgebraicNumber<C>(this, c.number); 190 } 191 192 193 /** 194 * Get the zero element. 195 * @return 0 as RealAlgebraicNumber. 196 */ 197 public RealAlgebraicNumber<C> getZERO() { 198 return new RealAlgebraicNumber<C>(this, algebraic.getZERO()); 199 } 200 201 202 /** 203 * Get the one element. 204 * @return 1 as RealAlgebraicNumber. 205 */ 206 public RealAlgebraicNumber<C> getONE() { 207 return new RealAlgebraicNumber<C>(this, algebraic.getONE()); 208 } 209 210 211 /** 212 * Get the generating element. 213 * @return alpha as RealAlgebraicNumber. 214 */ 215 public RealAlgebraicNumber<C> getGenerator() { 216 return new RealAlgebraicNumber<C>(this, algebraic.getGenerator()); 217 } 218 219 220 /** 221 * Get a list of the generating elements. 222 * @return list of generators for the algebraic structure. 223 * @see edu.jas.structure.ElemFactory#generators() 224 */ 225 public List<RealAlgebraicNumber<C>> generators() { 226 List<AlgebraicNumber<C>> agens = algebraic.generators(); 227 List<RealAlgebraicNumber<C>> gens = new ArrayList<RealAlgebraicNumber<C>>(agens.size()); 228 for (AlgebraicNumber<C> a : agens) { 229 gens.add(getZERO().sum(a.getVal())); 230 } 231 return gens; 232 } 233 234 235 /** 236 * Query if this ring is commutative. 237 * @return true if this ring is commutative, else false. 238 */ 239 public boolean isCommutative() { 240 return algebraic.isCommutative(); 241 } 242 243 244 /** 245 * Query if this ring is associative. 246 * @return true if this ring is associative, else false. 247 */ 248 public boolean isAssociative() { 249 return algebraic.isAssociative(); 250 } 251 252 253 /** 254 * Query if this ring is a field. 255 * @return true if algebraic is prime, else false. 256 */ 257 public boolean isField() { 258 return algebraic.isField(); 259 } 260 261 262 /** 263 * Assert that this ring is a field. 264 * @param isField true if this ring is a field, else false. 265 */ 266 public void setField(boolean isField) { 267 algebraic.setField(isField); 268 } 269 270 271 /** 272 * Characteristic of this ring. 273 * @return characteristic of this ring. 274 */ 275 public java.math.BigInteger characteristic() { 276 return algebraic.characteristic(); 277 } 278 279 280 /** 281 * Get a RealAlgebraicNumber element from a BigInteger value. 282 * @param a BigInteger. 283 * @return a RealAlgebraicNumber. 284 */ 285 public RealAlgebraicNumber<C> fromInteger(java.math.BigInteger a) { 286 return new RealAlgebraicNumber<C>(this, algebraic.fromInteger(a)); 287 } 288 289 290 /** 291 * Get a RealAlgebraicNumber element from a long value. 292 * @param a long. 293 * @return a RealAlgebraicNumber. 294 */ 295 public RealAlgebraicNumber<C> fromInteger(long a) { 296 return new RealAlgebraicNumber<C>(this, algebraic.fromInteger(a)); 297 } 298 299 300 /** 301 * Get the String representation as RingFactory. 302 * @see java.lang.Object#toString() 303 */ 304 @Override 305 public String toString() { 306 return "RealAlgebraicRing[ " + algebraic.modul.toString() + " in " + root + " | isField=" 307 + algebraic.isField() + " :: " + algebraic.ring.toString() + " ]"; 308 } 309 310 311 /** 312 * Get a scripting compatible string representation. 313 * @return script compatible representation for this ElemFactory. 314 * @see edu.jas.structure.ElemFactory#toScript() 315 */ 316 @Override 317 public String toScript() { 318 // Python case 319 return "RealN( " + algebraic.modul.toScript() + ", " + root.toScript() 320 //+ ", " + algebraic.isField() 321 //+ ", " + algebraic.ring.toScript() 322 + " )"; 323 } 324 325 326 /** 327 * Comparison with any other object. 328 * @see java.lang.Object#equals(java.lang.Object) 329 */ 330 @Override 331 @SuppressWarnings("unchecked") 332 public boolean equals(Object b) { 333 if (b == null) { 334 return false; 335 } 336 if (!(b instanceof RealAlgebraicRing)) { 337 return false; 338 } 339 RealAlgebraicRing<C> a = (RealAlgebraicRing<C>) b; 340 return algebraic.equals(a.algebraic) && root.equals(a.root); 341 } 342 343 344 /** 345 * Hash code for this RealAlgebraicNumber. 346 * @see java.lang.Object#hashCode() 347 */ 348 @Override 349 public int hashCode() { 350 return 37 * algebraic.hashCode() + root.hashCode(); 351 } 352 353 354 /** 355 * RealAlgebraicNumber random. 356 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 357 * @return a random integer mod modul. 358 */ 359 public RealAlgebraicNumber<C> random(int n) { 360 return new RealAlgebraicNumber<C>(this, algebraic.random(n)); 361 } 362 363 364 /** 365 * RealAlgebraicNumber random. 366 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 367 * @param rnd is a source for random bits. 368 * @return a random integer mod modul. 369 */ 370 public RealAlgebraicNumber<C> random(int n, Random rnd) { 371 return new RealAlgebraicNumber<C>(this, algebraic.random(n, rnd)); 372 } 373 374 375 /** 376 * Parse RealAlgebraicNumber from String. 377 * @param s String. 378 * @return RealAlgebraicNumber from s. 379 */ 380 public RealAlgebraicNumber<C> parse(String s) { 381 return new RealAlgebraicNumber<C>(this, algebraic.parse(s)); 382 } 383 384 385 /** 386 * Parse RealAlgebraicNumber from Reader. 387 * @param r Reader. 388 * @return next RealAlgebraicNumber from r. 389 */ 390 public RealAlgebraicNumber<C> parse(Reader r) { 391 return new RealAlgebraicNumber<C>(this, algebraic.parse(r)); 392 } 393 394}