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