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