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