001/* 002 * $Id: RealAlgebraicRing.java 3947 2012-05-28 10:50:47Z kredel $ 003 */ 004 005package edu.jas.application; 006 007 008import java.io.Reader; 009import java.util.ArrayList; 010import java.util.List; 011import java.util.Random; 012 013import org.apache.log4j.Logger; 014 015import edu.jas.kern.Scripting; 016import edu.jas.arith.BigRational; 017import edu.jas.arith.Rational; 018import edu.jas.poly.AlgebraicNumber; 019import edu.jas.poly.AlgebraicNumberRing; 020import edu.jas.poly.PolyUtil; 021import edu.jas.poly.TermOrder; 022import edu.jas.poly.GenPolynomial; 023import edu.jas.poly.GenPolynomialRing; 024import edu.jas.root.RealRootTuple; 025import edu.jas.root.PolyUtilRoot; 026import edu.jas.root.Interval; 027import edu.jas.structure.GcdRingElem; 028import edu.jas.structure.Power; 029import 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 040public 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 * Assert that this ring is a field. 282 * @param isField true if this ring is a field, else false. 283 */ 284 public void setField(boolean isField) { 285 realRing.setField(isField); 286 } 287 288 289 /** 290 * Characteristic of this ring. 291 * @return characteristic of this ring. 292 */ 293 public java.math.BigInteger characteristic() { 294 return realRing.characteristic(); 295 } 296 297 298 /** 299 * Get a RealAlgebraicNumber element from a BigInteger value. 300 * @param a BigInteger. 301 * @return a RealAlgebraicNumber. 302 */ 303 public RealAlgebraicNumber<C> fromInteger(java.math.BigInteger a) { 304 return new RealAlgebraicNumber<C>(this, realRing.fromInteger(a)); 305 } 306 307 308 /** 309 * Get a RealAlgebraicNumber element from a long value. 310 * @param a long. 311 * @return a RealAlgebraicNumber. 312 */ 313 public RealAlgebraicNumber<C> fromInteger(long a) { 314 return new RealAlgebraicNumber<C>(this, realRing.fromInteger(a)); 315 } 316 317 318 /** 319 * Get the String representation as RingFactory. 320 * @see java.lang.Object#toString() 321 */ 322 @Override 323 public String toString() { 324 return "RealAlgebraicRing[ " + realRing.toString() + " in " + root + " | isField=" 325 + realRing.isField() + ", algebraic.ideal=" + algebraic.ideal.toString() + " ]"; 326 } 327 328 329 /** 330 * Get a scripting compatible string representation. 331 * @return script compatible representation for this ElemFactory. 332 * @see edu.jas.structure.ElemFactory#toScript() 333 */ 334 //JAVA6only: @Override 335 public String toScript() { 336 // Python case 337 return "RealRecN( " + realRing.toScript() + ", " + root.toScript() 338 //+ ", " + realRing.isField() 339 //+ ", " + realRing.ring.toScript() 340 + " )"; 341 } 342 343 344 /** 345 * Comparison with any other object. 346 * @see java.lang.Object#equals(java.lang.Object) 347 */ 348 @Override 349 @SuppressWarnings("unchecked") 350 // not jet working 351 public boolean equals(Object b) { 352 if (!(b instanceof RealAlgebraicRing)) { 353 return false; 354 } 355 RealAlgebraicRing<C> a = null; 356 try { 357 a = (RealAlgebraicRing<C>) b; 358 } catch (ClassCastException e) { 359 } 360 if (a == null) { 361 return false; 362 } 363 return realRing.equals(a.realRing) && 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 * realRing.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, realRing.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, realRing.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, realRing.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, realRing.parse(r)); 415 } 416 417}